Merge branch 'master' into features/feeds
This commit is contained in:
commit
8d74123d61
56 changed files with 1042 additions and 758 deletions
1
.rbenv-version
Normal file
1
.rbenv-version
Normal file
|
@ -0,0 +1 @@
|
|||
1.9.2-p290
|
|
@ -1,3 +1,10 @@
|
|||
v 1.2.0
|
||||
- new design
|
||||
- user dashboard
|
||||
- markdown support for comments
|
||||
- encoding issues
|
||||
- wall like twitter timeline
|
||||
|
||||
v 1.1.0
|
||||
- project dashboard
|
||||
- wall redesigned
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -37,7 +37,6 @@ end
|
|||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails'
|
||||
gem "shoulda", "~> 3.0.0.beta2"
|
||||
gem 'capybara'
|
||||
gem 'autotest'
|
||||
gem 'autotest-rails'
|
||||
|
@ -51,4 +50,5 @@ end
|
|||
group :test do
|
||||
gem 'turn', :require => false
|
||||
gem 'simplecov', :require => false
|
||||
gem "shoulda", "~> 3.0.0.beta2"
|
||||
end
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.1.0
|
||||
1.2.0
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
//= require jquery.ui.selectmenu
|
||||
//= require jquery.tagify
|
||||
//= require jquery.cookie
|
||||
//= require raphael
|
||||
//= require branch-graph
|
||||
//= require_tree .
|
||||
|
||||
$(function(){
|
||||
|
@ -19,8 +21,20 @@ $(function(){
|
|||
|
||||
$('select#branch').selectmenu({style:'popup', width:200});
|
||||
$('select#tag').selectmenu({style:'popup', width:200});
|
||||
|
||||
$(".account-box").mouseenter(showMenu);
|
||||
$(".account-box").mouseleave(resetMenu);
|
||||
|
||||
});
|
||||
|
||||
function updatePage(data){
|
||||
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
|
||||
}
|
||||
|
||||
function showMenu() {
|
||||
$(this).toggleClass('hover');
|
||||
}
|
||||
|
||||
function resetMenu() {
|
||||
$(this).removeClass("hover");
|
||||
}
|
||||
|
|
|
@ -8,3 +8,34 @@
|
|||
*= require_self
|
||||
*= require_tree .
|
||||
*/
|
||||
|
||||
/** COLORS **/
|
||||
.cgray { color:gray; }
|
||||
.cred { color:#D12F19; }
|
||||
.cgreen { color:#44aa22; }
|
||||
|
||||
/** COMMON STYLES **/
|
||||
.left {
|
||||
float:left;
|
||||
}
|
||||
.right {
|
||||
float:right;
|
||||
}
|
||||
.width-50p{
|
||||
width:50%;
|
||||
}
|
||||
.width-49p{
|
||||
width:49%;
|
||||
}
|
||||
.width-30p{
|
||||
width:30%;
|
||||
}
|
||||
.width-65p{
|
||||
width:65%;
|
||||
}
|
||||
.append-bottom-10 {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.prepend-top-10 {
|
||||
margin-top:10px;
|
||||
}
|
||||
|
|
42
app/assets/stylesheets/commits.css.scss
Normal file
42
app/assets/stylesheets/commits.css.scss
Normal file
|
@ -0,0 +1,42 @@
|
|||
/** Commit diff view **/
|
||||
.diff_file {
|
||||
border:1px solid #CCC;
|
||||
margin-bottom:1em;
|
||||
|
||||
.diff_file_header {
|
||||
padding:5px 5px;
|
||||
border-bottom:1px solid #CCC;
|
||||
background: #eee;
|
||||
}
|
||||
.diff_file_content {
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
background:#fff;
|
||||
color:#333;
|
||||
font-size: 12px;
|
||||
font-family: 'Courier New', 'andale mono','lucida console',monospace;
|
||||
}
|
||||
.diff_file_content_image {
|
||||
background:#eee;
|
||||
text-align:center;
|
||||
img {
|
||||
padding:100px;
|
||||
max-width:300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.diff_file_content{
|
||||
.old_line, .new_line {
|
||||
background:#ECECEC;
|
||||
color:#777;
|
||||
width:30px;
|
||||
float:left;
|
||||
padding: 0px 5px;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
pre.commit_message {
|
||||
white-space: pre-wrap;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
// Place all the styles related to the Dashboard controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -1,3 +1,48 @@
|
|||
// Place all the styles related to the Issues controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
.issue-number {
|
||||
float: left;
|
||||
border-radius: 5px;
|
||||
text-shadow: none;
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
text-align: center;
|
||||
padding: 14px 8px;
|
||||
width: 40px;
|
||||
margin-right: 10px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.issues_filter {
|
||||
margin-top:10px;
|
||||
.left {
|
||||
margin-right:15px;
|
||||
}
|
||||
}
|
||||
|
||||
.top_panel_issues{
|
||||
#issue_search_form {
|
||||
margin:5px 0;
|
||||
input {
|
||||
border:1px solid #D3D3D3;
|
||||
padding: 3px;
|
||||
height: 28px;
|
||||
width: 300px;
|
||||
-webkit-appearance:none;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color:#c2e1ef;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** ISSUES LIST **/
|
||||
.issue .action-links {
|
||||
display:none;
|
||||
a {
|
||||
margin-left:10px;
|
||||
}
|
||||
}
|
||||
.issue:hover .action-links { display:block; }
|
||||
|
||||
|
||||
|
|
44
app/assets/stylesheets/notes.css.scss
Normal file
44
app/assets/stylesheets/notes.css.scss
Normal file
|
@ -0,0 +1,44 @@
|
|||
/** Notes **/
|
||||
|
||||
#notes-list {
|
||||
display:block;
|
||||
list-style:none;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.issue_notes {
|
||||
.note_content {
|
||||
float:left;
|
||||
width:400px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Note textare */
|
||||
#note_note {
|
||||
height:100px;
|
||||
width:97%;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
#new_note {
|
||||
#note_note {
|
||||
height:25px;
|
||||
}
|
||||
.attach_holder {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
#notes-list .note .delete-note { display:none; }
|
||||
#notes-list .note:hover .delete-note { display:block; }
|
||||
|
||||
body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
|
||||
body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
|
||||
body.project-page #notes-list .note img{float: left; margin-right: 10px;}
|
||||
body.project-page #notes-list .note span.note-title{display: block;}
|
||||
body.project-page #notes-list .note span.note-title{margin-bottom: 10px}
|
||||
body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;}
|
||||
body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
// Place all the styles related to the Profile controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -1,29 +1,20 @@
|
|||
// Place all the styles related to the Projects controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
||||
/** MIXINS **/
|
||||
@mixin round-borders-bottom($radius) {
|
||||
border-top: 1px solid #eaeaea;
|
||||
|
||||
-moz-border-radius-bottomright: $radius;
|
||||
-moz-border-radius-bottomleft: $radius;
|
||||
|
||||
border-bottom-right-radius: $radius;
|
||||
border-bottom-left-radius: $radius;
|
||||
|
||||
-webkit-border-bottom-left-radius: $radius;
|
||||
-webkit-border-bottom-right-radius: $radius;
|
||||
}
|
||||
|
||||
@mixin round-borders-top($radius) {
|
||||
border-top: 1px solid #eaeaea;
|
||||
|
||||
-moz-border-radius-topright: $radius;
|
||||
-moz-border-radius-topleft: $radius;
|
||||
|
||||
border-top-right-radius: $radius;
|
||||
border-top-left-radius: $radius;
|
||||
|
||||
-webkit-border-top-left-radius: $radius;
|
||||
-webkit-border-top-right-radius: $radius;
|
||||
}
|
||||
|
@ -35,46 +26,7 @@
|
|||
border-radius: $radius;
|
||||
}
|
||||
|
||||
@mixin hover-color {
|
||||
background: #fff !important;
|
||||
background: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#FFF6BF)) !important;
|
||||
background: -moz-linear-gradient(top,#fff,#FFF6BF) !important;
|
||||
background: transparent 9 !important;
|
||||
}
|
||||
|
||||
.diff_file {
|
||||
border:1px solid #CCC;
|
||||
margin-bottom:1em;
|
||||
|
||||
.diff_file_header {
|
||||
padding:5px 5px;
|
||||
border-bottom:1px solid #CCC;
|
||||
background: #eee;
|
||||
}
|
||||
.diff_file_content {
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
background:#fff;
|
||||
color:#333;
|
||||
font-size: 12px;
|
||||
font-family: 'Courier New', 'andale mono','lucida console',monospace;
|
||||
}
|
||||
.diff_file_content_image {
|
||||
background:#eee;
|
||||
text-align:center;
|
||||
img {
|
||||
padding:100px;
|
||||
max-width:300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#logo {
|
||||
&:hover {
|
||||
background:none;
|
||||
}
|
||||
}
|
||||
|
||||
/** File stat **/
|
||||
.file_stats {
|
||||
margin-bottom:10px;
|
||||
@include round-borders-all(4px);
|
||||
|
@ -99,85 +51,16 @@
|
|||
@include round-borders-all(4px);
|
||||
padding: 4px 0px;
|
||||
}
|
||||
|
||||
table.round-borders {
|
||||
float:left;
|
||||
}
|
||||
|
||||
@mixin panel-color {
|
||||
background: #111 !important;
|
||||
background: -webkit-gradient(linear,left top,left bottom,from(#333),to(#111)) !important;
|
||||
background: -moz-linear-gradient(top,#333,#111) !important;
|
||||
background: transparent 9 !important;
|
||||
}
|
||||
|
||||
#header-panel {
|
||||
@include panel-color;
|
||||
height:40px;
|
||||
position:fixed;
|
||||
z-index:999;
|
||||
top:0px;
|
||||
width:100%;
|
||||
margin-bottom:10px;
|
||||
overflow:hidden;
|
||||
.button{
|
||||
color:#bbb;
|
||||
border:none;
|
||||
margin:0px;
|
||||
height:25px;
|
||||
background:transparent;
|
||||
padding:10px 20px 5px 20px;
|
||||
&:hover{
|
||||
color:white;
|
||||
}
|
||||
|
||||
&.current {
|
||||
border-bottom: 3px solid #EAEAEA !important;
|
||||
padding: 10px 20px 0;
|
||||
color: #eaeaea;
|
||||
}
|
||||
}
|
||||
.search-holder {
|
||||
float:left;
|
||||
width:290px;
|
||||
input {
|
||||
@include round-borders-all(4px);
|
||||
width:290px;
|
||||
border-color:#888;
|
||||
padding:5px;
|
||||
background:#666;
|
||||
color:#222;
|
||||
&:focus {
|
||||
background:#fff;
|
||||
color:#000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#content-container{
|
||||
min-height:250px;
|
||||
background: #fff;
|
||||
@include round-borders-bottom(8px);
|
||||
borders:2px solid #eaeaea;
|
||||
border-top: none;
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.diff_file_content{
|
||||
.old_line, .new_line {
|
||||
background:#ECECEC;
|
||||
color:#777;
|
||||
width:30px;
|
||||
float:left;
|
||||
padding: 0px 5px;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
/** FILE CONTENT VIEW **/
|
||||
.view_file_content{
|
||||
.old_line, .new_line {
|
||||
background:#ECECEC;
|
||||
|
@ -216,10 +99,34 @@ a {
|
|||
}
|
||||
}
|
||||
|
||||
.back_small.button{
|
||||
|
||||
td.code {
|
||||
width: 100%;
|
||||
.highlight {
|
||||
margin-left: 55px;
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
}
|
||||
}
|
||||
.highlight pre {
|
||||
white-space: pre;
|
||||
word-wrap:normal;
|
||||
}
|
||||
|
||||
.highlighttable tr:hover {
|
||||
background:white;
|
||||
}
|
||||
table.highlighttable pre{
|
||||
line-height:16px !important;
|
||||
font-size:12px !important;
|
||||
}
|
||||
|
||||
|
||||
table.highlighttable .linenodiv pre {
|
||||
text-align: right;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
/** PROJECTS **/
|
||||
input.ssh_project_url {
|
||||
padding:5px;
|
||||
margin:0px;
|
||||
|
@ -243,38 +150,7 @@ input.ssh_project_url {
|
|||
clear: both;
|
||||
}
|
||||
|
||||
.top_project_menu {
|
||||
a {
|
||||
border-right: 1px solid #FFFFFF;
|
||||
box-shadow: -1px 0 #DDDDDD inset;
|
||||
color: #666;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
line-height: 20px;
|
||||
padding: 11px 26px 12px 24px;
|
||||
text-shadow: 0 1px 0 #FFFFFF;
|
||||
float:left;
|
||||
|
||||
&.current {
|
||||
background-color: #FFFFFF;
|
||||
color: #222222;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top_bar {
|
||||
margin-top:50px;
|
||||
background-color: #F4F4F4;
|
||||
@include round-borders-top(8px);
|
||||
box-shadow: 0 1px #FFFFFF inset, 0 -1px #DDDDDD inset;
|
||||
height: 43px;
|
||||
overflow: hidden;
|
||||
width:990px;
|
||||
}
|
||||
|
||||
/** FORM INPUTS **/
|
||||
|
||||
.user_new,
|
||||
.new_key,
|
||||
.new_issue,
|
||||
|
@ -296,7 +172,6 @@ input.ssh_project_url {
|
|||
}
|
||||
|
||||
.input_button {
|
||||
//@include round-borders-all(4px);
|
||||
padding:8px;
|
||||
font-size:14px;
|
||||
cursor:pointer;
|
||||
|
@ -307,36 +182,11 @@ input.ssh_project_url {
|
|||
border-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
.top_menu_count {
|
||||
background: none repeat scroll 0 0 white;
|
||||
color: #333;
|
||||
border-color: #4BB8D2;
|
||||
padding: 2px;
|
||||
font-size:10px;
|
||||
border-top:none;
|
||||
text-align:center;
|
||||
float:right;
|
||||
width:25px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#logo {
|
||||
color: #EAEAEA;
|
||||
font-family: monospace;
|
||||
font-size: 26px;
|
||||
padding: 4px;
|
||||
text-decoration: none;
|
||||
text-shadow: #555 1px 1px;
|
||||
}
|
||||
|
||||
/** FLASH **/
|
||||
|
||||
#flash_container {
|
||||
height:40px;
|
||||
position:fixed;
|
||||
z-index:1009;
|
||||
z-index:1209;
|
||||
top:0px;
|
||||
width:100%;
|
||||
margin-bottom:10px;
|
||||
|
@ -354,7 +204,6 @@ input.ssh_project_url {
|
|||
}
|
||||
|
||||
/** Buttons **/
|
||||
|
||||
.lbutton,
|
||||
.lite_button {
|
||||
display:block;
|
||||
|
@ -386,89 +235,87 @@ input.ssh_project_url {
|
|||
}
|
||||
}
|
||||
|
||||
/** Notes **/
|
||||
|
||||
#notes-list {
|
||||
display:block;
|
||||
list-style:none;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.notes_count {
|
||||
background: none repeat scroll 0 0 #FFF6BF;
|
||||
border-color: #FFD324;
|
||||
color: #514721;
|
||||
border: 2px solid #DDDDDD;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 3px;
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.issue_notes {
|
||||
.note_content {
|
||||
float:left;
|
||||
width:400px;
|
||||
}
|
||||
}
|
||||
|
||||
#user_projects_limit{
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.project_thumb {
|
||||
margin:20px 0;
|
||||
width: 250px;
|
||||
float:left;
|
||||
padding:20px;
|
||||
text-align:center;
|
||||
p, h4 {
|
||||
text-align:left;
|
||||
}
|
||||
.lbutton {
|
||||
float:left;
|
||||
}
|
||||
}
|
||||
|
||||
.handle:hover{
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.handle{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* Note textare */
|
||||
#note_note {
|
||||
height:100px;
|
||||
width:97%;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
#new_note {
|
||||
#note_note {
|
||||
height:25px;
|
||||
}
|
||||
.attach_holder {
|
||||
display:none;
|
||||
.project-refs-form {
|
||||
span {
|
||||
background: none !important;
|
||||
position:static !important;
|
||||
width:auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.field_with_errors {
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
textarea
|
||||
{
|
||||
background: none repeat scroll 0 0 #FFBBBB
|
||||
.project-refs-select {
|
||||
width:200px;
|
||||
}
|
||||
|
||||
.filter .left { margin-right:15px; }
|
||||
|
||||
body.project-page table .commit {
|
||||
a.tree-commit-link {
|
||||
color:gray;
|
||||
&:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** NEW PROJECT **/
|
||||
.new-project-hodler {
|
||||
.icon span { background-position: -31px -70px; }
|
||||
td { border-bottom: 1px solid #DEE2E3; }
|
||||
}
|
||||
|
||||
/** Feed entry **/
|
||||
.commit,
|
||||
.snippet,
|
||||
.message {
|
||||
.title {
|
||||
color:#666;
|
||||
a { color:#666 !important; }
|
||||
p { margin-top:0px; }
|
||||
}
|
||||
.author { color: #999 }
|
||||
}
|
||||
|
||||
/** JQuery UI **/
|
||||
.ui-autocomplete { @include round-borders-all(5px); }
|
||||
.ui-menu-item { cursor: pointer }
|
||||
.ui-selectmenu{
|
||||
@include round-borders-all(4px);
|
||||
margin-right:10px;
|
||||
font-size:1.5em;
|
||||
height:auto;
|
||||
font-weight:bold;
|
||||
.ui-selectmenu-status {
|
||||
padding:3px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/** Snippets **/
|
||||
.new_snippet textarea,
|
||||
.edit_snippet textarea {
|
||||
height:300px;
|
||||
padding: 8px;
|
||||
width: 95%;
|
||||
}
|
||||
.snippet .action-links {
|
||||
display:none;
|
||||
a {
|
||||
margin-left:10px;
|
||||
}
|
||||
}
|
||||
.snippet:hover .action-links { display:block; }
|
||||
|
||||
/** ISSUES TAGS **/
|
||||
.tag {
|
||||
@include round-borders-all(4px);
|
||||
padding:2px 4px;
|
||||
|
@ -497,187 +344,38 @@ input.ssh_project_url {
|
|||
background: #2c5c66;
|
||||
color:white;
|
||||
}
|
||||
}
|
||||
|
||||
#issues-table .issue {
|
||||
&.critical {
|
||||
td {
|
||||
//background: #D12F19;
|
||||
//color:#fff;
|
||||
}
|
||||
&.note {
|
||||
background: #2c5c66;
|
||||
color:white;
|
||||
}
|
||||
&.issue {
|
||||
background: #D12F19;
|
||||
color:white;
|
||||
}
|
||||
&.commit {
|
||||
background: #44aacc;
|
||||
color:white;
|
||||
}
|
||||
}
|
||||
|
||||
.top_panel_issues{
|
||||
#issue_search_form {
|
||||
margin:5px 0;
|
||||
input {
|
||||
border:1px solid #D3D3D3;
|
||||
padding: 3px;
|
||||
height: 28px;
|
||||
width: 300px;
|
||||
-webkit-appearance:none;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color:#c2e1ef;
|
||||
}
|
||||
}
|
||||
}
|
||||
#holder {
|
||||
border: solid 1px #999;
|
||||
cursor: move;
|
||||
height: 70%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left {
|
||||
float:left;
|
||||
}
|
||||
.right {
|
||||
float:right;
|
||||
}
|
||||
/* Project Dashboard Page */
|
||||
html, body { height: 100%; }
|
||||
|
||||
.width-50p{
|
||||
width:50%;
|
||||
}
|
||||
.width-49p{
|
||||
width:49%;
|
||||
}
|
||||
.width-30p{
|
||||
width:30%;
|
||||
}
|
||||
.width-65p{
|
||||
width:65%;
|
||||
}
|
||||
pre.commit_message {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#container {
|
||||
min-height:100%;
|
||||
}
|
||||
.ui-selectmenu{
|
||||
@include round-borders-all(4px);
|
||||
margin-right:10px;
|
||||
font-size:1.5em;
|
||||
height:auto;
|
||||
font-weight:bold;
|
||||
.ui-selectmenu-status {
|
||||
padding:3px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
td.code {
|
||||
width: 100%;
|
||||
.highlight {
|
||||
margin-left: 55px;
|
||||
overflow:auto;
|
||||
overflow-y:hidden;
|
||||
}
|
||||
}
|
||||
.highlight pre {
|
||||
white-space: pre;
|
||||
word-wrap:normal;
|
||||
}
|
||||
|
||||
.highlighttable tr:hover {
|
||||
background:white;
|
||||
}
|
||||
table.highlighttable pre{
|
||||
line-height:16px !important;
|
||||
font-size:12px !important;
|
||||
}
|
||||
|
||||
.project-refs-form {
|
||||
span {
|
||||
background: none !important;
|
||||
position:static !important;
|
||||
width:auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.project-refs-select {
|
||||
width:200px;
|
||||
}
|
||||
|
||||
.issues_filter {
|
||||
margin-top:10px;
|
||||
.left {
|
||||
margin-right:15px;
|
||||
}
|
||||
}
|
||||
.filter .left { margin-right:15px; }
|
||||
|
||||
|
||||
.cgray { color:gray; }
|
||||
.cred { color:#D12F19; }
|
||||
.cgreen { color:#44aa22; }
|
||||
|
||||
body.project-page table .commit {
|
||||
a.tree-commit-link {
|
||||
color:gray;
|
||||
&:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#notes-list .note .delete-note { display:none; }
|
||||
#notes-list .note:hover .delete-note { display:block; }
|
||||
|
||||
#issues-table-holder .issue .action-links {
|
||||
display:none;
|
||||
a {
|
||||
margin-left:10px;
|
||||
}
|
||||
}
|
||||
|
||||
.issue-number {
|
||||
float: left;
|
||||
border-radius: 5px;
|
||||
text-shadow: none;
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
text-align: center;
|
||||
padding: 14px 8px;
|
||||
width: 40px;
|
||||
margin-right: 10px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
#issues-table-holder .issue:hover .action-links { display:block; }
|
||||
|
||||
body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
|
||||
body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
|
||||
body.project-page #notes-list .note img{float: left; margin-right: 10px;}
|
||||
body.project-page #notes-list .note span.note-title{display: block;}
|
||||
body.project-page #notes-list .note span.note-title{margin-bottom: 10px}
|
||||
body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;}
|
||||
body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;}
|
||||
|
||||
|
||||
/** NEW PROJECT **/
|
||||
.new-project-hodler {
|
||||
.icon span {
|
||||
background-position: -31px -70px;
|
||||
}
|
||||
td {
|
||||
border-bottom: 1px solid #DEE2E3;
|
||||
}
|
||||
}
|
||||
|
||||
//.message .note-title p { margin-bottom:0px; }
|
||||
|
||||
.commit,
|
||||
.message {
|
||||
.title {
|
||||
color:#666;
|
||||
a {
|
||||
color:#666 !important;
|
||||
}
|
||||
p {
|
||||
margin-top:0px;
|
||||
}
|
||||
}
|
||||
|
||||
.author {
|
||||
color: #999
|
||||
}
|
||||
}
|
||||
body.dashboard.project-page .news-feed h2{float: left;}
|
||||
body.dashboard.project-page .news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;}
|
||||
body.dashboard.project-page .news-feed .project-updates .data{ padding: 0}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update:last-child{border-bottom: 0}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update img{float: left; margin-right: 10px;}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
|
||||
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
|
||||
/* eo Dashboard Page */
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
// Place all the styles related to the Snippets controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
149
app/assets/stylesheets/style.scss
Executable file → Normal file
149
app/assets/stylesheets/style.scss
Executable file → Normal file
|
@ -101,7 +101,7 @@ input.text{border: 1px solid #ccc; border-radius: 4px; display: block; padding:
|
|||
/* eo Forms */
|
||||
|
||||
/* Tables */
|
||||
table {width:100%; border: 1px solid #DEE2E3}
|
||||
table {width:100%; border: 1px solid #DEE2E3; margin-bottom: 20px}
|
||||
table thead{
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
|
@ -144,7 +144,8 @@ table tr:hover, .listed_items tr.odd:hover{background-color:#FFFFCF}
|
|||
background-image: -o-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
|
||||
}
|
||||
|
||||
.button{
|
||||
a.button, input.button {
|
||||
font-weight: bold;
|
||||
padding: 10px 20px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
@ -159,6 +160,8 @@ table tr:hover, .listed_items tr.odd:hover{background-color:#FFFFCF}
|
|||
background-image: -o-linear-gradient(#dbf5f6 79.4%, #c5eef0);
|
||||
}
|
||||
|
||||
input.button{margin-bottom: 1.5em}
|
||||
|
||||
.button:hover {color: rgba(0,0,0,.8)}
|
||||
|
||||
.button.green {margin-right: 0; }
|
||||
|
@ -301,14 +304,30 @@ body.login-page{background-color: #f1f1f1; padding-top: 10%}
|
|||
|
||||
/* eo Icons*/
|
||||
|
||||
/* Errors */
|
||||
#error_explanation{background: #ffe5eb; padding: 20px; margin-bottom: 20px; border-radius: 5px}
|
||||
#error_explanation h2{margin: 0; margin-bottom: 20px; color: red}
|
||||
#error_explanation ul li{margin-bottom: 10px}
|
||||
#error_explanation ul li:last-child{margin-bottom: 0}
|
||||
.field_with_errors {
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
textarea
|
||||
{
|
||||
border: 1px solid #FFBBBB;
|
||||
background: #fff4f6;
|
||||
}
|
||||
}
|
||||
/* eo Errors */
|
||||
|
||||
/* General */
|
||||
#container{background-color: white; overflow: hidden;}
|
||||
#container{background-color: white; overflow: hidden; }
|
||||
body.collapsed #container{margin: auto; width: 980px; border: 1px solid rgba(0,0,0,.22); border-top: 0; box-shadow: 0 0 0px 4px rgba(0,0,0,.04)}
|
||||
|
||||
|
||||
|
||||
/* Header */
|
||||
header{background: #474D57 url('bg-header.png') repeat-x bottom; z-index: 10000; height: 44px; padding: 10px 2% 6px 2%}
|
||||
header{background: #474D57 url('bg-header.png') repeat-x bottom; z-index: 10000; height: 44px; padding: 10px 2% 6px 2%; position: relative}
|
||||
header a{color: white; text-shadow: 0 -1px 0 black}
|
||||
header a:hover{color: #f1f1f1}
|
||||
header h1{
|
||||
|
@ -370,40 +389,14 @@ header nav a.admin{
|
|||
}
|
||||
|
||||
|
||||
header .search{ display: inline-block; float: right; margin-right: 10px}
|
||||
header .search{ display: inline-block; float: right; margin-right: 46px}
|
||||
|
||||
header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;}
|
||||
|
||||
header nav a.dashboard span{background: url('images.png') no-repeat -161px 0;}
|
||||
header nav a.admin span{background: url('images.png') no-repeat -184px 0;}
|
||||
header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 7px}
|
||||
/*
|
||||
|
||||
header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 14px;}
|
||||
|
||||
header nav a.dashboard.current span{ background-position: -163px -22px; }
|
||||
header nav a.admin.current span{ background-position: -186px -22px;}
|
||||
header nav a.project.current span{ background-position: -211px -23px;}
|
||||
|
||||
header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 15px}
|
||||
|
||||
|
||||
header nav a span.current{top: 18px}
|
||||
|
||||
|
||||
header nav {margin-left: 180px; display: inline-block; float: left;}
|
||||
header nav a{float: left; background: #31363e; padding: 16px 20px 20px 34px; margin-right: 10px;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-moz-border-radius-topleft: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header nav a.current{background: white; color: #333; text-shadow: none;}
|
||||
*/
|
||||
|
||||
header .login-top{float: right; width: 180px;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 62, color-stop(0.032, #464c56), to(#363c45));
|
||||
|
@ -426,10 +419,11 @@ header{margin-bottom: 0; clear: both; }
|
|||
.page-title a.grey-button{float: right;}
|
||||
.right{float: right;}
|
||||
|
||||
|
||||
/* Account box */
|
||||
header .account-box{position: relative;z-index: 10000; top: -3px; width: 38px; height: 38px; font-size: 11px; float: right; display: block; cursor: pointer; }
|
||||
header .account-box img{ border-radius: 4px; width: 38px; height: 38px; display: block; box-shadow: 0 1px 2px black}
|
||||
header .account-box:after{
|
||||
header .account-box{position: absolute; right: 0; top: 8px; z-index: 10000; width: 128px; font-size: 11px; float: right; display: block; cursor: pointer;}
|
||||
header .account-box img{ border-radius: 4px; right: 20px; position: absolute; width: 38px; height: 38px; display: block; box-shadow: 0 1px 2px black}
|
||||
header .account-box img:after{
|
||||
content: " ";
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
@ -449,11 +443,38 @@ float: right;
|
|||
background-origin: border-box;
|
||||
}
|
||||
|
||||
.account-box:hover > .account-links, .account-box:hover > .arrow-up{display: block;}
|
||||
header .account-links{background: white; display: none; border-radius: 5px; width: 100px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); }
|
||||
header .account-links a{color: #666; padding: 6px 10px; display: block; text-shadow: none; border-bottom: 1px solid #eee}
|
||||
header .account-links a:hover{background-color: #f1f1f1; text-shadow: none; color: #333}
|
||||
.account-box.hover{height: 138px;}
|
||||
|
||||
.account-box:hover > .account-links{display: block;}
|
||||
header .account-links{background: white; display: none; border-radius: 5px; width: 100px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); position:relative;}
|
||||
header .account-links:before {
|
||||
content: ".";
|
||||
width:0;
|
||||
height:0;
|
||||
position:absolute;
|
||||
border:5px solid transparent;
|
||||
border-color:rgba(255,255,255,0);
|
||||
border-bottom-color:#fafafa;
|
||||
text-indent:-9999px;
|
||||
top:-10px;
|
||||
line-height:0;
|
||||
right:10px;
|
||||
z-index:10;
|
||||
}
|
||||
|
||||
|
||||
/* Inspired by http://maxvoltar.com/temp/nowplaying/ */
|
||||
header .account-links{background: white; display: none; z-index: 100000; border-radius: 5px; width: 100px; position: absolute; right: 20px; top: 46px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); }
|
||||
header .account-links a{color: #666; padding: 6px 10px; display: block; text-shadow: none; border-bottom: 1px solid #eee}
|
||||
header .account-links a:hover{
|
||||
background: #3aacec;
|
||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#39acec), to(#279ada), color-stop(.05, #4cbefe));
|
||||
background: -moz-linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
|
||||
background: linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
|
||||
color: #fff;
|
||||
text-shadow: #1488c8 0 -1px 0;
|
||||
}
|
||||
.account-box.hover .arrow-up{top: 41px; right: 6px; position: absolute}
|
||||
header .account-links a:first-child{
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
|
@ -473,18 +494,15 @@ header .account-links a:last-child{
|
|||
border-bottom: 0;
|
||||
}
|
||||
|
||||
header a.arrow-up{
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
float: right;
|
||||
margin-right: 26px;
|
||||
margin-bottom: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
|
||||
border-bottom: 5px solid white;
|
||||
#no_ssh_key_defined {
|
||||
border:1px solid #ee8801;
|
||||
margin:20px;
|
||||
padding:20px;
|
||||
background:#ffe3f0;
|
||||
h2{margin:0;}
|
||||
p {margin:10px 0 0;}
|
||||
}
|
||||
|
||||
/* eo Account Box */
|
||||
input.search-input{float: left; text-shadow: none; width: 116px; background-image: url('icon-search.png') ; background-repeat: no-repeat; background-position: 10px; border-radius: 100px; border: 1px solid rgba(0,0,0,.7); box-shadow: 0 1px 0 rgba(255,255,255,.2), 0 2px 2px rgba(0,0,0,.4) inset ; background-color: #D2D5DA; background-color: rgba(255,255,255,.5); padding: 5px; padding-left: 26px; margin-top: 4px; margin-right: 10px }
|
||||
input.search-input:focus{ background-color: white; width: 216px;}
|
||||
|
@ -506,9 +524,9 @@ body.dashboard-page header{margin-bottom: 0}
|
|||
body.dashboard-page .news-feed{padding-left: 1em; margin-right: 450px; margin-left: 1%}
|
||||
body.dashboard-page .dashboard-content{ position: relative; float: left; width: 100%; height: 100%; }
|
||||
body.dashboard-page .news-feed h2{float: left;}
|
||||
body.dashboard-page aside{ width: 420px; float: right; right: 0; height: 100%; bottom: 0; position: absolute; background-color: #f7f7f7; border-left: 1px solid #ccc }
|
||||
body.dashboard-page aside{ min-height: 700px; width: 420px; float: right; background-color: #f7f7f7; border-left: 1px solid #ccc }
|
||||
body.dashboard-page aside h4{margin: 0; border-bottom: 1px solid #ccc; padding: 10px 10px; font-size: 11px; font-weight: bold; text-transform: uppercase;}
|
||||
body.dashboard-page aside h4 a.button-small{float: right; text-transform: none; border-radius: 4px; margin-right: 4%; margin-top: -4px; display: block;}
|
||||
body.dashboard-page aside h4 a.button-small{float: right; text-transform: none; border-radius: 4px; margin-right: 2%; margin-top: -4px; display: block;}
|
||||
body.dashboard-page aside .project-list {list-style: none; margin: 0; padding: 0;}
|
||||
body.dashboard-page aside .project-list li a {background: white; color: #{$blue_link}; display: block; border-bottom: 1px solid #eee; padding: 14px 6% 14px 14px;}
|
||||
body.dashboard-page aside .project-list li a:hover {background: #f1f1f1}
|
||||
|
@ -548,8 +566,16 @@ body.project-page h2.icon .project-name i.arrow{float: right;
|
|||
body.project-page h2.icon span{ background-position: -78px -68px; }
|
||||
body.project-page .project-container{ position: relative; float: left; width: 100%; height: 100%; }
|
||||
body.project-page .page-title{margin-bottom: 0}
|
||||
body.project-page .project-sidebar {width: 220px; left: 0; top: 0; height: 100%; bottom: 0; position: absolute; background-color: #f7f7f7; border-left: 1px solid #ccc; float: left; display: inline-block; background: #f7f7f7; padding: 20px 0 20px 2%; margin: 0; }
|
||||
body.project-page .project-sidebar input.text.git-url{ font-size: 12px; border-radius: 5px; color: #666; box-shadow: 0 1px 2px rgba(0,0,0,.2) inset; padding: 8px 14px 8px 30px; margin-bottom: 20px; background: white url('images.png') no-repeat 8px -40px;}
|
||||
body.project-page .project-sidebar {width: 220px; left: 0; top: 0; height: 100%; bottom: 0; position: absolute; background-color: #f7f7f7; float: left; display: inline-block; background: #f7f7f7; padding: 20px 0 20px 2%; margin: 0; }
|
||||
|
||||
body.project-page input.text.git-url,
|
||||
body.projects-page input.text.git-url { font-size: 12px; border-radius: 5px; color: #666; box-shadow: 0 1px 2px rgba(0,0,0,.2) inset; padding: 8px 14px 8px 30px; margin-bottom: 20px; background: white url('images.png') no-repeat 8px -40px;}
|
||||
body.projects-page input.text.git-url {margin:10px 0 0 }
|
||||
.git_url_wrapper { margin-right:50px }
|
||||
|
||||
.projects_selector:hover > .project-box{ -moz-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); -webkit-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); box-shadow:0px 0px 10px rgba(0, 0, 0, .1); }
|
||||
|
||||
|
||||
body.project-page .project-sidebar aside{width: 219px}
|
||||
body.project-page .project-sidebar aside a{display: block; position: relative; background: white; padding: 15px 10px; border-bottom: 1px solid #eee}
|
||||
body.project-page .project-sidebar aside a:first-child{
|
||||
|
@ -565,13 +591,18 @@ body.project-page .project-sidebar aside a:first-child{
|
|||
body.project-page .project-sidebar aside a:hover{background-color: #eee;}
|
||||
body.project-page .project-sidebar aside a span.number{float: right; border-radius: 5px; text-shadow: none; background: rgba(0,0,0,.12); text-align: center; padding: 5px 8px; position: absolute; top: 10px; right: 10px}
|
||||
body.project-page .project-sidebar aside a.current{background-color: #79c3e0; color: white; text-shadow: none; border-color: transparent}
|
||||
body.project-page .project-content{ padding: 20px; display: block; margin-left: 250px }
|
||||
body.project-page .project-content{ padding: 20px; display: block; margin-left: 250px; min-height: 400px}
|
||||
body.project-page .project-content h2{ margin-top: 6px}
|
||||
body.project-page .project-content .button.right{margin-left: 20px}
|
||||
body.project-page table .commit a{color: #{$blue_link}}
|
||||
body.project-page table th, body.project-page table td{ border-bottom: 1px solid #DEE2E3;}
|
||||
body.project-page .fixed{position: fixed; }
|
||||
|
||||
/* New project Page */
|
||||
.new-project-page .container{width: 600px; background-color: rgba(0,0,0,.02); margin: auto; border: 1px solid #eee; padding: 0 20px; margin: 30px auto 60px auto; border-radius: 5px}
|
||||
.new-project-page .container table{background: white}
|
||||
/* eo New Project Page */
|
||||
|
||||
/* Commit Page */
|
||||
body.project-page.commits-page .commit-info{float: right;}
|
||||
body.project-page.commits-page .commit-info data{
|
||||
|
@ -670,3 +701,13 @@ body.projects-page .browse-code{margin-right: 10px}
|
|||
p, h2, h3 { orphans: 3; widows: 3; }
|
||||
h2, h3 { page-break-after: avoid; }
|
||||
}
|
||||
|
||||
/**
|
||||
* author:DZ
|
||||
* date: Nov 09
|
||||
* fix different fonts for firefox & webkit
|
||||
*/
|
||||
body, button, input, select, textarea {
|
||||
font-family: "Helvetica", sans-serif;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
before_filter :authenticate_user!
|
||||
before_filter :view_style
|
||||
|
||||
protect_from_forgery
|
||||
|
||||
helper_method :abilities, :can?
|
||||
|
||||
rescue_from Gitosis::AccessDenied do |exception|
|
||||
|
@ -64,7 +61,7 @@ class ApplicationController < ActionController::Base
|
|||
else
|
||||
@branch = params[:branch].blank? ? nil : params[:branch]
|
||||
@tag = params[:tag].blank? ? nil : params[:tag]
|
||||
@ref = @branch || @tag || "master"
|
||||
@ref = @branch || @tag || Repository.default_ref
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -76,20 +73,6 @@ class ApplicationController < ActionController::Base
|
|||
redirect_to @project unless @project.repo_exists?
|
||||
end
|
||||
|
||||
def view_style
|
||||
if params[:view_style] == "collapsed"
|
||||
cookies[:view_style] = "collapsed"
|
||||
elsif params[:view_style] == "fluid"
|
||||
cookies[:view_style] = ""
|
||||
end
|
||||
|
||||
@view_mode = if cookies[:view_style] == "collapsed"
|
||||
:fixed
|
||||
else
|
||||
:fluid
|
||||
end
|
||||
end
|
||||
|
||||
def respond_with_notes
|
||||
if params[:last_id] && params[:first_id]
|
||||
@notes = @notes.where("id >= ?", params[:first_id])
|
||||
|
|
|
@ -8,18 +8,18 @@ class CommitsController < ApplicationController
|
|||
before_filter :add_project_abilities
|
||||
before_filter :authorize_read_project!
|
||||
before_filter :require_non_empty_project
|
||||
before_filter :load_refs, :only => :index # load @branch, @tag & @ref
|
||||
|
||||
|
||||
def index
|
||||
load_refs # load @branch, @tag & @ref
|
||||
|
||||
@repo = project.repo
|
||||
limit, offset = (params[:limit] || 20), (params[:offset] || 0)
|
||||
|
||||
if params[:path]
|
||||
@commits = @repo.log(@ref, params[:path], :max_count => limit, :skip => offset)
|
||||
else
|
||||
@commits = @repo.commits(@ref, limit, offset)
|
||||
end
|
||||
@commits = if params[:path]
|
||||
@repo.log(@ref, params[:path], :max_count => limit, :skip => offset)
|
||||
else
|
||||
@repo.commits(@ref, limit, offset)
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
|
@ -30,8 +30,8 @@ class CommitsController < ApplicationController
|
|||
|
||||
def show
|
||||
@commit = project.repo.commits(params[:id]).first
|
||||
@notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit").order("created_at DESC").limit(20)
|
||||
@note = @project.notes.new(:noteable_id => @commit.id, :noteable_type => "Commit")
|
||||
@notes = project.commit_notes(@commit).fresh.limit(20)
|
||||
@note = @project.build_commit_note(@commit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require File.join(Rails.root, 'lib', 'graph_commit')
|
||||
|
||||
class ProjectsController < ApplicationController
|
||||
before_filter :project, :except => [:index, :new, :create]
|
||||
layout :determine_layout
|
||||
|
@ -6,8 +8,8 @@ class ProjectsController < ApplicationController
|
|||
before_filter :add_project_abilities
|
||||
before_filter :authorize_read_project!, :except => [:index, :new, :create]
|
||||
before_filter :authorize_admin_project!, :only => [:edit, :update, :destroy]
|
||||
|
||||
before_filter :require_non_empty_project, :only => [:blob, :tree]
|
||||
before_filter :load_refs, :only => :tree # load @branch, @tag & @ref
|
||||
|
||||
def index
|
||||
source = current_user.projects
|
||||
|
@ -64,21 +66,8 @@ class ProjectsController < ApplicationController
|
|||
|
||||
def show
|
||||
return render "projects/empty" unless @project.repo_exists?
|
||||
@date = case params[:view]
|
||||
when "week" then Date.today - 7.days
|
||||
when "day" then Date.today
|
||||
else nil
|
||||
end
|
||||
|
||||
if @date
|
||||
@date = @date.at_beginning_of_day
|
||||
|
||||
@commits = @project.commits_since(@date)
|
||||
@messages = project.notes.since(@date).order("created_at DESC")
|
||||
else
|
||||
@commits = @project.fresh_commits
|
||||
@messages = project.notes.fresh.limit(10)
|
||||
end
|
||||
limit = (params[:limit] || 40).to_i
|
||||
@activities = @project.updates(limit)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -101,15 +90,13 @@ class ProjectsController < ApplicationController
|
|||
#
|
||||
|
||||
def tree
|
||||
load_refs # load @branch, @tag & @ref
|
||||
|
||||
@repo = project.repo
|
||||
|
||||
if params[:commit_id]
|
||||
@commit = @repo.commits(params[:commit_id]).first
|
||||
else
|
||||
@commit = @repo.commits(@ref || "master").first
|
||||
end
|
||||
@commit = if params[:commit_id]
|
||||
@repo.commits(params[:commit_id]).first
|
||||
else
|
||||
@repo.commits(@ref).first
|
||||
end
|
||||
|
||||
@tree = @commit.tree
|
||||
@tree = @tree / params[:path] if params[:path]
|
||||
|
@ -127,6 +114,34 @@ class ProjectsController < ApplicationController
|
|||
return render_404
|
||||
end
|
||||
|
||||
def graph
|
||||
@repo = project.repo
|
||||
commits = Grit::Commit.find_all(@repo, nil, {:max_count => 650})
|
||||
ref_cache = {}
|
||||
commits.collect! do |commit|
|
||||
add_refs(commit, ref_cache)
|
||||
GraphCommit.new(commit)
|
||||
end
|
||||
|
||||
days = GraphCommit.index_commits(commits)
|
||||
@days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
|
||||
@commits_json = commits.collect do |c|
|
||||
h = {}
|
||||
h[:parents] = c.parents.collect do |p|
|
||||
[p.id,0,0]
|
||||
end
|
||||
h[:author] = c.author.name.force_encoding("UTF-8")
|
||||
h[:time] = c.time
|
||||
h[:space] = c.space
|
||||
h[:refs] = c.refs.collect{|r|r.name}.join(" ") unless c.refs.nil?
|
||||
h[:id] = c.sha
|
||||
h[:date] = c.date
|
||||
h[:message] = c.message.force_encoding("UTF-8")
|
||||
h[:login] = c.author.email
|
||||
h
|
||||
end.to_json
|
||||
end
|
||||
|
||||
def blob
|
||||
@repo = project.repo
|
||||
@commit = project.commit(params[:commit_id])
|
||||
|
@ -151,6 +166,17 @@ class ProjectsController < ApplicationController
|
|||
|
||||
protected
|
||||
|
||||
def add_refs(commit, ref_cache)
|
||||
if ref_cache.empty?
|
||||
@repo.refs.each do |ref|
|
||||
ref_cache[ref.commit.id] ||= []
|
||||
ref_cache[ref.commit.id] << ref
|
||||
end
|
||||
end
|
||||
commit.refs = ref_cache[commit.id] if ref_cache.include? commit.id
|
||||
commit.refs ||= []
|
||||
end
|
||||
|
||||
def project
|
||||
@project ||= Project.find_by_code(params[:id])
|
||||
end
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
require 'digest/md5'
|
||||
module ApplicationHelper
|
||||
|
||||
def gravatar_icon(user_email)
|
||||
"http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon"
|
||||
gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com"
|
||||
"#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon"
|
||||
end
|
||||
|
||||
def fixed_mode?
|
||||
@view_mode == :fixed
|
||||
true
|
||||
end
|
||||
|
||||
def body_class(default_class = nil)
|
||||
|
@ -13,7 +15,7 @@ module ApplicationHelper
|
|||
default_class :
|
||||
content_for(:body_class)
|
||||
|
||||
[main, cookies[:view_style]].join(" ")
|
||||
[main, "collapsed"].join(" ")
|
||||
end
|
||||
|
||||
def commit_name(project, commit)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module DashboardHelper
|
||||
def dashboard_feed_path(project, object)
|
||||
case object.class.name.to_s
|
||||
when "Issue" then project_issues_path(project, project.issues.find(object.id))
|
||||
when "Issue" then project_issue_path(project, project.issues.find(object.id))
|
||||
when "Grit::Commit" then project_commit_path(project, project.repo.commits(object.id).first)
|
||||
when "Note"
|
||||
then
|
||||
|
@ -19,12 +19,15 @@ module DashboardHelper
|
|||
end
|
||||
|
||||
def dashboard_feed_title(object)
|
||||
title = case object.class.name.to_s
|
||||
klass = object.class.to_s.split("::").last
|
||||
|
||||
title = case klass
|
||||
when "Note" then markdown(object.note)
|
||||
when "Issue" then object.title
|
||||
when "Grit::Commit" then object.safe_message
|
||||
when "Commit" then object.safe_message
|
||||
else return "Project Wall"
|
||||
end
|
||||
"[#{object.class.name}] #{truncate(sanitize(title, :tags => []), :length => 60)} "
|
||||
|
||||
"[#{klass}] #{truncate(sanitize(title, :tags => []), :length => 60)} "
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
module IssuesHelper
|
||||
def sort_class
|
||||
if can?(current_user, :admin_issue, @project) && (!params[:f] || params[:f] == "0")
|
||||
"handle"
|
||||
end
|
||||
end
|
||||
def sort_class
|
||||
if can?(current_user, :admin_issue, @project) && (!params[:f] || params[:f] == "0")
|
||||
"handle"
|
||||
end
|
||||
end
|
||||
|
||||
def project_issues_filter_path project, params = {}
|
||||
params[:f] ||= cookies['issue_filter']
|
||||
project_issues_path project, params
|
||||
end
|
||||
def project_issues_filter_path project, params = {}
|
||||
params[:f] ||= cookies['issue_filter']
|
||||
project_issues_path project, params
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
module TagsHelper
|
||||
def tag_path tag
|
||||
"/tags/#{tag}"
|
||||
end
|
||||
def tag_path tag
|
||||
"/tags/#{tag}"
|
||||
end
|
||||
|
||||
def tag_list project
|
||||
html = ''
|
||||
project.tag_list.each do |tag|
|
||||
html += link_to tag, tag_path(tag)
|
||||
end
|
||||
|
||||
html.html_safe
|
||||
end
|
||||
def tag_list project
|
||||
html = ''
|
||||
project.tag_list.each do |tag|
|
||||
html += link_to tag, tag_path(tag)
|
||||
end
|
||||
|
||||
html.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,5 +54,6 @@ end
|
|||
# updated_at :datetime
|
||||
# closed :boolean default(FALSE), not null
|
||||
# position :integer default(0)
|
||||
# critical :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ end
|
|||
# Table name: notes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# note :string(255)
|
||||
# note :text
|
||||
# noteable_id :string(255)
|
||||
# noteable_type :string(255)
|
||||
# author_id :integer
|
||||
|
|
|
@ -46,6 +46,25 @@ class Project < ActiveRecord::Base
|
|||
|
||||
scope :public_only, where(:private_flag => false)
|
||||
|
||||
def repository
|
||||
@repository ||= Repository.new(self)
|
||||
end
|
||||
|
||||
delegate :repo,
|
||||
:url_to_repo,
|
||||
:path_to_repo,
|
||||
:update_gitosis_project,
|
||||
:destroy_gitosis_project,
|
||||
:tags,
|
||||
:repo_exists?,
|
||||
:commit,
|
||||
:commits,
|
||||
:tree,
|
||||
:heads,
|
||||
:commits_since,
|
||||
:fresh_commits,
|
||||
:to => :repository, :prefix => nil
|
||||
|
||||
def to_param
|
||||
code
|
||||
end
|
||||
|
@ -59,16 +78,12 @@ class Project < ActiveRecord::Base
|
|||
notes.where(:noteable_type => ["", nil])
|
||||
end
|
||||
|
||||
def update_gitosis_project
|
||||
Gitosis.new.configure do |c|
|
||||
c.update_project(path, gitosis_writers)
|
||||
end
|
||||
def build_commit_note(commit)
|
||||
notes.new(:noteable_id => commit.id, :noteable_type => "Commit")
|
||||
end
|
||||
|
||||
def destroy_gitosis_project
|
||||
Gitosis.new.configure do |c|
|
||||
c.destroy_project(self)
|
||||
end
|
||||
def commit_notes(commit)
|
||||
notes.where(:noteable_id => commit.id, :noteable_type => "Commit")
|
||||
end
|
||||
|
||||
def add_access(user, *access)
|
||||
|
@ -106,26 +121,6 @@ class Project < ActiveRecord::Base
|
|||
private_flag
|
||||
end
|
||||
|
||||
def url_to_repo
|
||||
"#{GITOSIS["git_user"]}@#{GITOSIS["host"]}:#{path}.git"
|
||||
end
|
||||
|
||||
def path_to_repo
|
||||
GITOSIS["base_path"] + path + ".git"
|
||||
end
|
||||
|
||||
def repo
|
||||
@repo ||= Grit::Repo.new(path_to_repo)
|
||||
end
|
||||
|
||||
def tags
|
||||
repo.tags.map(&:name).sort.reverse
|
||||
end
|
||||
|
||||
def repo_exists?
|
||||
repo rescue false
|
||||
end
|
||||
|
||||
def last_activity
|
||||
updates(1).first
|
||||
rescue
|
||||
|
@ -146,48 +141,6 @@ class Project < ActiveRecord::Base
|
|||
end[0...n]
|
||||
end
|
||||
|
||||
def commit(commit_id = nil)
|
||||
if commit_id
|
||||
repo.commits(commit_id).first
|
||||
else
|
||||
repo.commits.first
|
||||
end
|
||||
end
|
||||
|
||||
def heads
|
||||
@heads ||= repo.heads
|
||||
end
|
||||
|
||||
def fresh_commits(n = 10)
|
||||
commits = heads.map do |h|
|
||||
repo.commits(h.name, n)
|
||||
end.flatten.uniq { |c| c.id }
|
||||
|
||||
commits.sort! do |x, y|
|
||||
y.committed_date <=> x.committed_date
|
||||
end
|
||||
|
||||
commits[0...n]
|
||||
end
|
||||
|
||||
def commits_since(date)
|
||||
commits = heads.map do |h|
|
||||
repo.log(h.name, nil, :since => date)
|
||||
end.flatten.uniq { |c| c.id }
|
||||
|
||||
commits.sort! do |x, y|
|
||||
y.committed_date <=> x.committed_date
|
||||
end
|
||||
|
||||
commits
|
||||
end
|
||||
|
||||
def tree(fcommit, path = nil)
|
||||
fcommit = commit if fcommit == :head
|
||||
tree = fcommit.tree
|
||||
path ? (tree / path) : tree
|
||||
end
|
||||
|
||||
def check_limit
|
||||
unless owner.can_create_project?
|
||||
errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
|
||||
|
|
97
app/models/repository.rb
Normal file
97
app/models/repository.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
class Repository
|
||||
attr_accessor :project
|
||||
|
||||
def self.default_ref
|
||||
"master"
|
||||
end
|
||||
|
||||
def initialize(project)
|
||||
@project = project
|
||||
end
|
||||
|
||||
def path
|
||||
@path ||= project.path
|
||||
end
|
||||
|
||||
def project_id
|
||||
project.id
|
||||
end
|
||||
|
||||
def repo
|
||||
@repo ||= Grit::Repo.new(project.path_to_repo)
|
||||
end
|
||||
|
||||
def url_to_repo
|
||||
if !GITOSIS["port"] or GITOSIS["port"] == 22
|
||||
"#{GITOSIS["git_user"]}@#{GITOSIS["host"]}:#{path}.git"
|
||||
else
|
||||
"ssh://#{GITOSIS["git_user"]}@#{GITOSIS["host"]}:#{GITOSIS["port"]}/#{path}.git"
|
||||
end
|
||||
end
|
||||
|
||||
def path_to_repo
|
||||
GITOSIS["base_path"] + path + ".git"
|
||||
end
|
||||
|
||||
def update_gitosis_project
|
||||
Gitosis.new.configure do |c|
|
||||
c.update_project(path, project.gitosis_writers)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_gitosis_project
|
||||
Gitosis.new.configure do |c|
|
||||
c.destroy_project(@project)
|
||||
end
|
||||
end
|
||||
|
||||
def repo_exists?
|
||||
repo rescue false
|
||||
end
|
||||
|
||||
def tags
|
||||
repo.tags.map(&:name).sort.reverse
|
||||
end
|
||||
|
||||
def heads
|
||||
@heads ||= repo.heads
|
||||
end
|
||||
|
||||
def tree(fcommit, path = nil)
|
||||
fcommit = commit if fcommit == :head
|
||||
tree = fcommit.tree
|
||||
path ? (tree / path) : tree
|
||||
end
|
||||
|
||||
def commit(commit_id = nil)
|
||||
if commit_id
|
||||
repo.commits(commit_id).first
|
||||
else
|
||||
repo.commits.first
|
||||
end
|
||||
end
|
||||
|
||||
def fresh_commits(n = 10)
|
||||
commits = heads.map do |h|
|
||||
repo.commits(h.name, n).each { |c| c.head = h }
|
||||
end.flatten.uniq { |c| c.id }
|
||||
|
||||
commits.sort! do |x, y|
|
||||
y.committed_date <=> x.committed_date
|
||||
end
|
||||
|
||||
commits[0...n]
|
||||
end
|
||||
|
||||
def commits_since(date)
|
||||
commits = heads.map do |h|
|
||||
repo.log(h.name, nil, :since => date).each { |c| c.head = h }
|
||||
end.flatten.uniq { |c| c.id }
|
||||
|
||||
commits.sort! do |x, y|
|
||||
y.committed_date <=> x.committed_date
|
||||
end
|
||||
|
||||
commits
|
||||
end
|
||||
end
|
|
@ -16,6 +16,10 @@ class User < ActiveRecord::Base
|
|||
:foreign_key => :author_id,
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :notes,
|
||||
:foreign_key => :author_id,
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :assigned_issues,
|
||||
:class_name => "Issue",
|
||||
:foreign_key => :assignee_id,
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
%a.project-update{:href => dashboard_feed_path(project, update)}
|
||||
= image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
|
||||
%span.update-title
|
||||
- if update.kind_of?(Grit::Commit)
|
||||
%span.right.tag.commit= update.head.name
|
||||
= dashboard_feed_title(update)
|
||||
%span.update-author
|
||||
%strong= update.author_name
|
||||
authored
|
||||
= time_ago_in_words(update.created_at)
|
||||
ago
|
||||
%br
|
||||
/ #news-feed
|
||||
/ #dashboard-content
|
||||
|
|
|
@ -8,15 +8,11 @@
|
|||
<%= image_tag gravatar_icon(current_user.email) %>
|
||||
<% end %>
|
||||
|
||||
<a href="#" class="arrow-up"></a>
|
||||
|
||||
<div class="account-links">
|
||||
<%= link_to profile_path, :class => "username" do %>
|
||||
<%#= current_user.name %>
|
||||
Your profile
|
||||
My profile
|
||||
<% end %>
|
||||
<%= link_to "Fluid layout", url_for( :view_style => 'fluid' ) if cookies[:view_style] == "collapsed"%>
|
||||
<%= link_to "Fixed layout", url_for( :view_style => 'collapsed' ) unless cookies[:view_style] == "collapsed"%>
|
||||
<%= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete %>
|
||||
</div>
|
||||
</div><!-- .account-box -->
|
||||
|
@ -50,3 +46,11 @@
|
|||
});
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.keys.all.empty? %>
|
||||
<div id="no_ssh_key_defined">
|
||||
<h2>ATTENTION!</h2>
|
||||
<p>No SSH Key is defined. You won't be able to use any Git command!
|
||||
<p>Click <%=link_to( 'here', keys_path ) %> to add one!
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
.project-container
|
||||
.project-sidebar
|
||||
.fixed
|
||||
%input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"}
|
||||
.git_url_wrapper
|
||||
%input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"}
|
||||
%aside
|
||||
= link_to "History", project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil
|
||||
= link_to "Activities", project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil
|
||||
= link_to "Tree", tree_project_path(@project), :class => current_page?(:controller => "projects", :action => "tree", :id => @project) ? "current" : nil
|
||||
= link_to "Commits", project_commits_path(@project), :class => current_page?(:controller => "commits", :action => "index", :project_id => @project) ? "current" : nil
|
||||
= link_to "Network graph", graph_project_path(@project), :class => current_page?(:controller => "projects", :action => "graph", :id => @project) ? "current" : nil
|
||||
= link_to team_project_path(@project), :class => (current_page?(:controller => "projects", :action => "team", :id => @project) || controller.controller_name == "team_members") ? "current" : nil do
|
||||
Team
|
||||
- if @project.users_projects.count > 0
|
||||
|
|
|
@ -28,4 +28,4 @@
|
|||
|
||||
.clear
|
||||
%br
|
||||
= f.submit 'Add note', :class => "lbutton vm", :id => "submit_note"
|
||||
= f.submit 'Add note', :class => "button", :id => "submit_note"
|
||||
|
|
15
app/views/projects/_feed.html.haml
Normal file
15
app/views/projects/_feed.html.haml
Normal file
|
@ -0,0 +1,15 @@
|
|||
%a.project-update{:href => dashboard_feed_path(project, update)}
|
||||
= image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
|
||||
%span.update-title
|
||||
= dashboard_feed_title(update)
|
||||
%span.update-author
|
||||
%strong= update.author_name
|
||||
authored
|
||||
= time_ago_in_words(update.created_at)
|
||||
ago
|
||||
.right
|
||||
- klass = update.class.to_s.split("::").last.downcase
|
||||
%span.tag{ :class => klass }= klass
|
||||
- if update.kind_of?(Grit::Commit)
|
||||
%span.tag.commit= update.head.name
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
%table
|
||||
%thead
|
||||
%th
|
||||
Commits
|
||||
.filter.right
|
||||
= form_tag project_path(@project), :method => :get, :class => "right" do
|
||||
.left
|
||||
= radio_button_tag :view, "recent", (params[:view] || "recent") == "recent", :onclick => "this.form.submit()", :id => "recent_view"
|
||||
= label_tag "recent_view","Recent"
|
||||
.left
|
||||
= radio_button_tag :view, "day", params[:view] == "day", :onclick => "this.form.submit()", :id => "day_view"
|
||||
= label_tag "day_view","Today"
|
||||
.left
|
||||
= radio_button_tag :view, "week", params[:view] == "week", :onclick => "this.form.submit()", :id => "week_view"
|
||||
= label_tag "week_view","Week"
|
||||
- @commits.each do |commit|
|
||||
%tr
|
||||
%td
|
||||
%div.commit
|
||||
- if commit.author.email
|
||||
= image_tag gravatar_icon(commit.author.email), :class => "left", :width => 40, :style => "padding-right:5px;"
|
||||
- else
|
||||
= image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
|
||||
.title
|
||||
%p= link_to truncate(commit.safe_message, :length => fixed_mode? ? 40 : 100), project_commit_path(@project, :id => commit.id)
|
||||
|
||||
%span
|
||||
%span.author
|
||||
%strong= commit.author.name.force_encoding("UTF-8")
|
||||
%cite.cgray
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
ago
|
|
@ -1,27 +0,0 @@
|
|||
- @messages.group_by{ |x| [x.noteable_id, x.noteable_type]}.each do |item, notes|
|
||||
- id, type = item[0], item[1]
|
||||
- parent = load_note_parent(id, type, @project)
|
||||
- next unless parent
|
||||
|
||||
%table
|
||||
%thead
|
||||
%th
|
||||
%div{ :class => "recent_message_parent"}
|
||||
= link_to(truncate(dashboard_feed_title(parent), :length => fixed_mode? ? 40 : 100 ), dashboard_feed_path(@project, parent))
|
||||
- notes.sort {|x,y| y.updated_at <=> x.updated_at }.each do |note|
|
||||
%tr
|
||||
%td
|
||||
%div.message
|
||||
= image_tag gravatar_icon(note.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
|
||||
%div.title
|
||||
= link_to markdown(truncate(note.note, :length => fixed_mode? ? 40 : 100)), dashboard_feed_path(@project, parent) + "#note_#{note.id}"
|
||||
- if note.attachment.url
|
||||
%br
|
||||
Attachment:
|
||||
= link_to note.attachment_identifier, note.attachment.url
|
||||
%div.author
|
||||
%strong= note.author_name
|
||||
%cite.cgray
|
||||
= time_ago_in_words(note.updated_at)
|
||||
ago
|
||||
%br
|
|
@ -1,13 +1,13 @@
|
|||
- @projects.in_groups_of(3, false) do |projects|
|
||||
- projects.each_with_index do |project, i|
|
||||
%div.grid_1
|
||||
%div.grid_1.projects_selector
|
||||
%div{ :class => "project-box ui-box ui-box-big" }
|
||||
= link_to project_path(project) do
|
||||
%h3= project.name
|
||||
%h3= truncate(project.name, :length => 20)
|
||||
.data
|
||||
%p.title.repository
|
||||
%p.title.repository.git_url_wrapper
|
||||
%span Repository:
|
||||
= project.url_to_repo
|
||||
%input{ :value => project.url_to_repo, :class => ['git-url', 'one_click_select', 'text', 'project_list_url'], :readonly => 'readonly' }
|
||||
%p.title.activity
|
||||
%span Last Activity:
|
||||
- last_note = project.notes.last
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
= time_ago_in_words(content_commit.committed_date)
|
||||
ago
|
||||
%td.commit
|
||||
= link_to truncate(content_commit.safe_message, :length => fixed_mode? ? 40 : 80), project_commit_path(@project, content_commit), :class => "tree-commit-link"
|
||||
= link_to truncate(content_commit.safe_message, :length => 40), project_commit_path(@project, content_commit), :class => "tree-commit-link"
|
||||
- tm = @project.team_member_by_name_or_email(content_commit.author_email, content_commit.author_name)
|
||||
- if tm
|
||||
= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
|
||||
|
|
|
@ -28,7 +28,7 @@ eos
|
|||
<h2>Existing Git Repo?</h2>
|
||||
<% exist_repo_setup_str = <<eos
|
||||
cd existing_git_repo
|
||||
git remote add origin #{@project.url_to_repo}
|
||||
git remote add origin #{@project.url_to_repo}
|
||||
git push -u origin master
|
||||
eos
|
||||
%>
|
||||
|
|
9
app/views/projects/graph.html.haml
Normal file
9
app/views/projects/graph.html.haml
Normal file
|
@ -0,0 +1,9 @@
|
|||
#holder.graph
|
||||
|
||||
:javascript
|
||||
var chunk1={commits:#{@commits_json}};
|
||||
var days=#{@days_json};
|
||||
initGraph();
|
||||
$(function(){
|
||||
branchGraph($("#holder")[0]);
|
||||
});
|
|
@ -1,8 +1,10 @@
|
|||
.new-project-hodler
|
||||
.container_4
|
||||
%h2.icon
|
||||
%span
|
||||
New Project
|
||||
- content_for(:body_class, "new-project-page")
|
||||
- content_for(:page_title) do
|
||||
.new-project-hodler
|
||||
.container
|
||||
%h2.icon
|
||||
%span
|
||||
New Project
|
||||
|
||||
%div.clear
|
||||
= render 'form'
|
||||
%div.clear
|
||||
= render 'form'
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
.left.width-49p
|
||||
=render "projects/recent_commits"
|
||||
- content_for(:body_class, "project-page dashboard")
|
||||
|
||||
.right.width-49p
|
||||
=render "projects/recent_messages"
|
||||
#news-feed.news-feed
|
||||
%h2.icon
|
||||
%span>
|
||||
Activities
|
||||
.project-box.project-updates.ui-box.ui-box-small.ui-box-big
|
||||
- @activities.each do |update|
|
||||
= render "projects/feed", :update => update, :project => @project
|
||||
|
||||
:javascript
|
||||
function updateDashboard(){
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
%td{:colspan => 2}
|
||||
= f.label :content, "Code"
|
||||
%br
|
||||
= f.text_area :content, :style => "height:240px;width:932px;"
|
||||
%br
|
||||
= f.text_area :content
|
||||
|
||||
.actions.prepend-top
|
||||
= f.submit 'Save', :class => "lbutton vm"
|
||||
= f.submit 'Save', :class => "button"
|
||||
|
|
|
@ -2,11 +2,17 @@
|
|||
%tr{ :id => dom_id(snippet), :class => "snippet", :url => project_snippet_path(@project, snippet) }
|
||||
%td
|
||||
= image_tag gravatar_icon(snippet.author.email), :class => "left", :width => 40, :style => "padding:0 5px;"
|
||||
= truncate snippet.author.name, :lenght => 20
|
||||
%td= html_escape snippet.title
|
||||
%td= html_escape snippet.file_name
|
||||
%td
|
||||
- if can?(current_user, :admin_snippet, @project) || snippet.author == current_user
|
||||
= link_to 'Edit', edit_project_snippet_path(@project, snippet), :class => "lbutton positive"
|
||||
- if can?(current_user, :admin_snippet, @project) || snippet.author == current_user
|
||||
= link_to 'Destroy', [@project, snippet], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-snippet negative", :id => "destroy_snippet_#{snippet.id}"
|
||||
%span
|
||||
%strong= html_escape snippet.title
|
||||
%br
|
||||
%br
|
||||
%div.author
|
||||
%strong= truncate snippet.author.name, :lenght => 20
|
||||
%cite.cgray
|
||||
= time_ago_in_words(snippet.updated_at)
|
||||
ago
|
||||
.right.action-links
|
||||
- if can?(current_user, :admin_snippet, @project) || snippet.author == current_user
|
||||
= link_to 'Edit', edit_project_snippet_path(@project, snippet), :class => "cgray"
|
||||
- if can?(current_user, :admin_snippet, @project) || snippet.author == current_user
|
||||
= link_to 'Destroy', [@project, snippet], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-snippet negative", :id => "destroy_snippet_#{snippet.id}"
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
%div
|
||||
- if can? current_user, :write_snippet, @project
|
||||
.left= link_to 'New Snippet', new_project_snippet_path(@project), :class => "lbutton vm"
|
||||
= link_to 'New Snippet', new_project_snippet_path(@project), :class => "button append-bottom-10"
|
||||
|
||||
%table.round-borders#snippets-table
|
||||
%tr
|
||||
%th Author
|
||||
%th Title
|
||||
%th File name
|
||||
%thead
|
||||
%th
|
||||
= render @snippets.fresh
|
||||
:javascript
|
||||
|
|
|
@ -2,3 +2,4 @@ admin_uri: git@localhost:gitosis-admin.git
|
|||
base_path: /home/git/repositories/
|
||||
host: localhost
|
||||
git_user: git
|
||||
# port: 22
|
||||
|
|
|
@ -34,6 +34,7 @@ Gitlab::Application.routes.draw do
|
|||
get "blob"
|
||||
get "team"
|
||||
get "wall"
|
||||
get "graph"
|
||||
|
||||
# tree viewer
|
||||
get "tree/:commit_id" => "projects#tree"
|
||||
|
|
178
lib/assets/javascripts/branch-graph.js
Normal file
178
lib/assets/javascripts/branch-graph.js
Normal file
|
@ -0,0 +1,178 @@
|
|||
var commits = {},
|
||||
comms = {},
|
||||
pixelsX = [],
|
||||
pixelsY = [],
|
||||
mmax = Math.max,
|
||||
mtime = 0,
|
||||
mspace = 0,
|
||||
parents = {},
|
||||
ii = 0,
|
||||
colors = ["#000"];
|
||||
|
||||
function initGraph(){
|
||||
commits = chunk1.commits;
|
||||
ii = commits.length;
|
||||
for (var i = 0; i < ii; i++) {
|
||||
for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
|
||||
parents[commits[i].parents[j][0]] = true;
|
||||
}
|
||||
mtime = Math.max(mtime, commits[i].time);
|
||||
mspace = Math.max(mspace, commits[i].space);
|
||||
}
|
||||
mtime = mtime + 4;
|
||||
mspace = mspace + 10;
|
||||
for (i = 0; i < ii; i++) {
|
||||
if (commits[i].id in parents) {
|
||||
commits[i].isParent = true;
|
||||
}
|
||||
comms[commits[i].id] = commits[i];
|
||||
}
|
||||
for (var k = 0; k < mspace; k++) {
|
||||
colors.push(Raphael.getColor());
|
||||
}
|
||||
}
|
||||
|
||||
function branchGraph(holder) {
|
||||
var ch = mspace * 20 + 20, cw = mtime * 20 + 20,
|
||||
r = Raphael("holder", cw, ch),
|
||||
top = r.set();
|
||||
var cuday = 0, cumonth = "";
|
||||
r.rect(0, 0, days.length * 20 + 20, 20).attr({fill: "#474D57"});
|
||||
r.rect(0, 20, days.length * 20 + 20, 20).attr({fill: "#f7f7f7"});
|
||||
|
||||
for (mm = 0; mm < days.length; mm++) {
|
||||
if(days[mm] != null){
|
||||
if(cuday != days[mm][0]){
|
||||
r.text(10 + mm * 20, 30, days[mm][0]).attr({font: "12px Fontin-Sans, Arial", fill: "#444"});
|
||||
cuday = days[mm][0]
|
||||
}
|
||||
if(cumonth != days[mm][1]){
|
||||
r.text(10 + mm * 20, 10, days[mm][1]).attr({font: "12px Fontin-Sans, Arial", fill: "#444"});
|
||||
cumonth = days[mm][1]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ii; i++) {
|
||||
var x = 10 + 20 * commits[i].time,
|
||||
y = 70 + 20 * commits[i].space;
|
||||
r.circle(x, y, 3).attr({fill: colors[commits[i].space], stroke: "none"});
|
||||
if (commits[i].refs != null && commits[i].refs != "") {
|
||||
var longrefs = commits[i].refs
|
||||
var shortrefs = commits[i].refs;
|
||||
if (shortrefs.length > 15){
|
||||
shortrefs = shortrefs.substr(0,13) + "...";
|
||||
}
|
||||
var t = r.text(x+5, y+5, shortrefs).attr({font: "12px Fontin-Sans, Arial", fill: "#666",
|
||||
title: longrefs, cursor: "pointer", rotation: "90"});
|
||||
|
||||
var textbox = t.getBBox();
|
||||
t.translate(textbox.height/-4,textbox.width/2);
|
||||
}
|
||||
for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
|
||||
var c = comms[commits[i].parents[j][0]];
|
||||
if (c) {
|
||||
var cx = 10 + 20 * c.time,
|
||||
cy = 70 + 20 * c.space;
|
||||
if (c.space == commits[i].space) {
|
||||
r.path("M" + (x - 5) + "," + (y + .0001) + "L" + (15 + 20 * c.time) + "," + (y + .0001))
|
||||
.attr({stroke: colors[c.space], "stroke-width": 2});
|
||||
|
||||
} else if (c.space < commits[i].space) {
|
||||
r.path(["M", x - 5, y + .0001, "l-5-2,0,4,5,-2C",x-5,y,x -17, y+2, x -20, y-10,"L", cx,y-10,cx , cy])
|
||||
.attr({stroke: colors[commits[i].space], "stroke-width": 2});
|
||||
} else {
|
||||
r.path(["M", x-5, y, "l-5-2,0,4,5,-2C",x-5,y,x -17, y-2, x -20, y+10,"L", cx,y+10,cx , cy])
|
||||
.attr({stroke: colors[commits[i].space], "stroke-width": 2});
|
||||
}
|
||||
}
|
||||
}
|
||||
(function (c, x, y) {
|
||||
top.push(r.circle(x, y, 10).attr({fill: "#000", opacity: 0, cursor: "pointer"})
|
||||
.hover(function () {
|
||||
var s = r.text(100, 100,c.author + "\n \n" +c.id + "\n \n" + c.message).attr({fill: "#fff"});
|
||||
this.popup = r.popupit(x, y + 5, s, 0);
|
||||
top.push(this.popup.insertBefore(this));
|
||||
}, function () {
|
||||
this.popup && this.popup.remove() && delete this.popup;
|
||||
}));
|
||||
}(commits[i], x, y));
|
||||
}
|
||||
top.toFront();
|
||||
var hw = holder.offsetWidth,
|
||||
hh = holder.offsetHeight,
|
||||
v = r.rect(hw - 8, 0, 4, Math.pow(hh, 2) / ch, 2).attr({fill: "#000", opacity: 0}),
|
||||
h = r.rect(0, hh - 8, Math.pow(hw, 2) / cw, 4, 2).attr({fill: "#000", opacity: 0}),
|
||||
bars = r.set(v, h),
|
||||
drag,
|
||||
dragger = function (e) {
|
||||
if (drag) {
|
||||
e = e || window.event;
|
||||
holder.scrollLeft = drag.sl - (e.clientX - drag.x);
|
||||
holder.scrollTop = drag.st - (e.clientY - drag.y);
|
||||
}
|
||||
};
|
||||
holder.onmousedown = function (e) {
|
||||
e = e || window.event;
|
||||
drag = {x: e.clientX, y: e.clientY, st: holder.scrollTop, sl: holder.scrollLeft};
|
||||
document.onmousemove = dragger;
|
||||
bars.animate({opacity: .5}, 300);
|
||||
};
|
||||
document.onmouseup = function () {
|
||||
drag = false;
|
||||
document.onmousemove = null;
|
||||
bars.animate({opacity: 0}, 300);
|
||||
};
|
||||
holder.scrollLeft = cw;
|
||||
};
|
||||
Raphael.fn.popupit = function (x, y, set, dir, size) {
|
||||
dir = dir == null ? 2 : dir;
|
||||
size = size || 5;
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
var bb = set.getBBox(),
|
||||
w = Math.round(bb.width / 2),
|
||||
h = Math.round(bb.height / 2),
|
||||
dx = [0, w + size * 2, 0, -w - size * 2],
|
||||
dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
|
||||
p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
|
||||
"l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
|
||||
"l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
|
||||
"l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
|
||||
"l", -mmax(w - size, 0), 0, "z"].join(","),
|
||||
xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];
|
||||
set.translate(xy.x - w - bb.x, xy.y - h - bb.y);
|
||||
return this.set(this.path(p).attr({fill: "#234", stroke: "none"}).insertBefore(set.node ? set : set[0]), set);
|
||||
};
|
||||
Raphael.fn.popup = function (x, y, text, dir, size) {
|
||||
dir = dir == null ? 2 : dir > 3 ? 3 : dir;
|
||||
size = size || 5;
|
||||
text = text || "$9.99";
|
||||
var res = this.set(),
|
||||
d = 3;
|
||||
res.push(this.path().attr({fill: "#000", stroke: "#000"}));
|
||||
res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"}));
|
||||
res.update = function (X, Y, withAnimation) {
|
||||
X = X || x;
|
||||
Y = Y || y;
|
||||
var bb = this[1].getBBox(),
|
||||
w = bb.width / 2,
|
||||
h = bb.height / 2,
|
||||
dx = [0, w + size * 2, 0, -w - size * 2],
|
||||
dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
|
||||
p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
|
||||
"l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
|
||||
"l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
|
||||
"l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
|
||||
"l", -mmax(w - size, 0), 0, "z"].join(","),
|
||||
xy = [{x: X, y: Y + size * 2 + h}, {x: X - size * 2 - w, y: Y}, {x: X, y: Y - size * 2 - h}, {x: X + size * 2 + w, y: Y}][dir];
|
||||
xy.path = p;
|
||||
if (withAnimation) {
|
||||
this.animate(xy, 500, ">");
|
||||
} else {
|
||||
this.attr(xy);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
return res.update(x, y);
|
||||
};
|
|
@ -1,4 +1,7 @@
|
|||
module CommitExt
|
||||
attr_accessor :head
|
||||
attr_accessor :refs
|
||||
|
||||
def safe_message
|
||||
message.encode("UTF-8",
|
||||
:invalid => :replace,
|
||||
|
|
75
lib/graph_commit.rb
Normal file
75
lib/graph_commit.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
require "grit"
|
||||
|
||||
class GraphCommit
|
||||
attr_accessor :time, :space
|
||||
def initialize(commit)
|
||||
@_commit = commit
|
||||
@time = -1
|
||||
@space = 0
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
@_commit.send(m, *args, &block)
|
||||
end
|
||||
|
||||
# Method is adding time and space on the
|
||||
# list of commits. As well as returns date list
|
||||
# corelated with time set on commits.
|
||||
#
|
||||
# @param [Array<GraphCommit>] comits to index
|
||||
#
|
||||
# @return [Array<TimeDate>] list of commit dates corelated with time on commits
|
||||
def self.index_commits(commits)
|
||||
days, heads = [], []
|
||||
map = {}
|
||||
|
||||
commits.reverse.each_with_index do |c,i|
|
||||
c.time = i
|
||||
days[i] = c.committed_date
|
||||
map[c.id] = c
|
||||
heads += c.refs unless c.refs.nil?
|
||||
end
|
||||
|
||||
heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
|
||||
# sort heads so the master is top and current branches are closer
|
||||
heads.sort! do |a,b|
|
||||
if a.name == "master"
|
||||
-1
|
||||
elsif b.name == "master"
|
||||
1
|
||||
else
|
||||
b.commit.committed_date <=> a.commit.committed_date
|
||||
end
|
||||
end
|
||||
|
||||
j = 0
|
||||
heads.each do |h|
|
||||
if map.include? h.commit.id then
|
||||
j = mark_chain(j+=1, map[h.commit.id], map)
|
||||
end
|
||||
end
|
||||
days
|
||||
end
|
||||
|
||||
# Add space mark on commit and its parents
|
||||
#
|
||||
# @param [Fixnum] space (row on the graph) to be set
|
||||
# @param [GraphCommit] the commit object.
|
||||
# @param [Hash<String,GraphCommit>] map of commits
|
||||
#
|
||||
# @return [Fixnum] max space used.
|
||||
def self.mark_chain(mark, commit, map)
|
||||
commit.space = mark if commit.space == 0
|
||||
m1 = mark - 1
|
||||
marks = commit.parents.collect do |p|
|
||||
if map.include? p.id and map[p.id].space == 0 then
|
||||
mark_chain(m1 += 1, map[p.id],map)
|
||||
else
|
||||
m1 + 1
|
||||
end
|
||||
end
|
||||
marks << mark
|
||||
marks.compact.max
|
||||
end
|
||||
|
||||
end
|
35
spec/helpers/application_helper_spec.rb
Normal file
35
spec/helpers/application_helper_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApplicationHelper do
|
||||
context ".gravatar_icon" do
|
||||
context "over http" do
|
||||
it "returns the correct URL to www.gravatar.com" do
|
||||
expected = "http://www.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
|
||||
|
||||
# Pretend we're running over HTTP
|
||||
helper.stub(:request) do
|
||||
request = double('request')
|
||||
request.stub(:ssl?) { false }
|
||||
request
|
||||
end
|
||||
|
||||
helper.gravatar_icon("admin@local.host").should == expected
|
||||
end
|
||||
end
|
||||
|
||||
context "over https" do
|
||||
it "returns the correct URL to secure.gravatar.com" do
|
||||
expected = "https://secure.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon"
|
||||
|
||||
# Pretend we're running over HTTPS
|
||||
helper.stub(:request) do
|
||||
request = double('request')
|
||||
request.stub(:ssl?) { true }
|
||||
request
|
||||
end
|
||||
|
||||
helper.gravatar_icon("admin@local.host").should == expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -39,5 +39,6 @@ end
|
|||
# updated_at :datetime
|
||||
# closed :boolean default(FALSE), not null
|
||||
# position :integer default(0)
|
||||
# critical :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ end
|
|||
# Table name: notes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# note :string(255)
|
||||
# note :text
|
||||
# noteable_id :string(255)
|
||||
# noteable_type :string(255)
|
||||
# author_id :integer
|
||||
|
|
|
@ -18,6 +18,21 @@ describe User do
|
|||
user = User.new(:email => "test@mail.com")
|
||||
user.identifier.should == "test_mail.com"
|
||||
end
|
||||
|
||||
describe "dependent" do
|
||||
before do
|
||||
@user = Factory :user
|
||||
@note = Factory :note,
|
||||
:author => @user,
|
||||
:project => Factory(:project)
|
||||
end
|
||||
|
||||
it "should destroy all notes with user" do
|
||||
Note.find_by_id(@note.id).should_not be_nil
|
||||
@user.destroy
|
||||
Note.find_by_id(@note.id).should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
|
|
|
@ -22,6 +22,7 @@ describe "Dashboard" do
|
|||
|
||||
it "should have news feed" do
|
||||
within "#news-feed" do
|
||||
page.should have_content("master")
|
||||
page.should have_content(@project.commit.author.name)
|
||||
page.should have_content(@project.commit.safe_message)
|
||||
end
|
||||
|
|
|
@ -72,10 +72,13 @@ describe "Projects" do
|
|||
current_path.should == project_path(@project)
|
||||
end
|
||||
|
||||
it "should beahave like dashboard" do
|
||||
page.should have_content("History")
|
||||
it "should beahave like activities page" do
|
||||
within ".project-update" do
|
||||
page.should have_content("master")
|
||||
page.should have_content(@project.commit.author.name)
|
||||
page.should have_content(@project.commit.safe_message)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "GET /projects/team" do
|
||||
|
|
|
@ -7,8 +7,9 @@ describe "Top Panel", :js => true do
|
|||
before do
|
||||
visit projects_path
|
||||
fill_in "search", :with => "Ke"
|
||||
sleep(2)
|
||||
find(:xpath, "//ul[contains(@class,'ui-autocomplete')]/li/a[.=\"Keys\"]").click
|
||||
within ".ui-autocomplete" do
|
||||
find(:xpath, "//a[.=\"Keys\"]").click
|
||||
end
|
||||
end
|
||||
|
||||
it "should be on projects page" do
|
||||
|
@ -23,8 +24,9 @@ describe "Top Panel", :js => true do
|
|||
visit project_path(@project)
|
||||
|
||||
fill_in "search", :with => "Commi"
|
||||
sleep(2)
|
||||
find(:xpath, "//ul[contains(@class,'ui-autocomplete')]/li/a[.=\"#{@project.code} / Commits\"]").click
|
||||
within ".ui-autocomplete" do
|
||||
find(:xpath, "//a[.=\"#{@project.code} / Commits\"]").click
|
||||
end
|
||||
end
|
||||
|
||||
it "should be on projects page" do
|
||||
|
|
7
vendor/assets/javascripts/raphael.js
vendored
Normal file
7
vendor/assets/javascripts/raphael.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -382,15 +382,13 @@
|
|||
padding:.2em .4em;
|
||||
line-height:1.5;
|
||||
zoom:1;
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-menu .ui-menu-item a.ui-state-hover,
|
||||
.ui-menu .ui-menu-item a.ui-state-active {
|
||||
font-weight: normal;
|
||||
margin: -1px;
|
||||
background: #fff !important;
|
||||
background: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#FFF6BF)) !important;
|
||||
background: -moz-linear-gradient(top,#fff,#FFF6BF) !important;
|
||||
background: transparent 9 !important;
|
||||
background: #eee;
|
||||
border-radius:0px;
|
||||
border-color:white;
|
||||
border-bottom: 1px solid #E2EAEE;
|
||||
|
|
Loading…
Reference in a new issue