Merge branch 'master' into api
This commit is contained in:
commit
eca823c1c7
124 changed files with 1743 additions and 657 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,6 +6,7 @@ log/*.log
|
|||
tmp/
|
||||
.sass-cache/
|
||||
coverage/*
|
||||
backups/*
|
||||
*.swp
|
||||
public/uploads/
|
||||
.rvmrc
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
v 2.7.0
|
||||
- Issue Labels
|
||||
- Inline diff
|
||||
- Git HTTP
|
||||
- API
|
||||
- UI improved
|
||||
- System hooks
|
||||
- UI improved
|
||||
- Dashboard events endless scroll
|
||||
- Source perfomance increased
|
||||
|
||||
v 2.6.0
|
||||
- UI polished
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -7,7 +7,7 @@ gem "sqlite3"
|
|||
gem "mysql2"
|
||||
|
||||
# Auth
|
||||
gem "devise", "~> 1.5"
|
||||
gem "devise", "~> 2.1.0"
|
||||
|
||||
# GITLAB patched libs
|
||||
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
|
||||
|
@ -71,7 +71,6 @@ group :development, :test do
|
|||
gem "awesome_print"
|
||||
gem "database_cleaner"
|
||||
gem "launchy"
|
||||
gem "webmock"
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
@ -82,4 +81,5 @@ group :test do
|
|||
gem "shoulda-matchers"
|
||||
gem 'email_spec'
|
||||
gem 'resque_spec'
|
||||
gem "webmock"
|
||||
end
|
||||
|
|
13
Gemfile.lock
13
Gemfile.lock
|
@ -148,10 +148,11 @@ GEM
|
|||
nokogiri (>= 1.5.0)
|
||||
daemons (1.1.8)
|
||||
database_cleaner (0.8.0)
|
||||
devise (1.5.3)
|
||||
devise (2.1.2)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.3)
|
||||
warden (~> 1.1)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.2.1)
|
||||
diff-lcs (1.1.3)
|
||||
drapper (0.8.4)
|
||||
email_spec (1.2.1)
|
||||
|
@ -225,7 +226,7 @@ GEM
|
|||
omniauth (1.1.0)
|
||||
hashie (~> 1.2)
|
||||
rack
|
||||
orm_adapter (0.0.7)
|
||||
orm_adapter (0.3.0)
|
||||
polyglot (0.3.3)
|
||||
posix-spawn (0.3.6)
|
||||
pry (0.9.9.6)
|
||||
|
@ -356,7 +357,7 @@ GEM
|
|||
raindrops (~> 0.7)
|
||||
vegas (0.1.11)
|
||||
rack (>= 1.0.0)
|
||||
warden (1.2.0)
|
||||
warden (1.2.1)
|
||||
rack (>= 1.0)
|
||||
webmock (1.8.7)
|
||||
addressable (>= 2.2.7)
|
||||
|
@ -383,7 +384,7 @@ DEPENDENCIES
|
|||
colored
|
||||
cucumber-rails
|
||||
database_cleaner
|
||||
devise (~> 1.5)
|
||||
devise (~> 2.1.0)
|
||||
drapper
|
||||
email_spec
|
||||
ffaker
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.7.0pre
|
||||
2.7.0
|
||||
|
|
BIN
app/assets/images/ajax_loader_tree.gif
Normal file
BIN
app/assets/images/ajax_loader_tree.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
|
@ -12,6 +12,7 @@
|
|||
//= require jquery.cookie
|
||||
//= require jquery.endless-scroll
|
||||
//= require jquery.highlight
|
||||
//= require jquery.waitforimages
|
||||
//= require bootstrap-modal
|
||||
//= require modernizr
|
||||
//= require chosen-jquery
|
||||
|
@ -20,10 +21,26 @@
|
|||
//= require_tree .
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
$(".one_click_select").live("click", function(){
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
|
||||
$('body').on('ajax:complete, ajax:beforeSend, submit', 'form', function(e){
|
||||
var buttons = $('[type="submit"]', this);
|
||||
switch( e.type ){
|
||||
case 'ajax:beforeSend':
|
||||
case 'submit':
|
||||
buttons.attr('disabled', 'disabled');
|
||||
break;
|
||||
case ' ajax:complete':
|
||||
default:
|
||||
buttons.removeAttr('disabled');
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
$(".account-box").mouseenter(showMenu);
|
||||
$(".account-box").mouseleave(resetMenu);
|
||||
|
||||
|
@ -97,3 +114,8 @@ function showDiff(link) {
|
|||
return _chosen.apply(this, [default_options]);
|
||||
}})
|
||||
})(jQuery);
|
||||
|
||||
|
||||
function ajaxGet(url) {
|
||||
$.ajax({type: "GET", url: url, dataType: "script"});
|
||||
}
|
||||
|
|
|
@ -73,4 +73,25 @@ function issuesPage(){
|
|||
$("#milestone_id, #assignee_id, #label_name").on("change", function(){
|
||||
$(this).closest("form").submit();
|
||||
});
|
||||
|
||||
$('body').on('ajax:success', '.close_issue, .reopen_issue, #new_issue', function(){
|
||||
var t = $(this),
|
||||
totalIssues,
|
||||
reopen = t.hasClass('reopen_issue'),
|
||||
newIssue = false;
|
||||
if( this.id == 'new_issue' ){
|
||||
newIssue = true;
|
||||
}
|
||||
$('.issue_counter, #new_issue').each(function(){
|
||||
var issue = $(this);
|
||||
totalIssues = parseInt( $(this).html(), 10 );
|
||||
|
||||
if( newIssue || ( reopen && issue.closest('.main_menu').length ) ){
|
||||
$(this).html( totalIssues+1 );
|
||||
}else {
|
||||
$(this).html( totalIssues-1 );
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ init:
|
|||
$(this).closest('li').fadeOut(); });
|
||||
|
||||
$("#new_note").live("ajax:before", function(){
|
||||
$("#submit_note").attr("disabled", "disabled");
|
||||
$(".submit_note").attr("disabled", "disabled");
|
||||
})
|
||||
|
||||
$("#new_note").live("ajax:complete", function(){
|
||||
$("#submit_note").removeAttr("disabled");
|
||||
$(".submit_note").removeAttr("disabled");
|
||||
})
|
||||
|
||||
$("#note_note").live("focus", function(){
|
||||
|
|
|
@ -604,7 +604,11 @@ li.note {
|
|||
border-style: solid;
|
||||
border-width: 1px;
|
||||
@include border-radius(4px);
|
||||
min-height:42px;
|
||||
min-height:22px;
|
||||
|
||||
.avatar {
|
||||
width:24px;
|
||||
}
|
||||
}
|
||||
|
||||
.supp_diff_link,
|
||||
|
|
|
@ -202,6 +202,10 @@ a:focus {
|
|||
color:$style_color;
|
||||
}
|
||||
|
||||
.nav-tabs > .active > a {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
/** COLORS **/
|
||||
.cgray { color:gray; }
|
||||
.cred { color:#D12F19; }
|
||||
|
@ -209,6 +213,7 @@ a:focus {
|
|||
.cblack { color:#111; }
|
||||
.cdark { color:#444 }
|
||||
.cwhite { color:#fff !important }
|
||||
.bgred { background: #F2DEDE !important}
|
||||
|
||||
/** COMMON STYLES **/
|
||||
.left {
|
||||
|
@ -299,9 +304,24 @@ table.no-borders {
|
|||
}
|
||||
|
||||
.event_label {
|
||||
background: #FCEEC1;
|
||||
padding: 2px 2px 0;
|
||||
font-family: monospace;
|
||||
@extend .label;
|
||||
background-color: #999;
|
||||
|
||||
&.pushed {
|
||||
background-color: #3A87AD;
|
||||
}
|
||||
|
||||
&.opened {
|
||||
background-color: #468847;
|
||||
}
|
||||
|
||||
&.closed {
|
||||
background-color: #B94A48;
|
||||
}
|
||||
|
||||
&.merged {
|
||||
background-color: #2A2;
|
||||
}
|
||||
}
|
||||
|
||||
img.avatar {
|
||||
|
@ -425,9 +445,10 @@ form {
|
|||
*/
|
||||
.ui-box {
|
||||
background:#F9F9F9;
|
||||
margin-bottom: 40px;
|
||||
margin-bottom: 25px;
|
||||
@include round-borders-all(4px);
|
||||
border-color: #CCC;
|
||||
@include solid_shade;
|
||||
|
||||
ul {
|
||||
margin:0;
|
||||
|
@ -443,6 +464,13 @@ form {
|
|||
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
|
||||
&.small {
|
||||
line-height: 28px;
|
||||
font-size: 14px;
|
||||
line-height:28px;
|
||||
text-shadow: 0 1px 1px white;
|
||||
}
|
||||
|
||||
form {
|
||||
padding:9px 0;
|
||||
margin:0px;
|
||||
|
@ -511,6 +539,7 @@ form {
|
|||
table.admin-table {
|
||||
@extend .table-bordered;
|
||||
@extend .zebra-striped;
|
||||
@include solid_shade;
|
||||
th {
|
||||
border-color: #CCC;
|
||||
border-bottom: 1px solid #bbb;
|
||||
|
@ -568,6 +597,8 @@ ul.breadcrumb {
|
|||
@extend .prepend-top-20;
|
||||
@extend .append-bottom-20;
|
||||
border-width:1px;
|
||||
@include solid_shade;
|
||||
|
||||
|
||||
img { max-width: 100%; }
|
||||
|
||||
|
@ -624,13 +655,166 @@ p {
|
|||
h3.page_title {
|
||||
color:#456;
|
||||
font-size:20px;
|
||||
font-weight: 600;
|
||||
font-weight: normal;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
pre.logs {
|
||||
.log {
|
||||
font-size:12px;
|
||||
line-height:18px;
|
||||
/**
|
||||
* File content holder
|
||||
*
|
||||
*/
|
||||
.file_holder {
|
||||
border:1px solid #CCC;
|
||||
margin-bottom:1em;
|
||||
@include solid_shade;
|
||||
|
||||
.file_title {
|
||||
border-bottom: 1px solid #bbb;
|
||||
background:#eee;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
padding: 9px 10px;
|
||||
height:18px;
|
||||
|
||||
.options {
|
||||
float:right;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.file_name {
|
||||
color:$style_color;
|
||||
font-size:14px;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
small {
|
||||
color:#999;
|
||||
font-size:13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.file_content {
|
||||
background:#fff;
|
||||
font-size: 11px;
|
||||
|
||||
&.wiki {
|
||||
font-size: 13px;
|
||||
code {
|
||||
padding:0 4px;
|
||||
}
|
||||
padding:20px;
|
||||
h1, h2 {
|
||||
line-height: 46px;
|
||||
}
|
||||
h3, h4 {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
&.image_file {
|
||||
background:#eee;
|
||||
text-align:center;
|
||||
img {
|
||||
padding:100px;
|
||||
max-width:300px;
|
||||
}
|
||||
}
|
||||
|
||||
&.blob_file {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Blame file
|
||||
*/
|
||||
&.blame {
|
||||
tr {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
td {
|
||||
padding:5px;
|
||||
}
|
||||
.author,
|
||||
.blame_commit {
|
||||
background:#f5f5f5;
|
||||
vertical-align:top;
|
||||
}
|
||||
.lines {
|
||||
pre {
|
||||
padding:0;
|
||||
margin:0;
|
||||
background:none;
|
||||
border:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.logs {
|
||||
background:#eee;
|
||||
max-height: 700px;
|
||||
overflow-y: auto;
|
||||
|
||||
ol {
|
||||
margin-left:40px;
|
||||
padding: 10px 0;
|
||||
border-left: 1px solid #CCC;
|
||||
margin-bottom:0;
|
||||
background: white;
|
||||
li {
|
||||
color:#888;
|
||||
p {
|
||||
margin:0;
|
||||
color:#333;
|
||||
line-height:24px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background:$hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Code file
|
||||
*/
|
||||
&.code {
|
||||
padding:0;
|
||||
td.code {
|
||||
width: 100%;
|
||||
.highlight {
|
||||
margin-left: 55px;
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
}
|
||||
}
|
||||
.highlight pre {
|
||||
white-space: pre;
|
||||
word-wrap:normal;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
border: none;
|
||||
}
|
||||
body.project-page table.highlighttable td { border: none }
|
||||
table.highlighttable tr:hover { background:none;}
|
||||
|
||||
table.highlighttable pre{
|
||||
line-height:16px !important;
|
||||
font-size:12px !important;
|
||||
}
|
||||
|
||||
table.highlighttable .linenodiv pre {
|
||||
text-align: right;
|
||||
padding-right: 4px;
|
||||
color:#666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ header {
|
|||
*/
|
||||
.search {
|
||||
float: right;
|
||||
margin-right: 55px;
|
||||
margin-right: 50px;
|
||||
|
||||
.search-input {
|
||||
@extend .span2;
|
||||
|
@ -126,10 +126,10 @@ header {
|
|||
cursor: pointer;
|
||||
img {
|
||||
border-radius: 4px;
|
||||
right: 0px;
|
||||
right: 5px;
|
||||
position: absolute;
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
width: 31px;
|
||||
height: 31px;
|
||||
display: block;
|
||||
top: 0;
|
||||
&:after {
|
||||
|
|
|
@ -31,6 +31,12 @@ $hover: #FDF5D9;
|
|||
box-shadow: 0 0 3px #ddd;
|
||||
}
|
||||
|
||||
@mixin solid_shade {
|
||||
-moz-box-shadow: 0 0 0 3px #eee;
|
||||
-webkit-box-shadow: 0 0 0 3px #eee;
|
||||
box-shadow: 0 0 0 3px #eee;
|
||||
}
|
||||
|
||||
@mixin border-radius($radius) {
|
||||
-moz-border-radius: $radius;
|
||||
-webkit-border-radius: $radius;
|
||||
|
@ -136,7 +142,7 @@ $hover: #FDF5D9;
|
|||
/**
|
||||
* Code (files list) styles. Browsing project files there
|
||||
*/
|
||||
@import "tree.scss";
|
||||
@import "sections/tree.scss";
|
||||
|
||||
/**
|
||||
* This file represent notes(comments) styles
|
||||
|
|
|
@ -63,18 +63,22 @@ p.notify_controls span{
|
|||
|
||||
tr.line_notes_row {
|
||||
border-bottom:1px solid #DDD;
|
||||
border-left: 7px solid #2A79A3;
|
||||
|
||||
&.reply {
|
||||
background:#eee;
|
||||
|
||||
border-left: 7px solid #2A79A3;
|
||||
border-top:1px solid #ddd;
|
||||
td {
|
||||
padding:7px 10px;
|
||||
}
|
||||
a.line_note_reply_link {
|
||||
@include round-borders-all(4px);
|
||||
border-color:#aaa;
|
||||
background: #bbb;
|
||||
padding: 3px 20px;
|
||||
padding: 3px 10px;
|
||||
margin-left:5px;
|
||||
color: white;
|
||||
background: #2A79A3;
|
||||
border-color: #2A79A3;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
|
@ -95,6 +99,9 @@ tr.line_notes_row {
|
|||
td {
|
||||
border-bottom:1px solid #ddd;
|
||||
}
|
||||
.actions {
|
||||
margin:0;
|
||||
}
|
||||
}
|
||||
|
||||
td .line_note_link {
|
||||
|
|
|
@ -101,16 +101,19 @@
|
|||
margin:50px;
|
||||
padding:1px;
|
||||
max-width:400px;
|
||||
}
|
||||
&.diff_image_removed {
|
||||
img {
|
||||
|
||||
&.diff_image_removed {
|
||||
border: 1px solid #C00;
|
||||
}
|
||||
|
||||
&.diff_image_added {
|
||||
border: 1px solid #0C0;;
|
||||
}
|
||||
}
|
||||
|
||||
&.diff_image_added {
|
||||
img {
|
||||
border: 1px solid #0C0;;
|
||||
&.img_compared {
|
||||
img {
|
||||
max-width:300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,3 +82,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
li.merge_request {
|
||||
padding:7px 10px;
|
||||
img.avatar {
|
||||
width: 32px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
p {
|
||||
padding: 0px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
|
96
app/assets/stylesheets/sections/tree.scss
Normal file
96
app/assets/stylesheets/sections/tree.scss
Normal file
|
@ -0,0 +1,96 @@
|
|||
#tree-holder {
|
||||
#tree-content-holder {
|
||||
float:left;
|
||||
width:100%;
|
||||
}
|
||||
#tree-readme-holder {
|
||||
float:left;
|
||||
width:100%;
|
||||
.readme {
|
||||
border:1px solid #ccc;
|
||||
padding:12px;
|
||||
background: #F7F7F7;
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree_progress {
|
||||
display:none;
|
||||
margin:20px;
|
||||
&.loading {
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
|
||||
#tree-slider {
|
||||
@include border-radius(0);
|
||||
.tree-item {
|
||||
&:hover {
|
||||
td { background: $hover; }
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
.tree-item-file-name {
|
||||
vertical-align:middle;
|
||||
font-weight:bold;
|
||||
a {
|
||||
color:$style_color;
|
||||
&:hover {
|
||||
color:$blue_link;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
top:-1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#tree-slider {
|
||||
@include solid_shade;
|
||||
width:100%;
|
||||
|
||||
border-color:#ccc;
|
||||
|
||||
td {
|
||||
padding:8px;
|
||||
border-color:#f1f1f1;
|
||||
background:#fafafa;
|
||||
}
|
||||
|
||||
tr:first-child td:first-child,
|
||||
tr:first-child td:last-child {
|
||||
border-radius:0;
|
||||
}
|
||||
|
||||
th {
|
||||
border-color: #CCC;
|
||||
border-bottom: 1px solid #bbb;
|
||||
background:#eee;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
}
|
||||
}
|
||||
|
||||
.tree-commit-link {
|
||||
color:#333;
|
||||
}
|
||||
|
||||
a.tree-commit-link {
|
||||
color: #666;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -70,8 +70,7 @@
|
|||
}
|
||||
}
|
||||
.separator {
|
||||
border-color:#444;
|
||||
background:#31363E;
|
||||
display:none;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
#tree-holder {
|
||||
#tree-content-holder {
|
||||
float:left;
|
||||
width:100%;
|
||||
}
|
||||
#tree-readme-holder {
|
||||
float:left;
|
||||
width:100%;
|
||||
.readme {
|
||||
border:1px solid #ccc;
|
||||
padding:12px;
|
||||
background: #F7F7F7;
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree_progress {
|
||||
display:none;
|
||||
margin:20px;
|
||||
&.loading {
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** FILE CONTENT VIEW **/
|
||||
.view_file_content{
|
||||
.old_line, .new_line {
|
||||
background:#ECECEC;
|
||||
color:#777;
|
||||
width:15px;
|
||||
float:left;
|
||||
padding: 0px 10px;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
.old_line{
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
.view_file .view_file_header,
|
||||
.diff_file .diff_file_header {
|
||||
border-bottom: 1px solid #bbb;
|
||||
background:#eee;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
padding: 9px 10px;
|
||||
height:18px;
|
||||
|
||||
.options {
|
||||
float:right;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.file_name {
|
||||
color:$style_color;
|
||||
font-size:14px;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
small {
|
||||
color:#999;
|
||||
font-size:13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.view_file {
|
||||
border:1px solid #CCC;
|
||||
margin-bottom:1em;
|
||||
|
||||
.view_file_content {
|
||||
background:#fff;
|
||||
color:#514721;
|
||||
font-size: 11px;
|
||||
}
|
||||
.view_file_content_image {
|
||||
background:#eee;
|
||||
text-align:center;
|
||||
img {
|
||||
padding:100px;
|
||||
max-width:300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td.code {
|
||||
width: 100%;
|
||||
.highlight {
|
||||
margin-left: 55px;
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
}
|
||||
}
|
||||
.highlight pre {
|
||||
white-space: pre;
|
||||
word-wrap:normal;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
border: none;
|
||||
}
|
||||
body.project-page table.highlighttable td { border: none }
|
||||
table.highlighttable tr:hover { background:none;}
|
||||
|
||||
table.highlighttable pre{
|
||||
line-height:16px !important;
|
||||
font-size:12px !important;
|
||||
}
|
||||
|
||||
table.highlighttable .linenodiv pre {
|
||||
text-align: right;
|
||||
padding-right: 4px;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
#tree-slider {
|
||||
@include border-radius(0);
|
||||
.tree-item {
|
||||
&:hover {
|
||||
td { background: $hover; }
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
.tree-item-file-name {
|
||||
vertical-align:middle;
|
||||
font-weight:bold;
|
||||
a {
|
||||
color:$style_color;
|
||||
&:hover {
|
||||
color:$blue_link;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
top:-1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#tree-slider {
|
||||
@include shade;
|
||||
width:100%;
|
||||
|
||||
border-color:#ccc;
|
||||
|
||||
td {
|
||||
padding:8px;
|
||||
border-color:#f1f1f1;
|
||||
background:#fafafa;
|
||||
}
|
||||
|
||||
tr:first-child td:first-child,
|
||||
tr:first-child td:last-child {
|
||||
border-radius:0;
|
||||
}
|
||||
|
||||
th {
|
||||
border-color: #CCC;
|
||||
border-bottom: 1px solid #bbb;
|
||||
background:#eee;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
||||
}
|
||||
}
|
||||
|
||||
.tree-commit-link {
|
||||
color:#333;
|
||||
}
|
||||
|
||||
#tree-content-holder .view_file{
|
||||
@include shade;
|
||||
}
|
||||
|
||||
#tree-readme-holder .readme {
|
||||
@include shade;
|
||||
margin-bottom:20px;
|
||||
h1, h2 {
|
||||
line-height: 56px;
|
||||
}
|
||||
h3, h4 {
|
||||
line-height: 46px;
|
||||
}
|
||||
}
|
||||
|
||||
a.tree-commit-link {
|
||||
color: #666;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.blame_file {
|
||||
.view_file_content {
|
||||
tr {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
td {
|
||||
padding:5px;
|
||||
}
|
||||
.author,
|
||||
.commit {
|
||||
background:#f5f5f5;
|
||||
vertical-align:top;
|
||||
}
|
||||
.lines {
|
||||
pre {
|
||||
padding:0;
|
||||
margin:0;
|
||||
background:none;
|
||||
border:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
app/contexts/base_context.rb
Normal file
8
app/contexts/base_context.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
class BaseContext
|
||||
attr_accessor :project, :current_user, :params
|
||||
|
||||
def initialize(project, user, params)
|
||||
@project, @current_user, @params = project, user, params.dup
|
||||
end
|
||||
end
|
||||
|
26
app/contexts/commit_load.rb
Normal file
26
app/contexts/commit_load.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
class CommitLoad < BaseContext
|
||||
def execute
|
||||
result = {
|
||||
:commit => nil,
|
||||
:suppress_diff => false,
|
||||
:line_notes => [],
|
||||
:notes_count => 0,
|
||||
:note => nil
|
||||
}
|
||||
|
||||
commit = project.commit(params[:id])
|
||||
|
||||
if commit
|
||||
commit = CommitDecorator.decorate(commit)
|
||||
line_notes = project.commit_line_notes(commit)
|
||||
|
||||
result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
|
||||
result[:commit] = commit
|
||||
result[:note] = project.build_commit_note(commit)
|
||||
result[:line_notes] = line_notes
|
||||
result[:notes_count] = line_notes.count + project.commit_notes(commit).count
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
end
|
16
app/contexts/merge_requests_load.rb
Normal file
16
app/contexts/merge_requests_load.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
class MergeRequestsLoad < BaseContext
|
||||
def execute
|
||||
type = params[:f].to_i
|
||||
|
||||
merge_requests = project.merge_requests
|
||||
|
||||
merge_requests = case type
|
||||
when 1 then merge_requests
|
||||
when 2 then merge_requests.closed
|
||||
when 3 then merge_requests.opened.assigned(current_user)
|
||||
else merge_requests.opened
|
||||
end.page(params[:page]).per(20)
|
||||
|
||||
merge_requests.includes(:author, :project).order("closed, created_at desc")
|
||||
end
|
||||
end
|
30
app/contexts/notes_load.rb
Normal file
30
app/contexts/notes_load.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class NotesLoad < BaseContext
|
||||
def execute
|
||||
target_type = params[:target_type]
|
||||
target_id = params[:target_id]
|
||||
first_id = params[:first_id]
|
||||
last_id = params[:last_id]
|
||||
|
||||
|
||||
@notes = case target_type
|
||||
when "commit"
|
||||
then project.commit_notes(project.commit(target_id)).fresh.limit(20)
|
||||
when "snippet"
|
||||
then project.snippets.find(target_id).notes
|
||||
when "wall"
|
||||
then project.common_notes.order("created_at DESC").fresh.limit(50)
|
||||
when "issue"
|
||||
then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
||||
when "merge_request"
|
||||
then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
||||
end
|
||||
|
||||
@notes = if last_id
|
||||
@notes.where("id > ?", last_id)
|
||||
elsif first_id
|
||||
@notes.where("id < ?", first_id)
|
||||
else
|
||||
@notes
|
||||
end
|
||||
end
|
||||
end
|
44
app/controllers/admin/hooks_controller.rb
Normal file
44
app/controllers/admin/hooks_controller.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
class Admin::HooksController < ApplicationController
|
||||
layout "admin"
|
||||
before_filter :authenticate_user!
|
||||
before_filter :authenticate_admin!
|
||||
|
||||
def index
|
||||
@hooks = SystemHook.all
|
||||
@hook = SystemHook.new
|
||||
end
|
||||
|
||||
def create
|
||||
@hook = SystemHook.new(params[:hook])
|
||||
|
||||
if @hook.save
|
||||
redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
|
||||
else
|
||||
@hooks = SystemHook.all
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@hook = SystemHook.find(params[:id])
|
||||
@hook.destroy
|
||||
|
||||
redirect_to admin_hooks_path
|
||||
end
|
||||
|
||||
|
||||
def test
|
||||
@hook = SystemHook.find(params[:hook_id])
|
||||
data = {
|
||||
event_name: "project_create",
|
||||
name: "Ruby",
|
||||
path: "ruby",
|
||||
project_id: 1,
|
||||
owner_name: "Someone",
|
||||
owner_email: "example@gitlabhq.com"
|
||||
}
|
||||
@hook.execute(data)
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
|
@ -1,45 +0,0 @@
|
|||
class Admin::MailerController < ApplicationController
|
||||
layout "admin"
|
||||
before_filter :authenticate_user!
|
||||
before_filter :authenticate_admin!
|
||||
|
||||
def preview
|
||||
|
||||
end
|
||||
|
||||
def preview_note
|
||||
@note = Note.first
|
||||
@user = @note.author
|
||||
@project = @note.project
|
||||
case params[:type]
|
||||
when "Commit" then
|
||||
@commit = @project.commit
|
||||
render :file => 'notify/note_commit_email', :layout => 'notify'
|
||||
when "Issue" then
|
||||
@issue = Issue.first
|
||||
render :file => 'notify/note_issue_email', :layout => 'notify'
|
||||
else
|
||||
render :file => 'notify/note_wall_email', :layout => 'notify'
|
||||
end
|
||||
rescue
|
||||
render :text => "Preview not available"
|
||||
end
|
||||
|
||||
def preview_user_new
|
||||
@user = User.first
|
||||
@password = "DHasJKDHAS!"
|
||||
|
||||
render :file => 'notify/new_user_email', :layout => 'notify'
|
||||
rescue
|
||||
render :text => "Preview not available"
|
||||
end
|
||||
|
||||
def preview_issue_new
|
||||
@issue = Issue.first
|
||||
@user = @issue.assignee
|
||||
@project = @issue.project
|
||||
render :file => 'notify/new_issue_email', :layout => 'notify'
|
||||
rescue
|
||||
render :text => "Preview not available"
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ class Admin::ProjectsController < ApplicationController
|
|||
def index
|
||||
@admin_projects = Project.scoped
|
||||
@admin_projects = @admin_projects.search(params[:name]) if params[:name].present?
|
||||
@admin_projects = @admin_projects.page(params[:page])
|
||||
@admin_projects = @admin_projects.page(params[:page]).per(20)
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -72,6 +72,6 @@ class Admin::ProjectsController < ApplicationController
|
|||
@admin_project = Project.find_by_code(params[:id])
|
||||
@admin_project.destroy
|
||||
|
||||
redirect_to admin_projects_url
|
||||
redirect_to admin_projects_url, notice: 'Project was successfully deleted.'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,7 +52,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def layout_by_resource
|
||||
if devise_controller?
|
||||
"devise"
|
||||
"devise_layout"
|
||||
else
|
||||
"application"
|
||||
end
|
||||
|
|
|
@ -26,43 +26,31 @@ class CommitsController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
@commit = project.commit(params[:id])
|
||||
result = CommitLoad.new(project, current_user, params).execute
|
||||
|
||||
git_not_found! and return unless @commit
|
||||
@commit = result[:commit]
|
||||
|
||||
@commit = CommitDecorator.decorate(@commit)
|
||||
|
||||
@note = @project.build_commit_note(@commit)
|
||||
@comments_allowed = true
|
||||
@line_notes = project.commit_line_notes(@commit)
|
||||
|
||||
@notes_count = @line_notes.count + project.commit_notes(@commit).count
|
||||
|
||||
if @commit.diffs.size > 200 && !params[:force_show_diff]
|
||||
@suppress_diff = true
|
||||
if @commit
|
||||
@suppress_diff = result[:suppress_diff]
|
||||
@note = result[:note]
|
||||
@line_notes = result[:line_notes]
|
||||
@notes_count = result[:notes_count]
|
||||
@comments_allowed = true
|
||||
else
|
||||
return git_not_found!
|
||||
end
|
||||
|
||||
rescue Grit::Git::GitTimeout
|
||||
render "huge_commit"
|
||||
end
|
||||
|
||||
def compare
|
||||
first = project.commit(params[:to].try(:strip))
|
||||
last = project.commit(params[:from].try(:strip))
|
||||
result = Commit.compare(project, params[:from], params[:to])
|
||||
|
||||
@diffs = []
|
||||
@commits = []
|
||||
@commits = result[:commits]
|
||||
@commit = result[:commit]
|
||||
@diffs = result[:diffs]
|
||||
@line_notes = []
|
||||
|
||||
if first && last
|
||||
commits = [first, last].sort_by(&:created_at)
|
||||
younger = commits.first
|
||||
older = commits.last
|
||||
|
||||
|
||||
@commits = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
|
||||
@diffs = project.repo.diff(younger.id, older.id) rescue []
|
||||
@commit = Commit.new(older)
|
||||
end
|
||||
end
|
||||
|
||||
def patch
|
||||
|
|
|
@ -2,15 +2,13 @@ class DashboardController < ApplicationController
|
|||
respond_to :html
|
||||
|
||||
def index
|
||||
@projects = current_user.projects.includes(:events).order("events.created_at DESC")
|
||||
@projects = @projects.page(params[:page]).per(40)
|
||||
|
||||
@events = Event.where(:project_id => current_user.projects.map(&:id)).recent.limit(20)
|
||||
|
||||
@projects = current_user.projects_with_events.page(params[:page]).per(40)
|
||||
@events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0)
|
||||
@last_push = current_user.recent_push
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
format.atom { render :layout => false }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,24 +11,24 @@ class HooksController < ApplicationController
|
|||
respond_to :html
|
||||
|
||||
def index
|
||||
@hooks = @project.web_hooks.all
|
||||
@hook = WebHook.new
|
||||
@hooks = @project.hooks.all
|
||||
@hook = ProjectHook.new
|
||||
end
|
||||
|
||||
def create
|
||||
@hook = @project.web_hooks.new(params[:hook])
|
||||
@hook = @project.hooks.new(params[:hook])
|
||||
@hook.save
|
||||
|
||||
if @hook.valid?
|
||||
redirect_to project_hooks_path(@project)
|
||||
else
|
||||
@hooks = @project.web_hooks.all
|
||||
@hooks = @project.hooks.all
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def test
|
||||
@hook = @project.web_hooks.find(params[:id])
|
||||
@hook = @project.hooks.find(params[:id])
|
||||
commits = @project.commits(@project.default_branch, nil, 3)
|
||||
data = @project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{@project.default_branch}", current_user)
|
||||
@hook.execute(data)
|
||||
|
@ -37,7 +37,7 @@ class HooksController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
@hook = @project.web_hooks.find(params[:id])
|
||||
@hook = @project.hooks.find(params[:id])
|
||||
@hook.destroy
|
||||
|
||||
redirect_to project_hooks_path(@project)
|
||||
|
|
|
@ -24,16 +24,7 @@ class MergeRequestsController < ApplicationController
|
|||
|
||||
|
||||
def index
|
||||
@merge_requests = @project.merge_requests
|
||||
|
||||
@merge_requests = case params[:f].to_i
|
||||
when 1 then @merge_requests
|
||||
when 2 then @merge_requests.closed
|
||||
when 3 then @merge_requests.opened.assigned(current_user)
|
||||
else @merge_requests.opened
|
||||
end.page(params[:page]).per(20)
|
||||
|
||||
@merge_requests = @merge_requests.includes(:author, :project).order("closed, created_at desc")
|
||||
@merge_requests = MergeRequestsLoad.new(project, current_user, params).execute
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
|
@ -40,25 +40,6 @@ class NotesController < ApplicationController
|
|||
protected
|
||||
|
||||
def notes
|
||||
@notes = case params[:target_type]
|
||||
when "commit"
|
||||
then project.commit_notes(project.commit((params[:target_id]))).fresh.limit(20)
|
||||
when "snippet"
|
||||
then project.snippets.find(params[:target_id]).notes
|
||||
when "wall"
|
||||
then project.common_notes.order("created_at DESC").fresh.limit(50)
|
||||
when "issue"
|
||||
then project.issues.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
|
||||
when "merge_request"
|
||||
then project.merge_requests.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
|
||||
end
|
||||
|
||||
@notes = if params[:last_id]
|
||||
@notes.where("id > ?", params[:last_id])
|
||||
elsif params[:first_id]
|
||||
@notes.where("id < ?", params[:first_id])
|
||||
else
|
||||
@notes
|
||||
end
|
||||
@notes = NotesLoad.new(project, current_user, params).execute
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
|
||||
# Extend the standard message generation to accept our custom exception
|
||||
def failure_message
|
||||
exception = env["omniauth.error"]
|
||||
if exception.class == OmniAuth::Error
|
||||
error = exception.message
|
||||
else
|
||||
error = exception.error_reason if exception.respond_to?(:error_reason)
|
||||
error ||= exception.error if exception.respond_to?(:error)
|
||||
error ||= env["omniauth.error.type"].to_s
|
||||
end
|
||||
error.to_s.humanize if error
|
||||
end
|
||||
|
||||
def ldap
|
||||
# We only find ourselves here if the authentication to LDAP was successful.
|
||||
|
|
|
@ -9,7 +9,7 @@ class RefsController < ApplicationController
|
|||
before_filter :require_non_empty_project
|
||||
|
||||
before_filter :ref
|
||||
before_filter :define_tree_vars, :only => [:tree, :blob, :blame]
|
||||
before_filter :define_tree_vars, :only => [:tree, :blob, :blame, :logs_tree]
|
||||
before_filter :render_full_content
|
||||
|
||||
layout "project"
|
||||
|
@ -46,6 +46,18 @@ class RefsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def logs_tree
|
||||
contents = @tree.contents
|
||||
@logs = contents.map do |content|
|
||||
file = params[:path] ? File.join(params[:path], content.name) : content.name
|
||||
last_commit = @project.commits(@commit.id, file, 1).last
|
||||
{
|
||||
:file_name => content.name,
|
||||
:commit => last_commit
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def blob
|
||||
if @tree.is_blob?
|
||||
if @tree.text?
|
||||
|
@ -79,6 +91,15 @@ class RefsController < ApplicationController
|
|||
@commit = project.commit(@ref)
|
||||
@tree = Tree.new(@commit.tree, project, @ref, params[:path])
|
||||
@tree = TreeDecorator.new(@tree)
|
||||
@hex_path = Digest::SHA1.hexdigest(params[:path] || "/")
|
||||
|
||||
if params[:path]
|
||||
@history_path = tree_file_project_ref_path(@project, @ref, params[:path])
|
||||
@logs_path = logs_file_project_ref_path(@project, @ref, params[:path])
|
||||
else
|
||||
@history_path = tree_project_ref_path(@project, @ref)
|
||||
@logs_path = logs_tree_project_ref_path(@project, @ref)
|
||||
end
|
||||
rescue
|
||||
return render_404
|
||||
end
|
||||
|
|
25
app/decorators/event_decorator.rb
Normal file
25
app/decorators/event_decorator.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
class EventDecorator < ApplicationDecorator
|
||||
decorates :event
|
||||
|
||||
def feed_title
|
||||
if self.issue?
|
||||
"#{self.author_name} #{self.action_name} issue ##{self.target_id}:" + self.issue_title
|
||||
elsif self.merge_request?
|
||||
"#{self.author_name} #{self.action_name} MR ##{self.target_id}:" + self.merge_request_title
|
||||
elsif self.push?
|
||||
"#{self.author_name} #{self.push_action_name} #{self.ref_type} " + self.ref_name
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def feed_url
|
||||
if self.issue?
|
||||
h.project_issue_url(self.project, self.issue)
|
||||
elsif self.merge_request?
|
||||
h.project_merge_request_url(self.project, self.merge_request)
|
||||
elsif self.push?
|
||||
h.project_commits_url(self.project, :ref => self.ref_name)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -134,4 +134,8 @@ module ApplicationHelper
|
|||
end
|
||||
active ? "current" : nil
|
||||
end
|
||||
|
||||
def hexdigest(string)
|
||||
Digest::SHA1.hexdigest string
|
||||
end
|
||||
end
|
||||
|
|
27
app/helpers/tree_helper.rb
Normal file
27
app/helpers/tree_helper.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module TreeHelper
|
||||
def tree_icon(content)
|
||||
if content.is_a?(Grit::Blob)
|
||||
if content.text?
|
||||
image_tag "file_txt.png"
|
||||
elsif content.image?
|
||||
image_tag "file_img.png"
|
||||
else
|
||||
image_tag "file_bin.png"
|
||||
end
|
||||
else
|
||||
image_tag "file_dir.png"
|
||||
end
|
||||
end
|
||||
|
||||
def tree_hex_class(content)
|
||||
"file_#{hexdigest(content.name)}"
|
||||
end
|
||||
|
||||
def tree_full_path(content)
|
||||
if params[:path]
|
||||
File.join(params[:path], content.name)
|
||||
else
|
||||
content.name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -80,6 +80,29 @@ class Commit
|
|||
def commits_between(repo, from, to)
|
||||
repo.commits_between(from, to).map { |c| Commit.new(c) }
|
||||
end
|
||||
|
||||
def compare(project, from, to)
|
||||
first = project.commit(to.try(:strip))
|
||||
last = project.commit(from.try(:strip))
|
||||
|
||||
result = {
|
||||
:commits => [],
|
||||
:diffs => [],
|
||||
:commit => nil
|
||||
}
|
||||
|
||||
if first && last
|
||||
commits = [first, last].sort_by(&:created_at)
|
||||
younger = commits.first
|
||||
older = commits.last
|
||||
|
||||
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
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def persisted?
|
||||
|
|
|
@ -28,6 +28,10 @@ class Event < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.recent_for_user user
|
||||
where(:project_id => user.projects.map(&:id)).recent
|
||||
end
|
||||
|
||||
# Next events currently enabled for system
|
||||
# - push
|
||||
# - new issue
|
||||
|
|
|
@ -22,7 +22,6 @@ class MergeRequest < ActiveRecord::Base
|
|||
:should_remove_source_branch
|
||||
|
||||
validates_presence_of :project_id
|
||||
validates_presence_of :assignee_id
|
||||
validates_presence_of :author_id
|
||||
validates_presence_of :source_branch
|
||||
validates_presence_of :target_branch
|
||||
|
@ -36,6 +35,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
delegate :name,
|
||||
:email,
|
||||
:to => :assignee,
|
||||
:allow_nil => true,
|
||||
:prefix => true
|
||||
|
||||
validates :title,
|
||||
|
@ -128,7 +128,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
|
||||
def unmerged_diffs
|
||||
commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
|
||||
diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id)
|
||||
diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
|
||||
end
|
||||
|
||||
def last_commit
|
||||
|
|
|
@ -19,7 +19,7 @@ class Project < ActiveRecord::Base
|
|||
has_many :notes, :dependent => :destroy
|
||||
has_many :snippets, :dependent => :destroy
|
||||
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
|
||||
has_many :web_hooks, :dependent => :destroy
|
||||
has_many :hooks, :dependent => :destroy, :class_name => "ProjectHook"
|
||||
has_many :wikis, :dependent => :destroy
|
||||
has_many :protected_branches, :dependent => :destroy
|
||||
|
||||
|
@ -120,7 +120,7 @@ class Project < ActiveRecord::Base
|
|||
errors.add(:path, " like 'gitolite-admin' is not allowed")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.access_options
|
||||
UsersProject.access_roles
|
||||
end
|
||||
|
|
3
app/models/project_hook.rb
Normal file
3
app/models/project_hook.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class ProjectHook < WebHook
|
||||
belongs_to :project
|
||||
end
|
13
app/models/system_hook.rb
Normal file
13
app/models/system_hook.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class SystemHook < WebHook
|
||||
|
||||
def async_execute(data)
|
||||
Resque.enqueue(SystemHookWorker, id, data)
|
||||
end
|
||||
|
||||
def self.all_hooks_fire(data)
|
||||
SystemHook.all.each do |sh|
|
||||
sh.async_execute data
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,11 +1,12 @@
|
|||
class User < ActiveRecord::Base
|
||||
|
||||
include Account
|
||||
|
||||
devise :database_authenticatable, :token_authenticatable,
|
||||
devise :database_authenticatable, :token_authenticatable, :lockable,
|
||||
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
|
||||
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio,
|
||||
:name, :projects_limit, :skype, :linkedin, :twitter, :dark_scheme,
|
||||
:name, :projects_limit, :skype, :linkedin, :twitter, :dark_scheme,
|
||||
:theme_id, :force_random_password
|
||||
|
||||
attr_accessor :force_random_password
|
||||
|
@ -15,6 +16,11 @@ class User < ActiveRecord::Base
|
|||
has_many :my_own_projects, :class_name => "Project", :foreign_key => :owner_id
|
||||
has_many :keys, :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,
|
||||
|
@ -80,7 +86,8 @@ class User < ActiveRecord::Base
|
|||
|
||||
def self.find_for_ldap_auth(omniauth_info)
|
||||
name = omniauth_info.name.force_encoding("utf-8")
|
||||
email = omniauth_info.email.downcase
|
||||
email = omniauth_info.email.downcase unless omniauth_info.email.nil?
|
||||
raise OmniAuth::Error, "LDAP accounts must provide an email address" if email.nil?
|
||||
|
||||
if @user = User.find_by_email(email)
|
||||
@user
|
||||
|
|
|
@ -68,7 +68,7 @@ class UsersProject < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def repo_access_human
|
||||
""
|
||||
self.class.access_roles.invert[self.project_access]
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
|
|
|
@ -4,8 +4,6 @@ class WebHook < ActiveRecord::Base
|
|||
# HTTParty timeout
|
||||
default_timeout 10
|
||||
|
||||
belongs_to :project
|
||||
|
||||
validates :url,
|
||||
presence: true,
|
||||
format: {
|
||||
|
@ -14,9 +12,8 @@ class WebHook < ActiveRecord::Base
|
|||
|
||||
def execute(data)
|
||||
WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
|
||||
rescue
|
||||
# There was a problem calling this web hook, let's forget about it.
|
||||
end
|
||||
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
|
|
|
@ -43,7 +43,7 @@ class MailerObserver < ActiveRecord::Observer
|
|||
end
|
||||
|
||||
def new_merge_request(merge_request)
|
||||
if merge_request.assignee != current_user
|
||||
if merge_request.assignee && merge_request.assignee != current_user
|
||||
Notify.new_merge_request_email(merge_request.id).deliver
|
||||
end
|
||||
end
|
||||
|
|
67
app/observers/system_hook_observer.rb
Normal file
67
app/observers/system_hook_observer.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
class SystemHookObserver < ActiveRecord::Observer
|
||||
observe :user, :project, :users_project
|
||||
|
||||
def after_create(model)
|
||||
if model.kind_of? Project
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "project_create",
|
||||
name: model.name,
|
||||
path: model.path,
|
||||
project_id: model.id,
|
||||
owner_name: model.owner.name,
|
||||
owner_email: model.owner.email,
|
||||
created_at: model.created_at
|
||||
})
|
||||
elsif model.kind_of? User
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "user_create",
|
||||
name: model.name,
|
||||
email: model.email,
|
||||
created_at: model.created_at
|
||||
})
|
||||
|
||||
elsif model.kind_of? UsersProject
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "user_add_to_team",
|
||||
project_name: model.project.name,
|
||||
project_path: model.project.path,
|
||||
project_id: model.project_id,
|
||||
user_name: model.user.name,
|
||||
user_email: model.user.email,
|
||||
project_access: model.repo_access_human,
|
||||
created_at: model.created_at
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def after_destroy(model)
|
||||
if model.kind_of? Project
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "project_destroy",
|
||||
name: model.name,
|
||||
path: model.path,
|
||||
project_id: model.id,
|
||||
owner_name: model.owner.name,
|
||||
owner_email: model.owner.email,
|
||||
})
|
||||
elsif model.kind_of? User
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "user_destroy",
|
||||
name: model.name,
|
||||
email: model.email
|
||||
})
|
||||
|
||||
elsif model.kind_of? UsersProject
|
||||
SystemHook.all_hooks_fire({
|
||||
event_name: "user_remove_from_team",
|
||||
project_name: model.project.name,
|
||||
project_path: model.project.path,
|
||||
project_id: model.project_id,
|
||||
user_name: model.user.name,
|
||||
user_email: model.user.email,
|
||||
project_access: model.repo_access_human
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
|
@ -55,4 +55,8 @@ module Account
|
|||
# Take only latest one
|
||||
events = events.recent.limit(1).first
|
||||
end
|
||||
|
||||
def projects_with_events
|
||||
projects.includes(:events).order("events.created_at DESC")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ module GitPush
|
|||
true
|
||||
end
|
||||
|
||||
def execute_web_hooks(oldrev, newrev, ref, user)
|
||||
def execute_hooks(oldrev, newrev, ref, user)
|
||||
ref_parts = ref.split('/')
|
||||
|
||||
# Return if this is not a push to a branch (e.g. new commits)
|
||||
|
@ -35,7 +35,7 @@ module GitPush
|
|||
|
||||
data = post_receive_data(oldrev, newrev, ref, user)
|
||||
|
||||
web_hooks.each { |web_hook| web_hook.execute(data) }
|
||||
hooks.each { |hook| hook.execute(data) }
|
||||
end
|
||||
|
||||
def post_receive_data(oldrev, newrev, ref, user)
|
||||
|
@ -97,7 +97,7 @@ module GitPush
|
|||
self.update_merge_requests(oldrev, newrev, ref, user)
|
||||
|
||||
# Execute web hooks
|
||||
self.execute_web_hooks(oldrev, newrev, ref, user)
|
||||
self.execute_hooks(oldrev, newrev, ref, user)
|
||||
|
||||
# Create satellite
|
||||
self.satellite.create unless self.satellite.exists?
|
||||
|
|
66
app/views/admin/hooks/_data_ex.html.erb
Normal file
66
app/views/admin/hooks/_data_ex.html.erb
Normal file
|
@ -0,0 +1,66 @@
|
|||
<% data_ex_str = <<eos
|
||||
1. Project created:
|
||||
{
|
||||
"created_at": "2012-07-21T07:30:54Z",
|
||||
"event_name": "project_create",
|
||||
"name": "StoreCloud",
|
||||
"owner_email": "johnsmith@gmail.com",
|
||||
"owner_name": "John Smith",
|
||||
"path": "storecloud",
|
||||
"project_id": 74
|
||||
}
|
||||
|
||||
2. Project destroyed:
|
||||
{
|
||||
"event_name": "project_destroy",
|
||||
"name": "Underscore",
|
||||
"owner_email": "johnsmith@gmail.com",
|
||||
"owner_name": "John Smith",
|
||||
"path": "underscore",
|
||||
"project_id": 73
|
||||
}
|
||||
|
||||
3. New Team Member:
|
||||
{
|
||||
"created_at": "2012-07-21T07:30:56Z",
|
||||
"event_name": "user_add_to_team",
|
||||
"project_access": "Master",
|
||||
"project_id": 74,
|
||||
"project_name": "StoreCloud",
|
||||
"project_path": "storecloud",
|
||||
"owner_email": "johnsmith@gmail.com",
|
||||
"owner_name": "John Smith",
|
||||
}
|
||||
|
||||
4. Team Member Removed:
|
||||
{
|
||||
"created_at": "2012-07-21T07:30:56Z",
|
||||
"event_name": "user_remove_from_team",
|
||||
"project_access": "Master",
|
||||
"project_id": 74,
|
||||
"project_name": "StoreCloud",
|
||||
"project_path": "storecloud",
|
||||
"owner_email": "johnsmith@gmail.com",
|
||||
"owner_name": "John Smith",
|
||||
}
|
||||
|
||||
5. User created:
|
||||
{
|
||||
"created_at": "2012-07-21T07:44:07Z",
|
||||
"email": "js@gitlabhq.com",
|
||||
"event_name": "user_create",
|
||||
"name": "John Smith"
|
||||
}
|
||||
|
||||
6. User removed:
|
||||
{
|
||||
"created_at": "2012-07-21T07:44:07Z",
|
||||
"email": "js@gitlabhq.com",
|
||||
"event_name": "user_destroy",
|
||||
"name": "John Smith"
|
||||
}
|
||||
|
||||
eos
|
||||
%>
|
||||
<% js_lexer = Pygments::Lexer[:js] %>
|
||||
<%= raw js_lexer.highlight(data_ex_str) %>
|
39
app/views/admin/hooks/index.html.haml
Normal file
39
app/views/admin/hooks/index.html.haml
Normal file
|
@ -0,0 +1,39 @@
|
|||
.alert.alert-info
|
||||
%span
|
||||
Post receive hooks for binding events.
|
||||
%br
|
||||
Read more about system hooks
|
||||
%strong #{link_to "here", help_system_hooks_path, :class => "vlink"}
|
||||
|
||||
= form_for @hook, :as => :hook, :url => admin_hooks_path do |f|
|
||||
-if @hook.errors.any?
|
||||
.alert-message.block-message.error
|
||||
- @hook.errors.full_messages.each do |msg|
|
||||
%p= msg
|
||||
.clearfix
|
||||
= f.label :url, "URL:"
|
||||
.input
|
||||
= f.text_field :url, :class => "text_field xxlarge"
|
||||
|
||||
= f.submit "Add System Hook", :class => "btn primary"
|
||||
%hr
|
||||
|
||||
-if @hooks.any?
|
||||
%h3
|
||||
Hooks
|
||||
%small (#{@hooks.count})
|
||||
%br
|
||||
%table.admin-table
|
||||
%tr
|
||||
%th URL
|
||||
%th Method
|
||||
%th
|
||||
- @hooks.each do |hook|
|
||||
%tr
|
||||
%td
|
||||
= link_to admin_hook_path(hook) do
|
||||
%strong= hook.url
|
||||
= link_to 'Test Hook', admin_hook_test_path(hook), :class => "btn small right"
|
||||
%td POST
|
||||
%td
|
||||
= link_to 'Remove', admin_hook_path(hook), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn small right"
|
|
@ -1,6 +1,9 @@
|
|||
%h4
|
||||
%i.icon-file
|
||||
githost.log
|
||||
%pre.logs
|
||||
- Gitlab::Logger.read_latest.each do |line|
|
||||
%span.log= line
|
||||
.file_holder#README
|
||||
.file_title
|
||||
%i.icon-file
|
||||
githost.log
|
||||
.file_content.logs
|
||||
%ol
|
||||
- Gitlab::Logger.read_latest.each do |line|
|
||||
%li
|
||||
%p= line
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
%p This is page with preview for all system emails that are sent to user
|
||||
%p Email previews built based on existing Project/Commit/Issue base - so some preview maybe unavailable unless object appear in system
|
||||
|
||||
#accordion
|
||||
%h3
|
||||
%a New user
|
||||
%div
|
||||
%iframe{ :src=> admin_mailer_preview_user_new_path, :width=>"100%", :height=>"350"}
|
||||
%h3
|
||||
%a New issue
|
||||
%div
|
||||
%iframe{ :src=> admin_mailer_preview_issue_new_path, :width=>"100%", :height=>"350"}
|
||||
%h3
|
||||
%a Commit note
|
||||
%div
|
||||
%iframe{ :src=> admin_mailer_preview_note_path(:type => "Commit"), :width=>"100%", :height=>"350"}
|
||||
%h3
|
||||
%a Issue note
|
||||
%div
|
||||
%iframe{ :src=> admin_mailer_preview_note_path(:type => "Issue"), :width=>"100%", :height=>"350"}
|
||||
%h3
|
||||
%a Wall note
|
||||
%div
|
||||
%iframe{ :src=> admin_mailer_preview_note_path(:type => "Wall"), :width=>"100%", :height=>"350"}
|
||||
|
||||
:javascript
|
||||
$(function() {
|
||||
$("#accordion").accordion(); });
|
|
@ -13,8 +13,8 @@
|
|||
%th Team Members
|
||||
%th Post Receive
|
||||
%th Last Commit
|
||||
%th
|
||||
%th
|
||||
%th Edit
|
||||
%th.cred Danger Zone!
|
||||
|
||||
- @admin_projects.each do |project|
|
||||
%tr
|
||||
|
@ -24,5 +24,5 @@
|
|||
%td= check_box_tag :post_receive_file, 1, project.has_post_receive_file?, :disabled => true
|
||||
%td= last_commit(project)
|
||||
%td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}", :class => "btn small"
|
||||
%td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger"
|
||||
%td.bgred= link_to 'Destroy', [:admin, project], :confirm => "REMOVE #{project.name}? Are you sure?", :method => :delete, :class => "btn small danger"
|
||||
= paginate @admin_projects, :theme => "admin"
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
.alert
|
||||
.clearfix
|
||||
%p Give user ability to manage application.
|
||||
%p Make the user a GitLab administrator.
|
||||
= f.label :admin, :class => "checkbox" do
|
||||
= f.check_box :admin
|
||||
%span Administrator
|
||||
|
@ -59,11 +59,11 @@
|
|||
- if @admin_user.blocked
|
||||
%span
|
||||
= link_to 'Unblock', unblock_admin_user_path(@admin_user), :method => :put, :class => "btn small"
|
||||
This user is blocked and is not able to login GitLab
|
||||
This user is blocked and is not able to login to GitLab
|
||||
- else
|
||||
%span
|
||||
= link_to 'Block', block_admin_user_path(@admin_user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger"
|
||||
Blocked user will removed from all projects & will not be able to login to GitLab.
|
||||
Blocked users will be removed from all projects & will not be able to login to GitLab.
|
||||
.actions
|
||||
= f.submit 'Save', :class => "btn primary"
|
||||
- if @admin_user.new_record?
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
%th Projects
|
||||
%th Edit
|
||||
%th Blocked
|
||||
%th
|
||||
%th.cred Danger Zone!
|
||||
|
||||
- @admin_users.each do |user|
|
||||
%tr
|
||||
|
@ -41,6 +41,6 @@
|
|||
= link_to 'Unblock', unblock_admin_user_path(user), :method => :put, :class => "btn small success"
|
||||
- else
|
||||
= link_to 'Block', block_admin_user_path(user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger"
|
||||
%td= link_to 'Destroy', [:admin, user], :confirm => 'USER WILL BE REMOVED! Are you sure?', :method => :delete, :class => "btn small danger"
|
||||
%td.bgred= link_to 'Destroy', [:admin, user], :confirm => "USER #{user.name} WILL BE REMOVED! Are you sure?", :method => :delete, :class => "btn small danger"
|
||||
|
||||
= paginate @admin_users, :theme => "admin"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @commits.group_by { |c| c.committed_date.to_date }.each do |day, commits|
|
||||
%div.ui-box
|
||||
%h5= day.stamp("28 Aug, 2010")
|
||||
%h5.small
|
||||
%i.icon-calendar
|
||||
= day.stamp("28 Aug, 2010")
|
||||
%ul.unstyled= render commits
|
||||
|
|
|
@ -35,7 +35,13 @@
|
|||
- if file.text?
|
||||
= render "commits/text_file", :diff => diff, :index => i
|
||||
- elsif file.image?
|
||||
.diff_file_content_image{:class => image_diff_class(diff)}
|
||||
%img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
||||
- if diff.renamed_file || diff.new_file || diff.deleted_file
|
||||
.diff_file_content_image
|
||||
%img{:class => image_diff_class(diff), :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
||||
- else
|
||||
- old_file = (@commit.prev_commit.tree / diff.old_path)
|
||||
.diff_file_content_image.img_compared
|
||||
%img{:class => "diff_image_removed", :src => "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
|
||||
%img{:class => "diff_image_added", :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
||||
- else
|
||||
%p.nothing_here_message No preview for this file type
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
%li{:class => "#{branches_tab_class}"}
|
||||
= link_to project_repository_path(@project) do
|
||||
Branches
|
||||
%span.number= @project.repo.branch_count
|
||||
%span.badge= @project.repo.branch_count
|
||||
|
||||
%li{:class => "#{'active' if current_page?(tags_project_repository_path(@project)) }"}
|
||||
= link_to tags_project_repository_path(@project) do
|
||||
Tags
|
||||
%span.number= @project.repo.tag_count
|
||||
%span.badge= @project.repo.tag_count
|
||||
|
||||
|
||||
- if current_page?(project_commits_path(@project)) && current_user.private_token
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
= "..."
|
||||
= text_field_tag :to, params[:to], :placeholder => "aa8b4ef", :class => "xlarge"
|
||||
.actions
|
||||
= submit_tag "Compare", :class => "btn primary"
|
||||
= submit_tag "Compare", :class => "btn btn-primary"
|
||||
|
||||
|
||||
- unless @commits.empty?
|
||||
|
|
|
@ -8,17 +8,10 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
|||
|
||||
@events.each do |event|
|
||||
if event.allowed?
|
||||
event = EventDecorator.decorate(event)
|
||||
xml.entry do
|
||||
if event.issue?
|
||||
event_link = project_issue_url(event.project, event.issue)
|
||||
event_title = event.issue_title
|
||||
elsif event.merge_request?
|
||||
event_link = project_merge_request_url(event.project, event.merge_request)
|
||||
event_title = event.merge_request_title
|
||||
elsif event.push?
|
||||
event_link = project_commits_url(event.project, :ref => event.ref_name)
|
||||
event_title = event.ref_name
|
||||
end
|
||||
event_link = event.feed_url
|
||||
event_title = event.feed_title
|
||||
|
||||
xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
|
||||
xml.link :href => event_link
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
add new key
|
||||
to your profile
|
||||
- if @events.any?
|
||||
= render @events
|
||||
.content_list= render @events
|
||||
- else
|
||||
%h4.nothing_here_message Projects activity will be displayed here
|
||||
.loading.hide
|
||||
.side
|
||||
= render "events/event_last_push", :event => @last_push
|
||||
.projects_box
|
||||
|
@ -54,3 +55,7 @@
|
|||
New Project »
|
||||
- else
|
||||
If you will be added to project - it will be displayed here
|
||||
|
||||
|
||||
:javascript
|
||||
$(function(){ Pager.init(20); });
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
:plain
|
||||
$(".projects .activities").append("#{escape_javascript(render(@events))}");
|
||||
Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
%span.event_label= event.action_name
|
||||
issue
|
||||
%span.event_label{:class => event.action_name}= event.action_name
|
||||
issue
|
||||
= link_to project_issue_path(event.project, event.issue) do
|
||||
%strong= truncate event.issue_title
|
||||
at
|
||||
|
|
|
@ -5,12 +5,9 @@
|
|||
%span Your pushed to
|
||||
= event.ref_type
|
||||
= link_to project_commits_path(event.project, :ref => event.ref_name) do
|
||||
%strong= event.ref_name
|
||||
%strong= truncate(event.ref_name, :length => 28)
|
||||
at
|
||||
%strong= link_to event.project.name, event.project
|
||||
%span.cgray
|
||||
= time_ago_in_words(event.created_at)
|
||||
ago.
|
||||
|
||||
= link_to new_mr_path_from_push_event(event), :title => "New Merge Request", :class => "btn very_small primary" do
|
||||
Create Merge Request
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
.event_icon= image_tag "event_mr_merged.png"
|
||||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
%span.event_label= event.action_name
|
||||
merge request
|
||||
%span.event_label{:class => event.action_name}= event.action_name
|
||||
merge request
|
||||
= link_to project_merge_request_path(event.project, event.merge_request) do
|
||||
%strong= truncate event.merge_request_title
|
||||
at
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.event_icon= image_tag "event_push.png"
|
||||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
%span.event_label= event.push_action_name
|
||||
%span.event_label.pushed= event.push_action_name
|
||||
= event.ref_type
|
||||
= link_to project_commits_path(event.project, :ref => event.ref_name) do
|
||||
%strong= event.ref_name
|
||||
|
|
41
app/views/help/api.html.haml
Normal file
41
app/views/help/api.html.haml
Normal file
|
@ -0,0 +1,41 @@
|
|||
%h3 API
|
||||
.back_link
|
||||
= link_to help_path do
|
||||
← to index
|
||||
%hr
|
||||
|
||||
%ol
|
||||
%li
|
||||
%a{:href => "#README"} README
|
||||
%li
|
||||
%a{:href => "#projects"} Projects
|
||||
%li
|
||||
%a{:href => "#users"} Users
|
||||
|
||||
.file_holder#README
|
||||
.file_title
|
||||
%i.icon-file
|
||||
README
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown File.read(Rails.root.join("doc", "api", "README.md"))
|
||||
|
||||
%br
|
||||
|
||||
.file_holder#projects
|
||||
.file_title
|
||||
%i.icon-file
|
||||
Projects
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown File.read(Rails.root.join("doc", "api", "projects.md"))
|
||||
|
||||
%br
|
||||
|
||||
.file_holder#users
|
||||
.file_title
|
||||
%i.icon-file
|
||||
Users
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown File.read(Rails.root.join("doc", "api", "users.md"))
|
|
@ -22,3 +22,9 @@
|
|||
|
||||
%li
|
||||
%h5= link_to "Web Hooks", help_web_hooks_path
|
||||
|
||||
%li
|
||||
%h5= link_to "System Hooks", help_system_hooks_path
|
||||
|
||||
%li
|
||||
%h5= link_to "API", help_api_path
|
||||
|
|
13
app/views/help/system_hooks.html.haml
Normal file
13
app/views/help/system_hooks.html.haml
Normal file
|
@ -0,0 +1,13 @@
|
|||
%h3 System hooks
|
||||
.back_link
|
||||
= link_to :back do
|
||||
← back
|
||||
%hr
|
||||
|
||||
%p.slead
|
||||
Your Gitlab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member.
|
||||
%br
|
||||
System Hooks can be used for logging or change information in LDAP server.
|
||||
%br
|
||||
%h5 Hooks request example:
|
||||
= render "admin/hooks/data_ex"
|
|
@ -6,7 +6,9 @@
|
|||
.row
|
||||
.span7= paginate @issues, :remote => true, :theme => "gitlab"
|
||||
.span3.right
|
||||
%span.cgray.right #{@issues.total_count} issues for this filter
|
||||
%span.cgray.right
|
||||
%span.issue_counter #{@issues.total_count}
|
||||
issues for this filter
|
||||
- else
|
||||
%li
|
||||
%h4.nothing_here_message Nothing to show here
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
= issue.notes.count
|
||||
- if can? current_user, :modify_issue, issue
|
||||
- if issue.closed
|
||||
= link_to 'Reopen', project_issue_path(issue.project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "btn small grouped", :remote => true
|
||||
= link_to 'Reopen', project_issue_path(issue.project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "btn small grouped reopen_issue", :remote => true
|
||||
- else
|
||||
= link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "success btn small grouped", :remote => true
|
||||
= link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "success btn small grouped close_issue", :remote => true
|
||||
= link_to edit_project_issue_path(issue.project, issue), :class => "btn small edit-issue-link", :remote => true do
|
||||
%i.icon-edit
|
||||
Edit
|
||||
|
@ -35,6 +35,4 @@
|
|||
|
||||
|
||||
- if issue.upvotes > 0
|
||||
%span.badge.badge-success= "+#{issue.upvotes}"
|
||||
|
||||
|
||||
%span.badge.badge-success= "+#{issue.upvotes}"
|
|
@ -2,7 +2,7 @@
|
|||
.issues_content
|
||||
%h3.page_title
|
||||
Issues
|
||||
%small (#{@issues.total_count})
|
||||
%small (<span class=issue_counter>#{@issues.total_count}</span>)
|
||||
.right
|
||||
.span5
|
||||
- if can? current_user, :write_issue, @project
|
||||
|
@ -45,4 +45,4 @@
|
|||
:javascript
|
||||
$(function(){
|
||||
issuesPage();
|
||||
})
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
%h3 New key
|
||||
%h3.page_title New key
|
||||
%hr
|
||||
= render 'form'
|
||||
|
||||
|
@ -11,4 +11,4 @@
|
|||
if( key_mail && key_mail.length > 0 && title.val() == '' ){
|
||||
$('#key_title').val( key_mail );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
%li{:class => tab_class(:issues)}
|
||||
= link_to project_issues_filter_path(@project) do
|
||||
Issues
|
||||
%span.count= @project.issues.opened.count
|
||||
%span.count.issue_counter= @project.issues.opened.count
|
||||
|
||||
- if @project.repo_exists?
|
||||
- if @project.merge_requests_enabled
|
||||
%li{:class => tab_class(:merge_requests)}
|
||||
= link_to project_merge_requests_path(@project) do
|
||||
Merge Requests
|
||||
%span.count= @project.merge_requests.opened.count
|
||||
%span.count.merge_counter= @project.merge_requests.opened.count
|
||||
|
||||
- if @project.wall_enabled
|
||||
%li{:class => tab_class(:wall)}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
%li{:class => tab_class(:admin_logs)}
|
||||
= link_to "Logs", admin_logs_path
|
||||
%li{:class => tab_class(:admin_emails)}
|
||||
= link_to "Emails", admin_emails_path
|
||||
= link_to "Hooks", admin_hooks_path
|
||||
%li{:class => tab_class(:admin_resque)}
|
||||
= link_to "Resque", admin_resque_path
|
||||
|
||||
|
|
|
@ -12,16 +12,17 @@
|
|||
%li{:class => tab_class(:password)}
|
||||
= link_to "Password", profile_password_path
|
||||
|
||||
%li{:class => tab_class(:ssh_keys)}
|
||||
= link_to keys_path do
|
||||
SSH Keys
|
||||
%span.count= current_user.keys.count
|
||||
|
||||
%li{:class => tab_class(:token)}
|
||||
= link_to "Token", profile_token_path
|
||||
|
||||
%li{:class => tab_class(:design)}
|
||||
= link_to "Design", profile_design_path
|
||||
|
||||
%li{:class => tab_class(:ssh_keys)}
|
||||
= link_to keys_path do
|
||||
SSH Keys
|
||||
%span.count= current_user.keys.count
|
||||
|
||||
.content
|
||||
= yield
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
- @merge_request.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
%h3.padded.cgray 1. Select Branches
|
||||
%h4.cdark 1. Select Branches
|
||||
%br
|
||||
|
||||
.row
|
||||
.span6
|
||||
|
@ -30,14 +31,21 @@
|
|||
.bottom_commit
|
||||
.mr_target_commit
|
||||
|
||||
%h3.padded.cgray 2. Fill info
|
||||
%h4.cdark 2. Fill info
|
||||
|
||||
.clearfix
|
||||
= f.label :assignee_id, "Assign to", :class => "control-label"
|
||||
.controls= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px")
|
||||
.main_box
|
||||
.top_box_content
|
||||
= f.label :title do
|
||||
%strong= "Title *"
|
||||
.input= f.text_field :title, :class => "input-xxlarge pad", :maxlength => 255, :rows => 5
|
||||
.middle_box_content
|
||||
= f.label :assignee_id do
|
||||
%i.icon-user
|
||||
Assign to
|
||||
.input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px")
|
||||
|
||||
.control-group
|
||||
= f.label :title, :class => "control-label"
|
||||
.controls= f.text_field :title, :class => "input-xxlarge pad", :maxlength => 255, :rows => 5
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Save', :class => "btn-primary btn"
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
→
|
||||
= merge_request.target_branch
|
||||
= image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
|
||||
|
||||
= link_to project_merge_request_path(merge_request.project, merge_request) do
|
||||
%p.row_title= truncate(merge_request.title, :length => 80)
|
||||
|
||||
%span.update-author
|
||||
%strong= merge_request.author_name
|
||||
authored
|
||||
%small.cdark= "##{merge_request.id}"
|
||||
authored by #{merge_request.author_name}
|
||||
= time_ago_in_words(merge_request.created_at)
|
||||
ago
|
||||
- if merge_request.upvotes > 0
|
||||
%span.badge.badge-success= "+#{merge_request.upvotes}"
|
||||
= link_to project_merge_request_path(merge_request.project, merge_request) do
|
||||
%p.row_title= truncate(merge_request.title, :length => 80)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%h3
|
||||
%h3.page_title
|
||||
= "Edit merge request #{@merge_request.id}"
|
||||
%hr
|
||||
= render 'form'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
%h3 New Merge Request
|
||||
%h3.page_title New Merge Request
|
||||
%hr
|
||||
= render 'form'
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
- if @commits.present?
|
||||
.ui-box
|
||||
%h5 Commits (#{@commits.count})
|
||||
%h5
|
||||
%i.icon-list
|
||||
Commits (#{@commits.count})
|
||||
.merge-request-commits
|
||||
- if @commits.count > 8
|
||||
%ul.first_mr_commits.unstyled
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
= image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"
|
||||
%strong.author= link_to_merge_request_author(@merge_request)
|
||||
|
||||
%cite.cgray and currently assigned to
|
||||
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 16, :class => "lil_av"
|
||||
%strong.author= link_to_merge_request_assignee(@merge_request)
|
||||
- if @merge_request.assignee
|
||||
%cite.cgray and currently assigned to
|
||||
= image_tag gravatar_icon(@merge_request.assignee_email), :width => 16, :class => "lil_av"
|
||||
%strong.author= link_to_merge_request_assignee(@merge_request)
|
||||
|
||||
|
||||
- if @merge_request.closed
|
||||
|
|
|
@ -32,4 +32,4 @@
|
|||
%span Any file less than 10 MB
|
||||
|
||||
|
||||
= f.submit 'Add Comment', :class => "btn primary", :id => "submit_note"
|
||||
= f.submit 'Add Comment', :class => "btn primary submit_note", :id => "submit_note"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
= check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
|
||||
%span Commit author
|
||||
.actions
|
||||
= f.submit 'Add note', :class => "btn primary", :id => "submit_note"
|
||||
= f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
|
||||
= link_to "Close", "#", :class => "btn hide-button"
|
||||
|
||||
:javascript
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
%tr.line_notes_row.reply
|
||||
%td{:colspan => 3}
|
||||
%i.icon-comment
|
||||
= link_to "Reply", "#", :class => "line_note_reply_link", "line_code" => line_code, :title => "Add note for this line"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
= render :partial => "refs/tree_file", :locals => { :name => tree.name, :content => tree.data, :file => tree }
|
||||
- else
|
||||
- contents = tree.contents
|
||||
%table#tree-slider.bordered-table.table
|
||||
%table#tree-slider.bordered-table.table{:class => "table_#{@hex_path}" }
|
||||
%thead
|
||||
%th Name
|
||||
%th Last Update
|
||||
|
@ -29,34 +29,39 @@
|
|||
%td
|
||||
%td
|
||||
|
||||
- index = 0
|
||||
- contents.select{ |i| i.is_a?(Grit::Tree)}.each do |content|
|
||||
= render :partial => "refs/tree_item", :locals => { :content => content }
|
||||
= render :partial => "refs/tree_item", :locals => { :content => content, :index => (index += 1) }
|
||||
- contents.select{ |i| i.is_a?(Grit::Blob)}.each do |content|
|
||||
= render :partial => "refs/tree_item", :locals => { :content => content }
|
||||
= render :partial => "refs/tree_item", :locals => { :content => content, :index => (index += 1) }
|
||||
- contents.select{ |i| i.is_a?(Grit::Submodule)}.each do |content|
|
||||
= render :partial => "refs/submodule_item", :locals => { :content => content }
|
||||
= render :partial => "refs/submodule_item", :locals => { :content => content, :index => (index += 1) }
|
||||
|
||||
- if content = contents.select{ |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }.first
|
||||
#tree-readme-holder
|
||||
%h3= content.name
|
||||
.readme
|
||||
.file_holder#README
|
||||
.file_title
|
||||
%i.icon-file
|
||||
= content.name
|
||||
.file_content.wiki
|
||||
- if content.name =~ /\.(md|markdown)$/i
|
||||
= preserve do
|
||||
= markdown(content.data)
|
||||
- else
|
||||
= simple_format(content.data)
|
||||
|
||||
- if params[:path]
|
||||
- history_path = tree_file_project_ref_path(@project, @ref, params[:path])
|
||||
- else
|
||||
- history_path = tree_project_ref_path(@project, @ref)
|
||||
:javascript
|
||||
$(function(){
|
||||
$('select#branch').selectmenu({style:'popup', width:200});
|
||||
$('select#tag').selectmenu({style:'popup', width:200});
|
||||
$('.project-refs-select').chosen();
|
||||
|
||||
history.pushState({ path: this.path }, '', "#{history_path}")
|
||||
history.pushState({ path: this.path }, '', "#{@history_path}");
|
||||
|
||||
});
|
||||
|
||||
// Load last commit log for each file in tree
|
||||
$(window).load(function(){
|
||||
ajaxGet('#{@logs_path}');
|
||||
});
|
||||
|
||||
|
||||
|
|
3
app/views/refs/_tree_commit.html.haml
Normal file
3
app/views/refs/_tree_commit.html.haml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- if tm
|
||||
%strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
|
||||
= link_to truncate(content_commit.safe_message, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
|
|
@ -1,5 +1,5 @@
|
|||
.view_file
|
||||
.view_file_header
|
||||
.file_holder
|
||||
.file_title
|
||||
%i.icon-file
|
||||
%span.file_name
|
||||
= name
|
||||
|
@ -10,26 +10,28 @@
|
|||
= link_to "blame", blame_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
|
||||
- if file.text?
|
||||
- if name =~ /\.(md|markdown)$/i
|
||||
#tree-readme-holder
|
||||
.readme
|
||||
= preserve do
|
||||
= markdown(file.data)
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown(file.data)
|
||||
- else
|
||||
.view_file_content
|
||||
.file_content.code
|
||||
- unless file.empty?
|
||||
%div{:class => current_user.dark_scheme ? "black" : "white"}
|
||||
= preserve do
|
||||
= raw file.colorize(options: { linenos: 'True'})
|
||||
- else
|
||||
%h4.nothing_here_message Empty file
|
||||
|
||||
- elsif file.image?
|
||||
.view_file_content_image
|
||||
.file_content.image_file
|
||||
%img{ :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
||||
|
||||
- else
|
||||
%center
|
||||
= link_to blob_project_ref_path(@project, @ref, :path => params[:path]) do
|
||||
%div.padded
|
||||
%br
|
||||
= image_tag "download.png", :width => 64
|
||||
%h3
|
||||
Download (#{file.mb_size})
|
||||
.file_content.blob_file
|
||||
%center
|
||||
= link_to blob_project_ref_path(@project, @ref, :path => params[:path]) do
|
||||
%div.padded
|
||||
%br
|
||||
= image_tag "download.png", :width => 64
|
||||
%h3
|
||||
Download (#{file.mb_size})
|
||||
|
|
|
@ -1,23 +1,11 @@
|
|||
- file = params[:path] ? File.join(params[:path], content.name) : content.name
|
||||
- content_commit = @project.commits(@commit.id, file, 1).last
|
||||
- return unless content_commit
|
||||
%tr{ :class => "tree-item", :url => tree_file_project_ref_path(@project, @ref, file) }
|
||||
- file = tree_full_path(content)
|
||||
%tr{ :class => "tree-item #{tree_hex_class(content)}", :url => tree_file_project_ref_path(@project, @ref, file) }
|
||||
%td.tree-item-file-name
|
||||
- if content.is_a?(Grit::Blob)
|
||||
- if content.text?
|
||||
= image_tag "file_txt.png"
|
||||
- elsif content.image?
|
||||
= image_tag "file_img.png"
|
||||
- else
|
||||
= image_tag "file_bin.png"
|
||||
- else
|
||||
= image_tag "file_dir.png"
|
||||
= tree_icon(content)
|
||||
= link_to truncate(content.name, :length => 40), tree_file_project_ref_path(@project, @ref || @commit.id, file), :remote => :true
|
||||
%td.cgray
|
||||
= time_ago_in_words(content_commit.committed_date)
|
||||
ago
|
||||
%td.commit
|
||||
- tm = @project.team_member_by_name_or_email(content_commit.author_email, content_commit.author_name)
|
||||
- if tm
|
||||
%strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
|
||||
= link_to truncate(content_commit.safe_message, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
|
||||
%td.tree_time_ago.cgray
|
||||
- if index == 1
|
||||
%span.log_loading
|
||||
Loading commit data..
|
||||
= image_tag "ajax_loader_tree.gif", :width => 14
|
||||
%td.tree_commit
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
%li= link
|
||||
.clear
|
||||
|
||||
.view_file.blame_file
|
||||
.view_file_header
|
||||
.file_holder
|
||||
.file_title
|
||||
%i.icon-file
|
||||
%span.file_name
|
||||
= @tree.name
|
||||
|
@ -21,7 +21,7 @@
|
|||
= link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small", :target => "_blank"
|
||||
= link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "btn very_small"
|
||||
= link_to "source", tree_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
|
||||
.view_file_content
|
||||
.file_content.blame
|
||||
%table
|
||||
- @blame.each do |commit, lines|
|
||||
- commit = Commit.new(commit)
|
||||
|
@ -29,7 +29,7 @@
|
|||
%td.author
|
||||
= image_tag gravatar_icon(commit.author_email, 16)
|
||||
= commit.author_name
|
||||
%td.commit
|
||||
%td.blame_commit
|
||||
|
||||
= link_to project_commit_path(@project, :id => commit.id) do
|
||||
%code= commit.id.to_s[0..10]
|
||||
|
@ -37,8 +37,7 @@
|
|||
%td.lines
|
||||
= preserve do
|
||||
%pre
|
||||
- lines.each do |line|
|
||||
= line
|
||||
= Gitlab::Encode.utf8 lines.join("\n")
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
|
|
9
app/views/refs/logs_tree.js.haml
Normal file
9
app/views/refs/logs_tree.js.haml
Normal file
|
@ -0,0 +1,9 @@
|
|||
- @logs.each do |content_data|
|
||||
- file_name = content_data[:file_name]
|
||||
- content_commit = content_data[:commit]
|
||||
- tm = @project.team_member_by_name_or_email(content_commit.author_email, content_commit.author_name)
|
||||
|
||||
:plain
|
||||
var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}");
|
||||
row.find("td.tree_time_ago").html('#{escape_javascript(time_ago_in_words(content_commit.committed_date))} ago');
|
||||
row.find("td.tree_commit").html('#{escape_javascript(render("tree_commit", :tm => tm, :content_commit => content_commit))}');
|
|
@ -1,4 +1,10 @@
|
|||
:plain
|
||||
// Load Files list
|
||||
$("#tree-holder").html("#{escape_javascript(render(:partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}))}");
|
||||
$("#tree-content-holder").show("slide", { direction: "right" }, 150);
|
||||
$('.project-refs-form #path').val("#{params[:path]}");
|
||||
|
||||
// Load last commit log for each file in tree
|
||||
$('#tree-slider').waitForImages(function() {
|
||||
ajaxGet('#{@logs_path}');
|
||||
});
|
||||
|
|
|
@ -7,16 +7,14 @@
|
|||
= link_to "Edit", edit_project_snippet_path(@project, @snippet), :class => "btn small right"
|
||||
|
||||
%br
|
||||
#tree-holder
|
||||
#tree-content-holder
|
||||
.view_file
|
||||
.view_file_header
|
||||
%i.icon-file
|
||||
%strong= @snippet.file_name
|
||||
%span.options
|
||||
= link_to "raw", raw_project_snippet_path(@project, @snippet), :class => "btn very_small", :target => "_blank"
|
||||
.view_file_content
|
||||
%div{:class => current_user.dark_scheme ? "black" : ""}
|
||||
= raw @snippet.colorize(options: { linenos: 'True'})
|
||||
.file_holder
|
||||
.file_title
|
||||
%i.icon-file
|
||||
%strong= @snippet.file_name
|
||||
%span.options
|
||||
= link_to "raw", raw_project_snippet_path(@project, @snippet), :class => "btn very_small", :target => "_blank"
|
||||
.file_content.code
|
||||
%div{:class => current_user.dark_scheme ? "black" : ""}
|
||||
= raw @snippet.colorize(options: { linenos: 'True'})
|
||||
|
||||
= render "notes/notes", :tid => @snippet.id, :tt => "snippet"
|
||||
|
|
7
app/workers/system_hook_worker.rb
Normal file
7
app/workers/system_hook_worker.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class SystemHookWorker
|
||||
@queue = :system_hook
|
||||
|
||||
def self.perform(hook_id, data)
|
||||
SystemHook.find(hook_id).execute data
|
||||
end
|
||||
end
|
|
@ -23,7 +23,7 @@ module Gitlab
|
|||
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
||||
|
||||
# Activate observers that should always be running.
|
||||
config.active_record.observers = :mailer_observer, :activity_observer, :project_observer, :key_observer, :issue_observer, :user_observer
|
||||
config.active_record.observers = :mailer_observer, :activity_observer, :project_observer, :key_observer, :issue_observer, :user_observer, :system_hook_observer
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
|
|
|
@ -21,6 +21,8 @@ email:
|
|||
# Like default project limit for user etc
|
||||
app:
|
||||
default_projects_limit: 10
|
||||
# backup_path: "/vol/backups" # default: Rails.root + backups/
|
||||
# backup_keep_time: 604800 # default: 0 (forever) (in seconds)
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -95,11 +95,21 @@ class Settings < Settingslogic
|
|||
end
|
||||
|
||||
def gitolite_admin_uri
|
||||
git['admin_uri'] || 'git@localhost:gitolite-admin'
|
||||
git_host['admin_uri'] || 'git@localhost:gitolite-admin'
|
||||
end
|
||||
|
||||
def default_projects_limit
|
||||
app['default_projects_limit'] || 10
|
||||
end
|
||||
|
||||
def backup_path
|
||||
t = app['backup_path'] || "backups/"
|
||||
t = /^\//.match(t) ? t : File.join(Rails.root + t)
|
||||
t
|
||||
end
|
||||
|
||||
def backup_keep_time
|
||||
app['backup_keep_time'] || 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue