diff options
| author | Riyad Preukschas <riyad@informatik.uni-bremen.de> | 2012-12-23 01:03:57 +0100 |
|---|---|---|
| committer | Riyad Preukschas <riyad@informatik.uni-bremen.de> | 2012-12-23 01:03:57 +0100 |
| commit | db2c15369c365340aeaf4e431e8838714b40396b (patch) | |
| tree | 26ca045a337132370b67cc8f2ed4010e3087dfa5 /app | |
| parent | b47173da6a0fea0982d009f91e2c4d042f9b5c37 (diff) | |
| parent | 68c43d59f09a66cca0da1b9a50c11421d52eac9a (diff) | |
| download | gitlab-ce-db2c15369c365340aeaf4e431e8838714b40396b.tar.gz | |
Merge branch 'master' into discussions
Conflicts:
app/assets/stylesheets/main.scss
app/models/project.rb
app/views/notes/_common_form.html.haml
app/views/notes/_per_line_form.html.haml
lib/gitlab/markdown.rb
spec/models/note_spec.rb
Diffstat (limited to 'app')
171 files changed, 1614 insertions, 1426 deletions
diff --git a/app/assets/fonts/korolev-medium-compressed.otf b/app/assets/fonts/korolev-medium-compressed.otf Binary files differindex e3817cec857..a9cd3cbffff 100644 --- a/app/assets/fonts/korolev-medium-compressed.otf +++ b/app/assets/fonts/korolev-medium-compressed.otf diff --git a/app/assets/images/ajax_loader_gray.gif b/app/assets/images/ajax_loader_gray.gif Binary files differnew file mode 100644 index 00000000000..af3f618bd0b --- /dev/null +++ b/app/assets/images/ajax_loader_gray.gif diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png Binary files differdeleted file mode 100644 index 2d08c9f6825..00000000000 --- a/app/assets/images/logo.png +++ /dev/null diff --git a/app/assets/images/logo_basic.png b/app/assets/images/logo_basic.png Binary files differdeleted file mode 100644 index bc5ec128b90..00000000000 --- a/app/assets/images/logo_basic.png +++ /dev/null diff --git a/app/assets/images/logo_text.png b/app/assets/images/logo_text.png Binary files differdeleted file mode 100644 index c74663930e4..00000000000 --- a/app/assets/images/logo_text.png +++ /dev/null diff --git a/app/assets/images/logo_text_tr.png b/app/assets/images/logo_text_tr.png Binary files differdeleted file mode 100644 index fdb32ee29fe..00000000000 --- a/app/assets/images/logo_text_tr.png +++ /dev/null diff --git a/app/assets/images/logo_white.png b/app/assets/images/logo_white.png Binary files differindex 366e3f3f3b9..e3415816558 100644 --- a/app/assets/images/logo_white.png +++ b/app/assets/images/logo_white.png diff --git a/app/assets/images/service-disabled-gitlab-ci.png b/app/assets/images/service-disabled-gitlab-ci.png Binary files differdeleted file mode 100644 index 8d1f9d0b50d..00000000000 --- a/app/assets/images/service-disabled-gitlab-ci.png +++ /dev/null diff --git a/app/assets/images/service-gitlab-ci.png b/app/assets/images/service-gitlab-ci.png Binary files differdeleted file mode 100644 index bcb30a3fb1a..00000000000 --- a/app/assets/images/service-gitlab-ci.png +++ /dev/null diff --git a/app/assets/images/switch_icon.png b/app/assets/images/switch_icon.png Binary files differnew file mode 100644 index 00000000000..7c11f206593 --- /dev/null +++ b/app/assets/images/switch_icon.png diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index ffc4c409b54..1cc9d34dd80 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -1,52 +1,38 @@ # Creates the variables for setting up GFM auto-completion window.GitLab ?= {} -GitLab.GfmAutoComplete ?= {} - -# Emoji -data = [] -template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>" -GitLab.GfmAutoComplete.Emoji = {data, template} - -# Team Members -data = [] -url = ''; -params = {private_token: '', page: 1} -GitLab.GfmAutoComplete.Members = {data, url, params} - -# Add GFM auto-completion to all input fields, that accept GFM input. -GitLab.GfmAutoComplete.setup = -> - input = $('.js-gfm-input') - +GitLab.GfmAutoComplete = # Emoji - input.atWho ':', - data: GitLab.GfmAutoComplete.Emoji.data, - tpl: GitLab.GfmAutoComplete.Emoji.template + Emoji: + data: [] + template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>' # Team Members - input.atWho '@', (query, callback) -> - (getMoreMembers = -> - $.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params) - .success (members) -> - # pick the data we need - newMembersData = $.map(members, (m) -> m.name ) - - # add the new page of data to the rest - $.merge(GitLab.GfmAutoComplete.Members.data, newMembersData) - - # show the pop-up with a copy of the current data - callback(GitLab.GfmAutoComplete.Members.data[..]) - - # are we past the last page? - if newMembersData.length is 0 - # set static data and stop callbacks - input.atWho '@', - data: GitLab.GfmAutoComplete.Members.data - callback: null - else - # get next page - getMoreMembers() + Members: + data: [] + url: '' + params: + private_token: '' + template: '<li data-value="${username}">${username} <small>${name}</small></li>' + + # Add GFM auto-completion to all input fields, that accept GFM input. + setup: -> + input = $('.js-gfm-input') + + # Emoji + input.atWho ':', + data: @Emoji.data + tpl: @Emoji.template + + # Team Members + input.atWho '@', + tpl: @Members.template + callback: (query, callback) => + request_params = $.extend({}, @Members.params, query: query) + $.getJSON(@Members.url, request_params).done (members) => + new_members_data = $.map(members, (m) -> + username: m.username, + name: m.name + ) + callback(new_members_data) - # so the next request gets the next page - GitLab.GfmAutoComplete.Members.params.page += 1 - ).call() diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js index e2fe1075903..719d2c176c1 100644 --- a/app/assets/javascripts/issues.js +++ b/app/assets/javascripts/issues.js @@ -1,43 +1,3 @@ -function switchToNewIssue(){ - $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ - $('select#issue_assignee_id').chosen(); - $('select#issue_milestone_id').chosen(); - $("#new_issue_dialog").show("fade", { direction: "right" }, 150); - $('.top-tabs .add_new').hide(); - disableButtonIfEmptyField("#issue_title", ".save-btn"); - GitLab.GfmAutoComplete.setup(); - }); -} - -function switchToEditIssue(){ - $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ - $('select#issue_assignee_id').chosen(); - $('select#issue_milestone_id').chosen(); - $("#edit_issue_dialog").show("fade", { direction: "right" }, 150); - $('.add_new').hide(); - disableButtonIfEmptyField("#issue_title", ".save-btn"); - GitLab.GfmAutoComplete.setup(); - }); -} - -function switchFromNewIssue(){ - backToIssues(); -} - -function switchFromEditIssue(){ - backToIssues(); -} - -function backToIssues(){ - $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){ - $(".issues_content").show("fade", { direction: "left" }, 150, function() { - $("#edit_issue_dialog").html(""); - $("#new_issue_dialog").html(""); - $('.add_new').show(); - }); - }); -} - function initIssuesSearch() { var href = $('#issue_search_form').attr('action'); var last_terms = ''; @@ -76,23 +36,15 @@ function issuesPage(){ $(this).closest("form").submit(); }); - $("#new_issue_link").click(function(){ - updateNewIssueURL(); - }); - - $('body').on('ajax:success', '.close_issue, .reopen_issue, #new_issue', function(){ + $('body').on('ajax:success', '.close_issue, .reopen_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(){ + reopen = t.hasClass('reopen_issue'); + $('.issue_counter').each(function(){ var issue = $(this); totalIssues = parseInt( $(this).html(), 10 ); - if( newIssue || ( reopen && issue.closest('.main_menu').length ) ){ + if( reopen && issue.closest('.main_menu').length ){ $(this).html( totalIssues+1 ); }else { $(this).html( totalIssues-1 ); @@ -126,20 +78,3 @@ function issuesCheckChanged() { $('.issues_filters').show(); } } - -function updateNewIssueURL(){ - var new_issue_link = $("#new_issue_link"); - var milestone_id = $("#milestone_id").val(); - var assignee_id = $("#assignee_id").val(); - var new_href = ""; - if(milestone_id){ - new_href = "issue[milestone_id]=" + milestone_id + "&"; - } - if(assignee_id){ - new_href = new_href + "issue[assignee_id]=" + assignee_id; - } - if(new_href.length){ - new_href = new_issue_link.attr("href") + "?" + new_href; - new_issue_link.attr("href", new_href); - } -}; diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index bdb83f49474..f6c398c0acf 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -7,6 +7,18 @@ window.slugify = (text) -> window.ajaxGet = (url) -> $.ajax({type: "GET", url: url, dataType: "script"}) +window.errorMessage = (message) -> + ehtml = $("<p>") + ehtml.addClass("error_message") + ehtml.html(message) + ehtml + +window.split = (val) -> + return val.split( /,\s*/ ) + +window.extractLast = (term) -> + return split( term ).pop() + # Disable button if text field is empty window.disableButtonIfEmptyField = (field_selector, button_selector) -> field = $(field_selector) diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js index 170a0479de7..ee714f9cabb 100644 --- a/app/assets/javascripts/merge_requests.js +++ b/app/assets/javascripts/merge_requests.js @@ -26,6 +26,12 @@ var MergeRequest = { self.showState(data.state); }, "json"); } + + if(self.opts.ci_enable){ + $.get(self.opts.url_to_ci_check, function(data){ + self.showCiState(data.status); + }, "json"); + } }, initTabs: @@ -79,6 +85,11 @@ var MergeRequest = { $(".automerge_widget." + state).show(); }, + showCiState: + function(state){ + $(".ci_widget").hide(); + $(".ci_widget.ci-" + state).show(); + }, loadDiff: function() { diff --git a/app/assets/javascripts/projects.js.coffee b/app/assets/javascripts/projects.js.coffee index 1808f0578f6..d03a487c453 100644 --- a/app/assets/javascripts/projects.js.coffee +++ b/app/assets/javascripts/projects.js.coffee @@ -18,10 +18,3 @@ $ -> # Ref switcher $('.project-refs-select').on 'change', -> $(@).parents('form').submit() - -class @GraphNav - @init: -> - $('.graph svg').css 'position', 'relative' - $('body').bind 'keyup', (e) -> - $('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left - $('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css deleted file mode 100644 index a23d4532915..00000000000 --- a/app/assets/stylesheets/application.css +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This is a manifest file that'll automatically include all the stylesheets available in this directory - * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at - * the top of the compiled file, but it's generally better to create a new file per style scope. - *= require jquery.ui.gitlab - *= require jquery.atwho - *= require chosen - *= require_self - *= require main -*/ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 00000000000..f93246c13c7 --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,52 @@ +/* + * This is a manifest file that'll automatically include all the stylesheets available in this directory + * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at + * the top of the compiled file, but it's generally better to create a new file per style scope. + *= require jquery.ui.gitlab + *= require jquery.atwho + *= require chosen + *= require_self +*/ + +/** + * GitLab bootstrap: + */ +@import "gitlab_bootstrap.scss"; + +@import "common.scss"; +@import "ref_select.scss"; + +@import "sections/header.scss"; +@import "sections/nav.scss"; +@import "sections/commits.scss"; +@import "sections/issues.scss"; +@import "sections/projects.scss"; +@import "sections/snippets.scss"; +@import "sections/votes.scss"; +@import "sections/merge_requests.scss"; +@import "sections/graph.scss"; +@import "sections/events.scss"; +@import "sections/themes.scss"; +@import "sections/tree.scss"; +@import "sections/notes.scss"; +@import "sections/profile.scss"; +@import "sections/login.scss"; +@import "sections/editor.scss"; + +@import "highlight/white.scss"; +@import "highlight/dark.scss"; + +/** + * UI themes: + */ +@import "themes/ui_basic.scss"; +@import "themes/ui_mars.scss"; +@import "themes/ui_modern.scss"; +@import "themes/ui_gray.scss"; +@import "themes/ui_color.scss"; + +/** + * Styles for JS behaviors. + */ +@import "behaviors.scss"; + diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 44bfb619ead..6d4c815106b 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -13,20 +13,12 @@ body { margin: 0 0; } -.container .sidebar { - width: 200px; - height: 100%; - min-height: 450px; - float: right; -} - - .visible_link, .author_link { color: $link_color; } -.help li { color:#111 } +.help li { color:$style_color; } .back_link { text-decoration: underline; @@ -65,6 +57,9 @@ table a code { background: url(ajax_loader.gif) no-repeat center center; width: 40px; height: 40px; + &.loading-gray { + background: url(ajax_loader_gray.gif) no-repeat center center; + } } /** FLASH message **/ @@ -96,28 +91,17 @@ table a code { margin-right:50px } -.handle:hover { - cursor: move; -} - span.update-author { display: block; -} -span.update-author { color: #999; font-weight: normal; font-style: italic; -} -span.update-author strong { - font-weight: bold; - font-style: normal; + strong { + font-weight: bold; + font-style: normal; + } } -/** UPDATE ITEM **/ -span.update-author { - display: block; -} -/** END UPDATE ITEM **/ .dashboard-loader { float: left; margin: 10px; @@ -264,21 +248,6 @@ input.git_clone_url { } -/** bordered list **/ -ul.bordered-list { - margin: 5px 0px; - padding: 0px; - li { - padding: 5px 0; - border-bottom: 1px solid #EEE; - overflow: hidden; - display: block; - margin: 0px; - } -} - -ul.bordered-list li:last-child { border:none } - .line_holder { &:hover { td { @@ -316,98 +285,6 @@ p.time { } -.ico { - background: url("images.png") no-repeat -85px -77px; - width: 19px; - height: 16px; - float: left; - position: relative; - margin-right: 10px; - top: 8px; - - &.project { - background-position: -37px -77px; - } - - &.activities { - background-position:-162px -22px; - } - &.projects { - background-position:-209px -21px; - } -} - -.leftbar { - h5, .title { - padding: 5px 10px; - } - - h4 { - font-size: 14px; - padding: 2px 10px; - color: #666; - border-bottom: 1px solid #f1f1f1; - } - a:last-child h4 { border: none; } - - a:hover { - h4 { - color: #111; - background: $hover; - border-color: #CCC; - .ico.project { - background-position:-209px -21px; - } - } - } - .bottom { - padding: 10px; - } -} - -.votes { - font-size: 13px; - line-height: 15px; - .progress { - height: 4px; - margin: 0; - .bar { - float: left; - height: 100%; - } - .bar-success { - @include linear-gradient(#62C462, #51A351); - background-color: #468847; - } - .bar-danger { - @include linear-gradient(#EE5F5B, #BD362F); - background-color: #B94A48; - } - } - .upvotes { - display: inline-block; - color: #468847; - } - .downvotes { - display: inline-block; - color: #B94A48; - } -} -.votes-block { - margin: 14px 6px 6px 0; - .downvotes { - float: right; - } -} -.votes-inline { - display: inline-block; - margin: 0 8px; - .progress { - display: inline-block; - padding: 0 0 2px; - width: 45px; - } -} /* Fix for readme code (stopped it from being yellow) */ .readme { @@ -420,7 +297,6 @@ p.time { } } - .highlight_word { background: #EEDC94; } @@ -428,23 +304,16 @@ p.time { .status_info { font-size: 14px; padding: 5px 15px; - line-height: 24px; - width: 60px; + line-height: 26px; text-align: center; - float: left; - margin-right: 20px; + float: right; + position: relative; + top: -5px; + @include border-radius(4px); - &.success { - background: #5BB75B; - color: white; - text-shadow: 0 1px #111; - border-color: #9A9; - } &.error { background: #DA4E49; - border-color: #BD362F; - color: white; - text-shadow: 0 1px #111; + color: #FFF; } } @@ -463,16 +332,6 @@ p.time { height: 150px; } -.gitlab_pagination { - span a { color: $link_color; } - .prev, .next, .current, .page a { - padding: 10px; - } - .current { - border-bottom: 2px solid $style_color; - } -} - // Fixes alignment on notes. .new_note { label { @@ -647,9 +506,14 @@ pre { } } -.milestone .progress { - margin-bottom: 0; - margin-top: 4px; +.milestone { + &.milestone-closed { + background: #eee; + } + .progress { + margin-bottom: 0; + margin-top: 4px; + } } .float-link { diff --git a/app/assets/stylesheets/gitlab_bootstrap.scss b/app/assets/stylesheets/gitlab_bootstrap.scss new file mode 100644 index 00000000000..f53e0e50bab --- /dev/null +++ b/app/assets/stylesheets/gitlab_bootstrap.scss @@ -0,0 +1,26 @@ +/** Override bootstrap variables **/ +$baseFontSize: 13px !default; +$baseLineHeight: 18px !default; + +// BOOTSTRAP +@import "bootstrap"; +@import "bootstrap/responsive-utilities"; +@import "bootstrap/responsive-1200px-min"; + +@import "font-awesome"; + +/** + * GitLab bootstrap. + * Overrides some styles of twitter bootstrap. + * Also give some common classes for GitLab app + */ +@import "gitlab_bootstrap/variables.scss"; +@import "gitlab_bootstrap/fonts.scss"; +@import "gitlab_bootstrap/mixins.scss"; +@import "gitlab_bootstrap/common.scss"; +@import "gitlab_bootstrap/typography.scss"; +@import "gitlab_bootstrap/buttons.scss"; +@import "gitlab_bootstrap/blocks.scss"; +@import "gitlab_bootstrap/files.scss"; +@import "gitlab_bootstrap/tables.scss"; +@import "gitlab_bootstrap/lists.scss"; diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss index ecd6cf7e4e8..f9c8b7b05ea 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss @@ -31,6 +31,7 @@ .middle_box_content, .bottom_box_content { padding: 15px; + word-wrap: break-word; pre { background: none !important; @@ -40,6 +41,15 @@ } } + .top_box_content { + .box-title { + color: $style_color; + font-size: 18px; + font-weight: normal; + line-height: 28px; + } + } + .middle_box_content { @include border-radius(0); border: none; @@ -64,7 +74,7 @@ border: 1px solid #eaeaea; @include border-radius(4px); - + border-color: #CCC; @include solid-shade; @@ -83,6 +93,10 @@ border-top: 1px solid #eaeaea; border-bottom: 1px solid #bbb; + > a { + text-shadow: 0 1px 1px #fff; + } + &.small { line-height: 28px; font-size: 14px; @@ -138,19 +152,6 @@ } } - li, .wll { - padding: 10px; - &:first-child { - @include border-radius(4px 4px 0 0); - border-top: none; - } - - &:last-child { - @include border-radius(0 0 4px 4px); - border: none; - } - } - .ui-box-body { padding: 10px; } diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss index 9a4f2e80f87..3bb7cdbf706 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss @@ -10,11 +10,6 @@ /** COMMON CLASSES **/ .left { float:left } .right { float:right!important } -.width-50p { width:50% } -.width-49p { width:49% } -.width-30p { width:30% } -.width-65p { width:65% } -.width-100p { width:100% } .append-bottom-10 { margin-bottom:10px } .append-bottom-20 { margin-bottom:20px } .prepend-top-10 { margin-top:10px } @@ -30,6 +25,7 @@ .borders { border: 1px solid #ccc; @include shade; } .hint { font-style: italic; color: #999; } .light { color: #888 } +.tiny { font-weight: normal } /** PILLS & TABS**/ .nav-pills a:hover { background-color: #888; } @@ -99,18 +95,21 @@ input[type='search'].search-text-input { border: 1px solid #ccc; } -fieldset legend { font-size: 17px; } - -ul.nav.nav-projects-tabs { - @extend .nav-tabs; +input[type='text'].danger { + background: #F2DEDE!important; + border-color: #D66; + text-shadow: 0 1px 1px #fff +} - padding-left: 8px; +fieldset legend { font-size: 17px; } - li { - a { - padding: 4px 20px; - margin-top: 2px; - border-color: #DDD; - } +/** PAGINATION **/ +.gitlab_pagination { + span a { color: $link_color; } + .prev, .next, .current, .page a { + padding: 10px; + } + .current { + border-bottom: 2px solid $style_color; } } diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/gitlab_bootstrap/files.scss index e4924a49456..83954da525a 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/files.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/files.scss @@ -43,11 +43,15 @@ padding: 0 4px; } padding: 20px; - h1, h2 { - line-height: 46px; - } - h3, h4 { - line-height: 40px; + + h1 { font-size: 26px; line-height: 46px; } + h2 { font-size: 22px; line-height: 42px; } + h3 { font-size: 20px; line-height: 40px; } + h4 { font-size: 18px; line-height: 32px; } + h5 { font-size: 16px; line-height: 26px; } + + .white .highlight pre { + background: #f5f5f5; } } diff --git a/app/assets/stylesheets/fonts.scss b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss index 88c966d18f7..88c966d18f7 100644 --- a/app/assets/stylesheets/fonts.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss index 5bd087b080e..edaf3cef2cf 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss @@ -1,23 +1,38 @@ -/** LISTS **/ - -ul { - /** - * List li block element #1 - * - */ - .wll { +/** + * Well styled list + * + */ +.well-list { + margin: 0; + list-style: none; + li { background-color: #FFF; - padding: 10px 5px; + padding: 10px; min-height: 20px; border-bottom: 1px solid #eee; border-bottom: 1px solid rgba(0, 0, 0, 0.05); + &.disabled { + color: #888; + } + &.smoke { background-color: #f5f5f5; } + &:hover { background: $hover; border-bottom: 1px solid #ADF; } - &:last-child { border:none } + + &:first-child { + @include border-radius(4px 4px 0 0); + border-top: none; + } + + &:last-child { + @include border-radius(0 0 4px 4px); + border: none; + } + .author { color: #999; } p { @@ -29,6 +44,11 @@ ul { top: 3px; } } + + .well-title { + font-size: 14px; + line-height: 18px; + } } } @@ -39,3 +59,17 @@ ol, ul { } } } + +/** light list with border-bottom between li **/ +ul.bordered-list { + margin: 5px 0px; + padding: 0px; + li { + padding: 5px 0; + border-bottom: 1px solid #EEE; + overflow: hidden; + display: block; + margin: 0px; + &:last-child { border:none } + } +} diff --git a/app/assets/stylesheets/mixins.scss b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss index 441a85f3410..81830368c4c 100644 --- a/app/assets/stylesheets/mixins.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss @@ -57,4 +57,13 @@ @mixin solid-shade { @include box-shadow(0 0 0 3px #f1f1f1); -}
\ No newline at end of file +} + +@mixin header-font { + color: $style_color; + text-shadow: 0 1px 1px #FFF; + font-family: 'Korolev', sans-serif; + font-size: 28px; + line-height: 48px; + font-weight: normal; +} diff --git a/app/assets/stylesheets/variables.scss b/app/assets/stylesheets/gitlab_bootstrap/variables.scss index ba78c8351f4..869eb168c0d 100644 --- a/app/assets/stylesheets/variables.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/variables.scss @@ -2,4 +2,4 @@ $primary_color: #2FA0BB; $link_color: #3A89A3; $style_color: #474D57; -$hover: #D9EDF7;
\ No newline at end of file +$hover: #D9EDF7; diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index 4196ea7ad29..6018ff7074d 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -1,7 +1,8 @@ .black .highlight { + background-color: #333; pre { - background-color: #333; color: #eee; + background: inherit; } .hll { display: block; background-color: darken($hover, 65%) } diff --git a/app/assets/stylesheets/jquery.ui.gitlab.css b/app/assets/stylesheets/jquery.ui.gitlab.css index 171857657b6..5c51600ba67 100644 --- a/app/assets/stylesheets/jquery.ui.gitlab.css +++ b/app/assets/stylesheets/jquery.ui.gitlab.css @@ -1,27 +1,3 @@ -/* - * jQuery UI CSS Framework 1.8.7 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } -/* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -/* end clearfix */ -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - /* Interaction Cues ----------------------------------*/ .ui-state-disabled { cursor: default !important; } @@ -141,26 +117,6 @@ .ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } /* - * jQuery UI Resizable 1.8.7 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute; font-size: 0.1px; z-index: 999; display: block;} -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;} -/* * jQuery UI Selectable 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) @@ -240,34 +196,7 @@ cursor: pointer; font-weight: bold; } -/* - * jQuery UI Slider 1.8.7 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; background: #d7d7d7; z-index: 1; } -.ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; } -.ui-slider .ui-slider-handle { background: url(slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } -.ui-slider .ui-state-hover, .ui-slider .ui-state-active { background-position: 0 0; } -.ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } -.ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; } - -.ui-slider-horizontal { height: 5px; } -.ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: 5px; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; } /* * jQuery UI Datepicker 1.8.7 * @@ -326,45 +255,3 @@ .ui-datepicker table .ui-state-highlight { border-color: #ADE; } .ui-datepicker-calendar .ui-state-default { background: transparent; border-color: #FFF; } .ui-datepicker-calendar .ui-state-active { background: #D9EDF7; border-color: #ADE; color: #3A89A3; font-weight: bold; text-shadow: 0 1px 1px #fff; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; } - - -/* Extra Input Field Styling */ -.ui-form textarea, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]) { - padding: 3px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - border: 1px solid #cecece; - outline: none; - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2); - box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2); - -webkit-transition: all 250ms ease-in-out; - -moz-transition: all 250ms ease-in-out; - -o-transition: all 250ms ease-in-out; - transition: all 250ms ease-in-out; -} -.ui-form textarea:hover, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):hover { - border: 1px solid #bdbdbd; - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2); - box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2); -} -.ui-form textarea:focus, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):focus { - border: 1px solid #95bdd4; - -webkit-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2); - -moz-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2); - box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2); -} diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss deleted file mode 100644 index 98d755219d9..00000000000 --- a/app/assets/stylesheets/main.scss +++ /dev/null @@ -1,144 +0,0 @@ -/** Override bootstrap variables **/ -$baseFontSize: 13px !default; -$baseLineHeight: 18px !default; - -// BOOTSTRAP -@import "bootstrap"; -@import "bootstrap/responsive-utilities"; -@import "bootstrap/responsive-1200px-min"; - -// FONT AWESOME -@import "font-awesome"; - -/** - * Variables - * Contains colors - */ -@import "variables.scss"; - -/** - * Custom fonts - * Contains @font-face font Korolev and default $monotype - */ -@import "fonts.scss"; - -/** - * General mixins. - * Contains rounded borders, gradients and shades - */ -@import "mixins.scss"; - -/** - * Header of application. - * Contain application logo, search panel, profile icon - */ -@import "sections/header.scss"; - -/** - * Navigation menu of application. - * Panel with links to pages depends on project, profile or admin area - */ -@import "sections/nav.scss"; - -/** - * This file represent some UI that can be changed - * during web app restyle or theme select. - * - * Next items should be placed there - * - link, button colors - * - header restyles - * - main menu restyles - * - */ -@import "themes/ui_basic.scss"; - -/** - * UI themes: - */ -@import "themes/ui_mars.scss"; -@import "themes/ui_modern.scss"; -@import "themes/ui_gray.scss"; -@import "themes/ui_color.scss"; - -/** - * GitLab bootstrap. - * Overrides some styles of twitter bootstrap. - * Also give some common classes for GitLab app - */ -@import "gitlab_bootstrap/common.scss"; -@import "gitlab_bootstrap/typography.scss"; -@import "gitlab_bootstrap/buttons.scss"; -@import "gitlab_bootstrap/blocks.scss"; -@import "gitlab_bootstrap/files.scss"; -@import "gitlab_bootstrap/tables.scss"; -@import "gitlab_bootstrap/lists.scss"; - - -/** - * Most of application styles placed here. - * This file represent common UI that should not be changed between themes - * or project restyling like form width or user avatar class or commit title - * - * TODO: clean it - */ -@import "common.scss"; - -/** - * Styles necessary to support JS behaviours. - */ -@import "behaviors.scss"; - -/** - * Styles related to specific part of app - */ -@import "sections/commits.scss"; -@import "sections/issues.scss"; -@import "sections/projects.scss"; -@import "sections/merge_requests.scss"; -@import "sections/graph.scss"; -@import "sections/events.scss"; -@import "sections/themes.scss"; - -/** - * This scss file redefine chozen selectbox styles for - * project Branch/Tag select element - */ -@import "ref_select.scss"; - -/** - * Code (files list) styles. Browsing project files there - */ -@import "sections/tree.scss"; - -/** - * This file represent notes(comments) styles - */ -@import "sections/notes.scss"; - -/** - * This file represent profile styles - */ -@import "sections/profile.scss"; - -/** - * Devise styles - */ -@import "sections/login.scss"; - -/** - * CODE HIGHTLIGHT BASE - * - */ -@import "highlight/white.scss"; - -/** - * CODE HIGHTLIGHT DARK schema - * - */ -@import "highlight/dark.scss"; - -/** - * File Editor styles - * - */ -@import "sections/editor.scss"; diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index b96e460c4f3..1cae7b0c6b1 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -232,8 +232,6 @@ /** COMMIT ROW **/ .commit { - @extend .wll; - .browse_code_link_holder { @extend .span2; float: right; @@ -305,3 +303,17 @@ color: #fff; font-family: $monospace; } + + +.commits-compare-switch{ + background: url("switch_icon.png") no-repeat center center; + width: 16px; + height: 18px; + text-indent: -9999px; + float: left; + margin-right: 9px; + border: 1px solid #DDD; + @include border-radius(4px); + padding: 4px; + background-color: #EEE; +} diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 28551d9a6ee..071a9c35468 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -31,7 +31,6 @@ * */ .event-item { - min-height: 40px; border-bottom: 1px solid #eee; .event-title { color: #333; @@ -50,14 +49,18 @@ } } .avatar { - width: 32px; + position: relative; + top: -3px; } .event_icon { + position: relative; float: right; border: 1px solid #EEE; padding: 5px; @include border-radius(5px); background: #F9F9F9; + margin-left: 10px; + top: -6px; img { width: 20px; } @@ -71,9 +74,8 @@ } } - padding: 15px 5px; + padding: 16px 5px; &:last-child { border:none } - .wll:hover { background:none } .event_commits { margin-top: 5px; diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index 4171c00ab8b..c1b210be1ab 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -44,14 +44,9 @@ header { background: url('logo_dark.png') no-repeat 0px 2px; float: left; margin-left: 2px; - font-size: 30px; - line-height: 48px; - font-weight: normal; - color: $style_color; - text-shadow: 0 1px 1px #FFF; padding-left: 45px; height: 40px; - font-family: 'Korolev', sans-serif; + @include header-font; } } } @@ -66,12 +61,7 @@ header { float: left; margin: 0; margin-right: 30px; - font-size: 30px; - line-height: 48px; - font-weight: normal; - color: $style_color; - text-shadow: 0 1px 1px #FFF; - font-family: 'Korolev', sans-serif; + @include header-font; } /** @@ -172,7 +162,7 @@ header { display: none; z-index: 100000; @include border-radius(4px); - width: 100px; + width: 130px; position: absolute; right: 5px; top: 38px; @@ -181,7 +171,7 @@ header { box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); a { color: #fff; - padding: 7px 10px; + padding: 12px 15px; display: block; text-shadow: none; border-bottom: 1px solid #666; @@ -204,8 +194,8 @@ header { } &:last-child { @include border-radius(0 0 5px 5px); - border-bottom: 0; - } + border-bottom: 0; + } } diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss index ef3821f23ef..fd995728978 100644 --- a/app/assets/stylesheets/sections/issues.scss +++ b/app/assets/stylesheets/sections/issues.scss @@ -121,12 +121,3 @@ input.check_all_issues { #update_status { width: 100px; } - - -/** - * Milestones list - * - */ -.milestone { - @extend .wll; -} diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index a5ec1756e5f..4808117d02a 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -136,9 +136,3 @@ li.merge_request { } } } - -.status-badge { - height: 32px; - width: 100%; - @include border-radius(5px); -} diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss index 595568fc059..bc19bc75a67 100644 --- a/app/assets/stylesheets/sections/nav.scss +++ b/app/assets/stylesheets/sections/nav.scss @@ -3,15 +3,13 @@ * */ ul.main_menu { - @include border-radius(4px); margin: auto; margin: 30px 0; - border: 1px solid #BBB; + margin-top: 10px; + border-bottom: 1px solid #DDD; height: 37px; - @include bg-gray-gradient; position: relative; overflow: hidden; - @include shade; .count { position: relative; top: -1px; @@ -24,9 +22,6 @@ ul.main_menu { line-height: 14px; text-align: center; color: #777; - background: #f2f2f2; - border-top: 1px solid #CCC; - @include border-radius(8px); } .label { background: $hover; @@ -38,23 +33,10 @@ ul.main_menu { margin: 0; display: table-cell; width: 1%; - border-right: 1px solid #DDD; - border-left: 1px solid #EEE; - border-bottom: 2px solid #CFCFCF; - - &:first-child{ - @include border-radius(5px 0 0 5px); - border-left: 0; - } - &.active { - background-color: #D5D5D5; - border-right: 1px solid #BBB; - border-left: 1px solid #BBB; - @include border-radius(0 0 1px 1px); - &:first-child{ - border-bottom: none; - border-left: none; + border-bottom: 2px solid #474D57; + a { + color: $style_color; } } @@ -73,10 +55,10 @@ ul.main_menu { a { display: block; text-align: center; - font-weight: bold; + font-weight: normal; height: 35px; line-height: 36px; - color: $style_color; + color: #777; text-shadow: 0 1px 1px white; padding: 0 10px; } diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index a230f296700..717f85024cc 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -4,12 +4,11 @@ } .side { - @extend .span4; @extend .right; .groups_box, .projects_box { - h5 { + > h5 { color: $style_color; font-size: 16px; text-shadow: 0 1px 1px #fff; @@ -17,37 +16,22 @@ line-height: 32px; font-size: 14px; } - ul { - li { - padding: 0; - a { - display: block; - .group_name { - font-size: 14px; - line-height: 18px; - } - .project_name { - color: #4fa2bd; - font-size: 14px; - line-height: 18px; - } - .arrow { - float: right; - padding: 10px; - margin: 0; - } - .last_activity { - padding-top: 5px; - display: block; - span, strong { - font-size: 12px; - color: #666; - } - } + .nav-projects-tabs li { padding: 0; } + .well-list { + .arrow { + float: right; + padding: 10px; + margin: 0; + } + .last_activity { + padding-top: 5px; + display: block; + span, strong { + font-size: 12px; + color: #666; } } } - @extend .leftbar; @extend .ui-box; } } @@ -117,3 +101,25 @@ } } + +ul.nav.nav-projects-tabs { + @extend .nav-tabs; + + padding-left: 8px; + + li { + a { + padding: 4px 20px; + margin-top: 2px; + border-color: #DDD; + background-color: #EEE; + text-shadow: 0 1px 1px white; + color: #555; + } + &.active { + a { + font-weight: bold; + } + } + } +} diff --git a/app/assets/stylesheets/sections/snippets.scss b/app/assets/stylesheets/sections/snippets.scss new file mode 100644 index 00000000000..3944814fc3e --- /dev/null +++ b/app/assets/stylesheets/sections/snippets.scss @@ -0,0 +1,9 @@ +.snippet.file_holder { + .file_title { + .snippet-file-name { + position: relative; + top: -4px; + left: -4px; + } + } +} diff --git a/app/assets/stylesheets/sections/votes.scss b/app/assets/stylesheets/sections/votes.scss new file mode 100644 index 00000000000..4686f5422dc --- /dev/null +++ b/app/assets/stylesheets/sections/votes.scss @@ -0,0 +1,43 @@ +.votes { + font-size: 13px; + line-height: 15px; + .progress { + height: 4px; + margin: 0; + .bar { + float: left; + height: 100%; + } + .bar-success { + @include linear-gradient(#62C462, #51A351); + background-color: #468847; + } + .bar-danger { + @include linear-gradient(#EE5F5B, #BD362F); + background-color: #B94A48; + } + } + .upvotes { + display: inline-block; + color: #468847; + } + .downvotes { + display: inline-block; + color: #B94A48; + } +} +.votes-block { + margin: 14px 6px 6px 0; + .downvotes { + float: right; + } +} +.votes-inline { + display: inline-block; + margin: 0 8px; + .progress { + display: inline-block; + padding: 0 0 2px; + width: 45px; + } +} diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss index fee179899ce..b377727779a 100644 --- a/app/assets/stylesheets/themes/ui_basic.scss +++ b/app/assets/stylesheets/themes/ui_basic.scss @@ -4,18 +4,6 @@ * */ .ui_basic { - /* - * Common styles - * - */ - a { - color: $link_color; - &:hover { - text-decoration: none; - color: $primary_color; - } - } - .app_logo { .separator { margin-left: 0; diff --git a/app/contexts/project_update_context.rb b/app/contexts/project_update_context.rb index e28d43d0e81..5b77d0a7964 100644 --- a/app/contexts/project_update_context.rb +++ b/app/contexts/project_update_context.rb @@ -2,7 +2,9 @@ class ProjectUpdateContext < BaseContext def execute(role = :default) namespace_id = params[:project].delete(:namespace_id) - if namespace_id.present? + allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin + + if allowed_transfer && namespace_id.present? if namespace_id == Namespace.global_id if project.namespace.present? # Transfer to global namespace from anyone diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 8a0a9e9b245..a492e66611f 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -2,7 +2,7 @@ class Admin::GroupsController < AdminController before_filter :group, only: [:edit, :show, :update, :destroy, :project_update] def index - @groups = Group.scoped + @groups = Group.order('name ASC') @groups = @groups.search(params[:name]) if params[:name].present? @groups = @groups.page(params[:page]).per(20) end @@ -11,6 +11,7 @@ class Admin::GroupsController < AdminController @projects = Project.scoped @projects = @projects.not_in_group(@group) if @group.projects.present? @projects = @projects.all + @projects.reject!(&:empty_repo?) end def new diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index e61f94f8cf3..4fea8709b70 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -4,12 +4,13 @@ class Admin::ProjectsController < AdminController def index @projects = Project.scoped @projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present? + @projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id @projects = @projects.search(params[:name]) if params[:name].present? @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20) end def show - @users = User.scoped + @users = User.active @users = @users.not_in_project(@project) if @project.users.present? @users = @users.all end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 744b1912a6c..5f259bd7e27 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -3,7 +3,7 @@ class Admin::UsersController < AdminController @admin_users = User.scoped @admin_users = @admin_users.filter(params[:filter]) @admin_users = @admin_users.search(params[:name]) if params[:name].present? - @admin_users = @admin_users.order("updated_at DESC").page(params[:page]) + @admin_users = @admin_users.order("name ASC").page(params[:page]) end def show @@ -30,7 +30,7 @@ class Admin::UsersController < AdminController def new - @admin_user = User.new({ projects_limit: Gitlab.config.default_projects_limit }, as: :admin) + @admin_user = User.new({ projects_limit: Gitlab.config.gitlab.default_projects_limit }, as: :admin) end def edit diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5735c1d2916..75cd8f15605 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -112,6 +112,10 @@ class ApplicationController < ActionController::Base render file: Rails.root.join("public", "404"), layout: false, status: "404" end + def render_403 + render file: Rails.root.join("public", "403"), layout: false, status: "403" + end + def require_non_empty_project redirect_to @project if @project.empty_repo? end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 461dd51b570..1fcadbfefba 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -7,6 +7,8 @@ class DashboardController < ApplicationController def index @groups = current_user.authorized_groups + @has_authorized_projects = @projects.count > 0 + @projects = case params[:scope] when 'personal' then @projects.personal(current_user) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 93c495363d9..c82edb4c168 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -21,7 +21,7 @@ class GroupsController < ApplicationController # Get authored or assigned open merge requests def merge_requests - @merge_requests = current_user.cared_merge_requests + @merge_requests = current_user.cared_merge_requests.opened @merge_requests = @merge_requests.of_group(@group).recent.page(params[:page]).per(20) end @@ -49,6 +49,7 @@ class GroupsController < ApplicationController def people @project = group.projects.find(params[:project_id]) if params[:project_id] @users = @project ? @project.users : group.users + @users.sort_by!(&:name) if @project @team_member = @project.users_projects.new diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 443763cd2dd..9917d198cbf 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,6 +1,6 @@ class IssuesController < ProjectResourceController before_filter :module_enabled - before_filter :issue, only: [:edit, :update, :destroy, :show] + before_filter :issue, only: [:edit, :update, :show] # Allow read any issue before_filter :authorize_read_issue! @@ -11,9 +11,6 @@ class IssuesController < ProjectResourceController # Allow modify issue before_filter :authorize_modify_issue!, only: [:edit, :update] - # Allow destroy issue - before_filter :authorize_admin_issue!, only: [:destroy] - respond_to :js, :html def index @@ -79,15 +76,6 @@ class IssuesController < ProjectResourceController end end - def destroy - @issue.destroy - - respond_to do |format| - format.html { redirect_to project_issues_path } - format.js { render nothing: true } - end - end - def sort return render_404 unless can?(current_user, :admin_issue, @project) diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb index 841e8085ed3..355f4d79d67 100644 --- a/app/controllers/merge_requests_controller.rb +++ b/app/controllers/merge_requests_controller.rb @@ -1,6 +1,6 @@ class MergeRequestsController < ProjectResourceController before_filter :module_enabled - before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check] + before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status] before_filter :validates_merge_request, only: [:show, :diffs] before_filter :define_show_vars, only: [:show, :diffs] @@ -13,9 +13,6 @@ class MergeRequestsController < ProjectResourceController # Allow modify merge_request before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] - # Allow destroy merge_request - before_filter :authorize_admin_merge_request!, only: [:destroy] - def index @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute end @@ -90,14 +87,6 @@ class MergeRequestsController < ProjectResourceController end end - def destroy - @merge_request.destroy - - respond_to do |format| - format.html { redirect_to project_merge_requests_url(@project) } - end - end - def branch_from @commit = project.commit(params[:ref]) @commit = CommitDecorator.decorate(@commit) @@ -108,6 +97,13 @@ class MergeRequestsController < ProjectResourceController @commit = CommitDecorator.decorate(@commit) end + def ci_status + status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha) + response = { status: status } + + render json: response + end + protected def merge_request diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb index fadfee2dc06..a0c824e8abb 100644 --- a/app/controllers/milestones_controller.rb +++ b/app/controllers/milestones_controller.rb @@ -12,11 +12,12 @@ class MilestonesController < ProjectResourceController def index @milestones = case params[:f] - when 'all'; @project.milestones - else @project.milestones.active + when 'all'; @project.milestones.order("closed, due_date DESC") + when 'closed'; @project.milestones.closed.order("due_date DESC") + else @project.milestones.active.order("due_date ASC") end - @milestones = @milestones.includes(:project).order("due_date") + @milestones = @milestones.includes(:project) @milestones = @milestones.page(params[:page]).per(20) end @@ -42,6 +43,7 @@ class MilestonesController < ProjectResourceController def create @milestone = @project.milestones.new(params[:milestone]) + @milestone.author_id_of_changes = current_user.id if @milestone.save redirect_to project_milestone_path(@project, @milestone) @@ -51,7 +53,7 @@ class MilestonesController < ProjectResourceController end def update - @milestone.update_attributes(params[:milestone]) + @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id)) respond_to do |format| format.js diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 2fb783b289b..c4ebf0e4889 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -1,5 +1,5 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController - Gitlab.config.omniauth_providers.each do |provider| + Gitlab.config.omniauth.providers.each do |provider| define_method provider['name'] do handle_omniauth end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1165729f9f8..17b0921ba6c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -46,6 +46,10 @@ class ProjectsController < ProjectResourceController format.js end end + + rescue Project::TransferError => ex + @error = ex + render :update_failed end def show @@ -54,12 +58,12 @@ class ProjectsController < ProjectResourceController respond_to do |format| format.html do - unless @project.empty_repo? - @last_push = current_user.recent_push(@project.id) - render :show - else - render "projects/empty" - end + unless @project.empty_repo? + @last_push = current_user.recent_push(@project.id) + render :show + else + render "projects/empty" + end end format.js end @@ -86,12 +90,18 @@ class ProjectsController < ProjectResourceController end def graph - graph = Gitlab::Graph::JsonBuilder.new(project) - - @days_json, @commits_json = graph.days_json, graph.commits_json + respond_to do |format| + format.html + format.json do + graph = Gitlab::Graph::JsonBuilder.new(project) + render :json => graph.to_json + end + end end def destroy + return access_denied! unless can?(current_user, :remove_project, project) + # Disable the UsersProject update_repository call, otherwise it will be # called once for every person removed from the project UsersProject.skip_callback(:destroy, :after, :update_repository) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index b0438222461..977524a4db8 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -16,7 +16,7 @@ class SnippetsController < ProjectResourceController respond_to :html def index - @snippets = @project.snippets + @snippets = @project.snippets.fresh end def new @@ -62,7 +62,7 @@ class SnippetsController < ProjectResourceController redirect_to project_snippets_path(@project) end - def raw + def raw send_data( @snippet.content, type: "text/plain", diff --git a/app/decorators/commit_decorator.rb b/app/decorators/commit_decorator.rb index 69d5b178214..a066b2e4a26 100644 --- a/app/decorators/commit_decorator.rb +++ b/app/decorators/commit_decorator.rb @@ -76,7 +76,7 @@ class CommitDecorator < ApplicationDecorator source_name = send "#{options[:source]}_name".to_sym source_email = send "#{options[:source]}_email".to_sym text = if options[:avatar] - avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size] + avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "" %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>} else source_name diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a689213bcee..52715a265bd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,5 @@ require 'digest/md5' +require 'uri' module ApplicationHelper @@ -30,13 +31,15 @@ module ApplicationHelper args.any? { |v| v.to_s.downcase == action_name } end - def gravatar_icon(user_email = '', size = 40) - if Gitlab.config.disable_gravatar? || user_email.blank? + def gravatar_icon(user_email = '', size = nil) + size = 40 if size.nil? || size <= 0 + + if !Gitlab.config.gravatar.enabled || user_email.blank? 'no_avatar.png' else - gravatar_prefix = request.ssl? ? "https://secure" : "http://www" + gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url user_email.strip! - "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm" + sprintf(gravatar_url, {:hash => Digest::MD5.hexdigest(user_email.downcase), :email => URI.escape(user_email), :size => size}) end end @@ -45,7 +48,7 @@ module ApplicationHelper end def web_app_url - "#{request_protocol}://#{Gitlab.config.web_host}/" + "#{request_protocol}://#{Gitlab.config.gitlab.host}/" end def last_commit(project) @@ -92,6 +95,7 @@ module ApplicationHelper { label: "API Help", url: help_api_path }, { label: "Markdown Help", url: help_markdown_path }, { label: "SSH Keys Help", url: help_ssh_path }, + { label: "Gitlab Rake Tasks Help", url: help_raketasks_path }, ] project_nav = [] diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 99ea9ef2975..2825787fd2f 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -4,28 +4,6 @@ module IssuesHelper project_issues_path project, params end - def link_to_issue_assignee(issue) - project = issue.project - - tm = project.team_member_by_id(issue.assignee_id) - if tm - link_to issue.assignee_name, project_team_member_path(project, tm), class: "author_link" - else - issue.assignee_name - end - end - - def link_to_issue_author(issue) - project = issue.project - - tm = project.team_member_by_id(issue.author_id) - if tm - link_to issue.author_name, project_team_member_path(project, tm), class: "author_link" - else - issue.author_name - end - end - def issue_css_classes issue classes = "issue" classes << " closed" if issue.closed @@ -52,4 +30,14 @@ module IssuesHelper open: "open" } end + + def labels_autocomplete_source + labels = @project.issues_labels.order('count DESC') + labels = labels.map{ |l| { label: l.name, value: l.name } } + labels.to_json + end + + def issues_active_milestones + @project.milestones.active.order("id desc").all + end end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index b23c4a8f0df..f48425bd6de 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -1,26 +1,4 @@ module MergeRequestsHelper - def link_to_merge_request_assignee(merge_request) - project = merge_request.project - - tm = project.team_member_by_id(merge_request.assignee_id) - if tm - link_to merge_request.assignee_name, project_team_member_path(project, tm), class: "author_link" - else - merge_request.assignee_name - end - end - - def link_to_merge_request_author(merge_request) - project = merge_request.project - - tm = project.team_member_by_id(merge_request.author_id) - if tm - link_to merge_request.author_name, project_team_member_path(project, tm), class: "author_link" - else - merge_request.author_name - end - end - def new_mr_path_from_push_event(event) new_project_merge_request_path( event.project, @@ -39,7 +17,7 @@ module MergeRequestsHelper classes end - def ci_status_path - @project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha) + def ci_build_details_path merge_request + merge_request.project.gitlab_ci_service.build_page(merge_request.last_commit.sha) end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 7c302ef4176..425dd471b36 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -8,11 +8,49 @@ module ProjectsHelper end def link_to_project project - link_to project.name, project + link_to project do + title = content_tag(:strong, project.name) + + if project.namespace + namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'tiny') + title = namespace + title + end + + title + end + end + + def link_to_member(project, author) + return "(deleted)" unless author + + # Build avatar image tag + avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av") + + # Build name strong tag + name = content_tag :strong, author.name, class: 'author' + + author_html = avatar + name + + tm = project.team_member_by_id(author) + + content_tag :span, class: 'member-link' do + if tm + link_to author_html, project_team_member_path(project, tm), class: "author_link" + else + author_html + end + end end def tm_path team_member project_team_member_path(@project, team_member) end -end + def project_title project + if project.group + project.name_with_namespace + else + project.name + end + end +end diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index a4bec87caa7..d52d8af6641 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -72,7 +72,7 @@ module TabHelper return "active" if current_page?(controller: "projects", action: action, id: @project) end - if ['snippets', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name + if ['snippets', 'services', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name "active" end end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 29cebadaf94..5cd9b82900c 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -3,11 +3,11 @@ class Notify < ActionMailer::Base add_template_helper ApplicationHelper add_template_helper GitlabMarkdownHelper - default_url_options[:host] = Gitlab.config.web_host - default_url_options[:protocol] = Gitlab.config.web_protocol - default_url_options[:port] = Gitlab.config.web_port if Gitlab.config.web_custom_port? + default_url_options[:host] = Gitlab.config.gitlab.host + default_url_options[:protocol] = Gitlab.config.gitlab.protocol + default_url_options[:port] = Gitlab.config.gitlab.port if Gitlab.config.gitlab_on_non_standard_port? - default from: Gitlab.config.email_from + default from: Gitlab.config.gitlab.email_from @@ -31,6 +31,7 @@ class Notify < ActionMailer::Base def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id) @issue = Issue.find issue_id @issue_status = status + @project = @issue.project @updated_by = User.find updated_by_user_id mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title)) @@ -102,6 +103,12 @@ class Notify < ActionMailer::Base end + def project_was_moved_email(user_project_id) + @users_project = UsersProject.find user_project_id + @project = @users_project.project + mail(to: @users_project.user.email, + subject: subject("project was moved")) + end # # User diff --git a/app/models/ability.rb b/app/models/ability.rb index b09899f17dc..2d80c6720b7 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -17,9 +17,7 @@ class Ability # Rules based on role in project if project.master_access_for?(user) - # TODO: replace with master rules. - # Only allow project administration for namespace owners - rules << project_admin_rules + rules << project_master_rules elsif project.dev_access_for?(user) rules << project_dev_rules @@ -93,13 +91,16 @@ class Ability :admin_merge_request, :admin_note, :accept_mr, - :admin_wiki + :admin_wiki, + :admin_project ] end def project_admin_rules project_master_rules + [ - :admin_project + :change_namespace, + :rename_project, + :remove_project ] end diff --git a/app/models/commit.rb b/app/models/commit.rb index 200c915a335..f11b7fe0202 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -87,14 +87,10 @@ class Commit last = project.commit(from.try(:strip)) if first && last - commits = [first, last].sort_by(&:created_at) - younger = commits.first - older = commits.last - - result[:same] = (younger.id == older.id) - result[:commits] = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)} - result[:diffs] = project.repo.diff(younger.id, older.id) rescue [] - result[:commit] = Commit.new(older) + result[:same] = (first.id == last.id) + result[:commits] = project.repo.commits_between(last.id, first.id).map {|c| Commit.new(c)} + result[:diffs] = project.repo.diff(last.id, first.id) rescue [] + result[:commit] = Commit.new(first) end result @@ -163,6 +159,8 @@ class Commit while !lines.first.start_with?("diff --git") do lines.shift end + lines.pop if lines.last =~ /^[\d.]+$/ # Git version + lines.pop if lines.last == "-- " # end of diff lines.join("\n") end end diff --git a/app/models/event.rb b/app/models/event.rb index 2b92783ceac..90376e73753 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -15,6 +15,7 @@ # class Event < ActiveRecord::Base + include NoteEvent include PushEvent attr_accessible :project, :action, :data, :author_id, :project_id, @@ -58,12 +59,14 @@ class Event < ActiveRecord::Base end end - # Next events currently enabled for system - # - push - # - new issue - # - merge request - def allowed? - push? || issue? || merge_request? || membership_changed? + def proper? + if push? + true + elsif membership_changed? + true + else + (issue? || merge_request? || note? || milestone?) && target + end end def project_name @@ -94,6 +97,14 @@ class Event < ActiveRecord::Base action == self.class::Reopened end + def milestone? + target_type == "Milestone" + end + + def note? + target_type == "Note" + end + def issue? target_type == "Issue" end diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb index 24b70323098..a2f5634a86f 100644 --- a/app/models/gitlab_ci_service.rb +++ b/app/models/gitlab_ci_service.rb @@ -36,4 +36,22 @@ class GitlabCiService < Service def commit_badge_path sha project_url + "/status?sha=#{sha}" end + + def commit_status_path sha + project_url + "/builds/#{sha}/status.json?token=#{token}" + end + + def commit_status sha + response = HTTParty.get(commit_status_path(sha)) + + if response.code == 200 and response["status"] + response["status"] + else + :error + end + end + + def build_page sha + project_url + "/builds/#{sha}" + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 8039813ad1c..052e0850d96 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -204,7 +204,7 @@ class MergeRequest < ActiveRecord::Base def mr_and_commit_notes commit_ids = commits.map(&:id) - Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids) + Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids) end # Returns the raw diff for this merge request @@ -220,4 +220,8 @@ class MergeRequest < ActiveRecord::Base def to_patch project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}") end + + def last_commit_short_sha + @last_commit_short_sha ||= last_commit.sha[0..10] + end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index a50831a2241..4fac9bec259 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -13,18 +13,26 @@ # class Milestone < ActiveRecord::Base - attr_accessible :title, :description, :due_date, :closed + attr_accessible :title, :description, :due_date, :closed, :author_id_of_changes + attr_accessor :author_id_of_changes belongs_to :project has_many :issues has_many :merge_requests + scope :active, where(closed: false) + scope :closed, where(closed: true) + validates :title, presence: true validates :project, presence: true validates :closed, inclusion: { in: [true, false] } - def self.active - where("due_date > ? OR due_date IS NULL", Date.today) + def expired? + if due_date + due_date < Date.today + else + false + end end def participants @@ -52,4 +60,20 @@ class Milestone < ActiveRecord::Base def expires_at "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date end + + def can_be_closed? + open? && issues.opened.count.zero? + end + + def is_empty? + total_items_count.zero? + end + + def open? + !closed + end + + def author_id + author_id_of_changes + end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index e1c24de949a..8c90f5aee26 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -48,23 +48,30 @@ class Namespace < ActiveRecord::Base end def ensure_dir_exist - namespace_dir_path = File.join(Gitlab.config.git_base_path, path) + namespace_dir_path = File.join(Gitlab.config.gitolite.repos_path, path) system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path) end def move_dir if path_changed? - old_path = File.join(Gitlab.config.git_base_path, path_was) - new_path = File.join(Gitlab.config.git_base_path, path) + old_path = File.join(Gitlab.config.gitolite.repos_path, path_was) + new_path = File.join(Gitlab.config.gitolite.repos_path, path) if File.exists?(new_path) raise "Already exists" end - system("mv #{old_path} #{new_path}") + + if system("mv #{old_path} #{new_path}") + send_update_instructions + end end end def rm_dir - dir_path = File.join(Gitlab.config.git_base_path, path) + dir_path = File.join(Gitlab.config.gitolite.repos_path, path) system("rm -rf #{dir_path}") end + + def send_update_instructions + projects.each(&:send_move_instructions) + end end diff --git a/app/models/note.rb b/app/models/note.rb index a8ae9080627..b62b3fe61d5 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -19,7 +19,7 @@ require 'file_size_validator' class Note < ActiveRecord::Base attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id, - :attachment, :line_code + :attachment, :line_code, :commit_id attr_accessor :notify attr_accessor :notify_author @@ -35,10 +35,14 @@ class Note < ActiveRecord::Base validates :line_code, format: { with: /\A\d+_\d+_\d+\Z/ }, allow_blank: true validates :attachment, file_size: { maximum: 10.megabytes.to_i } + validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' } + validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' } + mount_uploader :attachment, AttachmentUploader # Scopes - scope :common, ->{ where(noteable_id: nil) } + scope :for_commits, ->{ where(noteable_type: "Commit") } + scope :common, ->{ where(noteable_id: nil, commit_id: nil) } scope :today, ->{ where("created_at >= :date", date: Date.today) } scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) } scope :since, ->(day) { where("created_at >= :date", date: (day)) } @@ -122,7 +126,7 @@ class Note < ActiveRecord::Base # override to return commits, which are not active record def noteable if for_commit? - project.commit(noteable_id) + project.commit(commit_id) else super end @@ -151,4 +155,12 @@ class Note < ActiveRecord::Base def votable? for_issue? || (for_merge_request? && !for_diff_line?) end + + def noteable_type_name + if noteable_type.present? + noteable_type.downcase + else + "wall" + end + end end diff --git a/app/models/project.rb b/app/models/project.rb index ac315c49f34..251f497548e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -25,6 +25,9 @@ class Project < ActiveRecord::Base include PushObserver include Authority include Team + include NamespacedProject + + class TransferError < StandardError; end attr_accessible :name, :path, :description, :default_branch, :issues_enabled, :wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin] @@ -36,6 +39,10 @@ class Project < ActiveRecord::Base # Relations belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'" belongs_to :namespace + + # TODO: replace owner with creator. + # With namespaces a project owner will be a namespace owner + # so this field makes sense only for global projects belongs_to :owner, class_name: "User" has_many :users, through: :users_projects has_many :events, dependent: :destroy @@ -97,7 +104,7 @@ class Project < ActiveRecord::Base namespace_id = Namespace.find_by_path(id.first).id where(namespace_id: namespace_id).find_by_path(id.last) else - find_by_path(id) + where(path: id, namespace_id: nil).last end end @@ -172,7 +179,7 @@ class Project < ActiveRecord::Base end def repo_name - denied_paths = %w(gitolite-admin groups projects dashboard) + denied_paths = %w(gitolite-admin admin dashboard groups help profile projects search) if denied_paths.include?(path) errors.add(:path, "like #{path} is not allowed") @@ -188,7 +195,7 @@ class Project < ActiveRecord::Base end def web_url - [Gitlab.config.url, path].join("/") + [Gitlab.config.gitlab.url, path_with_namespace].join("/") end def common_notes @@ -196,15 +203,15 @@ class Project < ActiveRecord::Base end def build_commit_note(commit) - notes.new(noteable_id: commit.id, noteable_type: "Commit") + notes.new(commit_id: commit.id, noteable_type: "Commit") end def commit_notes(commit) - notes.where(noteable_id: commit.id, noteable_type: "Commit").where('line_code IS NULL OR line_code = ""') + notes.where(commit_id: commit.id, noteable_type: "Commit").where('line_code IS NULL OR line_code = ""') end def commit_line_notes(commit) - notes.where(noteable_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL") + notes.where(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL") end def public? @@ -239,51 +246,11 @@ class Project < ActiveRecord::Base gitlab_ci_service && gitlab_ci_service.active end - def path_with_namespace - if namespace - namespace.path + '/' + path - else - path - end - end - # For compatibility with old code def code path end - def transfer(new_namespace) - Project.transaction do - old_namespace = namespace - self.namespace = new_namespace - - old_dir = old_namespace.try(:path) || '' - new_dir = new_namespace.try(:path) || '' - - old_repo = if old_dir.present? - File.join(old_dir, self.path) - else - self.path - end - - Gitlab::ProjectMover.new(self, old_dir, new_dir).execute - - git_host.move_repository(old_repo, self) - - save! - end - end - - def name_with_namespace - @name_with_namespace ||= begin - if namespace - namespace.human_name + " / " + name - else - name - end - end - end - def items_for entity case entity when 'issue' then @@ -293,7 +260,9 @@ class Project < ActiveRecord::Base end end - def namespace_owner - namespace.try(:owner) + def send_move_instructions + self.users_projects.each do |member| + Notify.project_was_moved_email(member.id).deliver + end end end diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 997c19bdb6b..8d7eb788abb 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -22,7 +22,7 @@ class Snippet < ActiveRecord::Base belongs_to :author, class_name: "User" has_many :notes, as: :noteable, dependent: :destroy - delegate :name, :email, to: :author, prefix: true + delegate :name, :email, to: :author, prefix: true, allow_nil: true validates :author, presence: true validates :project, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index 3f2d7c92ea8..1bc070f040d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -56,12 +56,12 @@ class User < ActiveRecord::Base has_many :issues, foreign_key: :author_id, dependent: :destroy has_many :notes, foreign_key: :author_id, dependent: :destroy has_many :merge_requests, foreign_key: :author_id, dependent: :destroy - has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC" has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy + validates :name, presence: true validates :bio, length: { within: 0..255 } validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} @@ -123,16 +123,4 @@ class User < ActiveRecord::Base self.password = self.password_confirmation = Devise.friendly_token.first(8) end end - - def authorized_groups - @authorized_groups ||= begin - groups = Group.where(id: self.projects.pluck(:namespace_id)).all - groups = groups + self.groups - groups.uniq - end - end - - def authorized_projects - Project.authorized_for(self) - end end diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 6231088ff79..3d76a4df037 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -28,6 +28,7 @@ class UsersProject < ActiveRecord::Base validates :user, presence: true validates :user_id, uniqueness: { :scope => [:project_id], message: "already exists in project" } + validates :project_access, inclusion: { in: [GUEST, REPORTER, DEVELOPER, MASTER] }, presence: true validates :project, presence: true delegate :name, :email, to: :user, prefix: true diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb index 48351bac667..c188e5720ac 100644 --- a/app/observers/activity_observer.rb +++ b/app/observers/activity_observer.rb @@ -1,18 +1,27 @@ class ActivityObserver < ActiveRecord::Observer - observe :issue, :merge_request + observe :issue, :merge_request, :note, :milestone def after_create(record) - Event.create( - project: record.project, - target_id: record.id, - target_type: record.class.name, - action: Event.determine_action(record), - author_id: record.author_id - ) + event_author_id = record.author_id + + # Skip status notes + if record.kind_of?(Note) && record.note.include?("_Status changed to ") + return true + end + + if event_author_id + Event.create( + project: record.project, + target_id: record.id, + target_type: record.class.name, + action: Event.determine_action(record), + author_id: event_author_id + ) + end end def after_save(record) - if record.changed.include?("closed") + if record.changed.include?("closed") && record.author_id_of_changes Event.create( project: record.project, target_id: record.id, diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb index 9f9762aea07..131336be8b6 100644 --- a/app/observers/issue_observer.rb +++ b/app/observers/issue_observer.rb @@ -16,7 +16,7 @@ class IssueObserver < ActiveRecord::Observer if status Note.create_status_change_note(issue, current_user, status) [issue.author, issue.assignee].compact.each do |recipient| - Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) + Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id).deliver end end end diff --git a/app/observers/note_observer.rb b/app/observers/note_observer.rb index 083aa7058d5..fe01efcaac2 100644 --- a/app/observers/note_observer.rb +++ b/app/observers/note_observer.rb @@ -21,7 +21,7 @@ class NoteObserver < ActiveRecord::Observer # Notifies the whole team except the author of note def notify_team(note) # Note: wall posts are not "attached" to anything, so fall back to "Wall" - noteable_type = note.noteable_type || "Wall" + noteable_type = note.noteable_type.presence || "Wall" notify_method = "note_#{noteable_type.underscore}_email".to_sym if Notify.respond_to? notify_method diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb index bd41e51e8e4..b1c694569d7 100644 --- a/app/observers/project_observer.rb +++ b/app/observers/project_observer.rb @@ -3,7 +3,8 @@ class ProjectObserver < ActiveRecord::Observer project.update_repository end - def after_save(project) + def after_update(project) + project.send_move_instructions if project.namespace_id_changed? end def after_destroy(project) diff --git a/app/roles/account.rb b/app/roles/account.rb index 8157898fef1..ede12b6056d 100644 --- a/app/roles/account.rb +++ b/app/roles/account.rb @@ -47,7 +47,7 @@ module Account end def cared_merge_requests - MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id).opened + MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id) end def project_ids @@ -105,4 +105,20 @@ module Account def namespace_id namespace.try :id end + + def authorized_groups + @authorized_groups ||= begin + groups = Group.where(id: self.projects.pluck(:namespace_id)).all + groups = groups + self.groups + groups.uniq + end + end + + def authorized_projects + Project.authorized_for(self) + end + + def my_own_projects + Project.personal(self) + end end diff --git a/app/roles/namespaced_project.rb b/app/roles/namespaced_project.rb new file mode 100644 index 00000000000..8656890a456 --- /dev/null +++ b/app/roles/namespaced_project.rb @@ -0,0 +1,59 @@ +module NamespacedProject + def transfer(new_namespace) + Project.transaction do + old_namespace = namespace + self.namespace = new_namespace + + old_dir = old_namespace.try(:path) || '' + new_dir = new_namespace.try(:path) || '' + + old_repo = if old_dir.present? + File.join(old_dir, self.path) + else + self.path + end + + if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present? + raise TransferError.new("Project with same path in target namespace already exists") + end + + Gitlab::ProjectMover.new(self, old_dir, new_dir).execute + + git_host.move_repository(old_repo, self) + + save! + end + rescue Gitlab::ProjectMover::ProjectMoveError => ex + raise TransferError.new(ex.message) + end + + def name_with_namespace + @name_with_namespace ||= begin + if namespace + namespace.human_name + " / " + name + else + name + end + end + end + + def namespace_owner + namespace.try(:owner) + end + + def chief + if namespace + namespace_owner + else + owner + end + end + + def path_with_namespace + if namespace + namespace.path + '/' + path + else + path + end + end +end diff --git a/app/roles/note_event.rb b/app/roles/note_event.rb new file mode 100644 index 00000000000..db4ced0c095 --- /dev/null +++ b/app/roles/note_event.rb @@ -0,0 +1,37 @@ +module NoteEvent + def note_commit_id + target.commit_id + end + + def note_short_commit_id + note_commit_id[0..8] + end + + def note_commit? + target.noteable_type == "Commit" + end + + def note_target + target.noteable + end + + def note_target_id + if note_commit? + target.commit_id + else + target.noteable_id.to_s + end + end + + def wall_note? + target.noteable_type.blank? + end + + def note_target_type + if target.noteable_type.present? + target.noteable_type.titleize + else + "Wall" + end.downcase + end +end diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb index c5c5203d7a6..dda18267207 100644 --- a/app/roles/push_observer.rb +++ b/app/roles/push_observer.rb @@ -114,7 +114,7 @@ module PushObserver id: commit.id, message: commit.safe_message, timestamp: commit.date.xmlschema, - url: "#{Gitlab.config.url}/#{path}/commits/#{commit.id}", + url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}", author: { name: commit.author_name, email: commit.author_email diff --git a/app/roles/repository.rb b/app/roles/repository.rb index 74cae5c8d5d..78190ca96d0 100644 --- a/app/roles/repository.rb +++ b/app/roles/repository.rb @@ -45,8 +45,22 @@ module Repository end def has_post_receive_file? - hook_file = File.join(path_to_repo, 'hooks', 'post-receive') - File.exists?(hook_file) + !!hook_file + end + + def valid_post_receive_file? + valid_hook_file == hook_file + end + + def valid_hook_file + @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive')) + end + + def hook_file + @hook_file ||= begin + hook_path = File.join(path_to_repo, 'hooks', 'post-receive') + File.read(hook_path) if File.exists?(hook_path) + end end # Returns an Array of branch names @@ -83,7 +97,7 @@ module Repository end def path_to_repo - File.join(Gitlab.config.git_base_path, "#{path_with_namespace}.git") + File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git") end def namespace_dir @@ -185,7 +199,7 @@ module Repository end def http_url_to_repo - http_url = [Gitlab.config.url, "/", path_with_namespace, ".git"].join('') + http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('') end # Check if current branch name is marked as protected in the system diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml deleted file mode 100644 index 67516eb26e3..00000000000 --- a/app/views/admin/groups/_form.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= form_for [:admin, @group] do |f| - - if @group.errors.any? - .alert-message.block-message.error - %span= @group.errors.full_messages.first - .clearfix.group_name_holder - = f.label :name do - Group name is - .input - = f.text_field :name, placeholder: "Example Group", class: "xxlarge" - - .form-actions - = f.submit 'Save group', class: "btn save-btn" diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml index 9904122c789..901d07e74f3 100644 --- a/app/views/admin/groups/edit.html.haml +++ b/app/views/admin/groups/edit.html.haml @@ -1,3 +1,28 @@ -%h3.page_title Edit Group -%br -= render 'form' +%h3.page_title Rename Group +%hr += form_for [:admin, @group] do |f| + - if @group.errors.any? + .alert-message.block-message.error + %span= @group.errors.full_messages.first + .clearfix.group_name_holder + = f.label :name do + Group name is + .input + = f.text_field :name, placeholder: "Example Group", class: "xxlarge" + + + + .clearfix.group_name_holder + = f.label :path do + %span.cred Group path is + .input + = f.text_field :path, placeholder: "example-group", class: "xxlarge danger" + %ul.cred + %li Changing group path can have unintended side effects. + %li Renaming group path will rename directory for all related projects + %li It will change web url for access group and group projects. + %li It will change the git path to repositories under this group. + + .form-actions + = f.submit 'Rename group', class: "btn danger" + = link_to 'Cancel', admin_groups_path, class: "btn cancel-btn" diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 952d515103c..49acedc8c79 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -12,17 +12,24 @@ %table %thead - %th Name - %th Path - %th Projects - %th Edit - %th.cred Danger Zone! + %tr + %th + Name + %i.icon-sort-down + %th Path + %th Projects + %th Owner + %th.cred Danger Zone! - @groups.each do |group| %tr - %td= link_to group.name, [:admin, group] + %td + %strong= link_to group.name, [:admin, group] %td= group.path %td= group.projects.count - %td= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small" - %td.bgred= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger" + %td + = link_to group.owner_name, admin_user_path(group.owner_id) + %td.bgred + = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small" + = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger" = paginate @groups, theme: "admin" diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index d371acadd15..41f6d9b3516 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -1,8 +1,5 @@ %h3.page_title Group: #{@group.name} - = link_to edit_admin_group_path(@group), class: "btn right" do - %i.icon-edit - Edit %br %table.zebra-striped @@ -16,36 +13,64 @@ Name: %td = @group.name + + = link_to edit_admin_group_path(@group), class: "btn btn-small right" do + %i.icon-edit + Rename %tr %td %b Path: %td - %span.monospace= File.join(Gitlab.config.git_base_path, @group.path) + %span.monospace= File.join(Gitlab.config.gitolite.repos_path, @group.path) %tr %td %b Owner: %td = @group.owner_name -.ui-box - %h5 - Projects - %small - (#{@group.projects.count}) - %ul.unstyled + .right + = link_to "#", class: "btn btn-small change-owner-link" do + %i.icon-edit + Change owner + + %tr.change-owner-holder.hide + %td.bgred + %b.cred + New Owner: + %td.bgred + = form_for [:admin, @group] do |f| + = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'} + %div + = f.submit 'Change Owner', class: "btn danger" + = link_to "Cancel", "#", class: "btn change-owner-cancel-link" +%fieldset + %legend Projects (#{@group.projects.count}) + %table + %thead + %tr + %th Project name + %th Path + %th Users + %th.cred Danger Zone! - @group.projects.each do |project| - %li.wll - %strong - = link_to project.name, [:admin, project] - .right - = link_to 'Remove from group', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Are you sure?', method: :delete, class: "btn danger small" - .clearfix + %tr + %td + = link_to project.name_with_namespace, [:admin, project] + %td + %span.monospace= project.path_with_namespace + ".git" + %td= project.users.count + %td.bgred + = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" = form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do %fieldset %legend Move projects to group + .alert + You can move only projects with existing repos + %br + Group projects will be moved in group directory and will not be accessible by old path .clearfix = label_tag :project_ids do Projects @@ -53,3 +78,17 @@ = select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' .form-actions = submit_tag 'Add', class: "btn primary" + +:javascript + $(function(){ + var modal = $('.change-owner-holder'); + $('.change-owner-link').bind("click", function(){ + $(this).hide(); + modal.show(); + }); + $('.change-owner-cancel-link').bind("click", function(){ + modal.hide(); + $('.change-owner-link').show(); + }) + }) + diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml index e33c5468555..25644d6321a 100644 --- a/app/views/admin/logs/show.html.haml +++ b/app/views/admin/logs/show.html.haml @@ -3,6 +3,8 @@ = link_to "githost.log", "#githost", 'data-toggle' => 'tab' %li = link_to "application.log", "#application", 'data-toggle' => 'tab' + %li + = link_to "production.log", "#production", 'data-toggle' => 'tab' %p.light To prevent perfomance issues admin logs output the last 2000 lines .tab-content @@ -34,3 +36,17 @@ - Gitlab::AppLogger.read_latest.each do |line| %li %p= line + .tab-pane#production + .file_holder#README + .file_title + %i.icon-file + production.log + .right + = link_to '#', class: 'log-bottom' do + %i.icon-arrow-down + Scroll down + .file_content.logs + %ol + - Gitlab::Logger.read_latest_for('production.log').each do |line| + %li + %p= line diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml index e515c68c382..27c22872d50 100644 --- a/app/views/admin/projects/_form.html.haml +++ b/app/views/admin/projects/_form.html.haml @@ -19,40 +19,47 @@ .input = text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true - - unless project.new_record? + - if project.repo_exists? .clearfix - = f.label :namespace_id - .input= f.select :namespace_id, namespaces_options(@project.namespace_id), {}, {class: 'chosen'} + = f.label :default_branch, "Default Branch" + .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;") - - if project.repo_exists? - .clearfix - = f.label :default_branch, "Default Branch" - .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;") + %fieldset.adv_settings + %legend Features: - - unless project.new_record? - %fieldset.adv_settings - %legend Features: + .clearfix + = f.label :issues_enabled, "Issues" + .input= f.check_box :issues_enabled - .clearfix - = f.label :issues_enabled, "Issues" - .input= f.check_box :issues_enabled + .clearfix + = f.label :merge_requests_enabled, "Merge Requests" + .input= f.check_box :merge_requests_enabled - .clearfix - = f.label :merge_requests_enabled, "Merge Requests" - .input= f.check_box :merge_requests_enabled + .clearfix + = f.label :wall_enabled, "Wall" + .input= f.check_box :wall_enabled - .clearfix - = f.label :wall_enabled, "Wall" - .input= f.check_box :wall_enabled + .clearfix + = f.label :wiki_enabled, "Wiki" + .input= f.check_box :wiki_enabled + + %fieldset.features + %legend Transfer: + .control-group + = f.label :namespace_id do + %span Namespace + .controls + = f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'} + %br + %ul.prepend-top-10.cred + %li Be careful. Changing project namespace can have unintended side effects + %li You can transfer project only to namespaces you can manage + %li You will need to update your local repositories to point to the new location. - .clearfix - = f.label :wiki_enabled, "Wiki" - .input= f.check_box :wiki_enabled - - unless project.new_record? - .actions - = f.submit 'Save Project', class: "btn save-btn" - = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn" + .actions + = f.submit 'Save Project', class: "btn save-btn" + = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn" diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 9bbcbc71111..310cfa53890 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,5 +1,5 @@ %h3.page_title - Projects + Projects (#{@projects.count}) = link_to 'New Project', new_project_path, class: "btn small right" %br = form_tag admin_projects_path, method: :get, class: 'form-inline' do @@ -9,12 +9,15 @@ %table %thead - %th Name - %th Path - %th Team Members - %th Last Commit - %th Edit - %th.cred Danger Zone! + %tr + %th + Name + %i.icon-sort-down + %th Path + %th Team Members + %th Last Commit + %th Edit + %th.cred Danger Zone! - @projects.each do |project| %tr diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 47185308f41..634b1836754 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -4,14 +4,24 @@ %i.icon-edit Edit -- if !@project.has_post_receive_file? && @project.has_commits? - %br - .alert.alert-error - %span - %strong Important! - Project has commits but missing post-receive file. - %br - If you exported project manually - copy post-receive hook to bare repository +- if @project.has_commits? + - if !@project.has_post_receive_file? + %br + .alert.alert-error + %span + %strong Project has commits but missing post-receive file. + %br + If you exported project manually - make a link of post-receive hook file from gitolite to project repository + - elsif !@project.valid_post_receive_file? + %br + .alert.alert-error + %span + %strong Project has invalid post-receive file. + %br + 1. Make sure your gitolite instace has latest post-receive file. + %br + 2. Make a link of post-receive hook file from gitolite to project repository + %br %table.zebra-striped @@ -37,9 +47,12 @@ %tr %td %b - Path: + Owned by: %td - %code= @project.path_to_repo + - if @project.chief + = link_to @project.chief.name, admin_user_path(@project.chief) + - else + (deleted) %tr %td %b @@ -49,11 +62,48 @@ %tr %td %b + Created at: + %td + = @project.created_at.stamp("March 1, 1999") + +%table.zebra-striped + %thead + %tr + %th Repository + %th + %tr + %td + %b + FS Path: + %td + %code= @project.path_to_repo + %tr + %td + %b + Smart HTTP: + %td + = link_to @project.http_url_to_repo + %tr + %td + %b + SSH: + %td + = link_to @project.ssh_url_to_repo + %tr + %td + %b + Last commit at: + %td + = last_commit(@project) + %tr + %td + %b Post Receive File: %td = check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true + %br -%h3 +%h5 Team %small (#{@project.users_projects.count}) @@ -75,7 +125,7 @@ %td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small" %br -%h3 Add new team member +%h5 Add new team member %br = form_tag team_update_admin_project_path(@project), class: "bulk_import", method: :put do %table.zebra-striped diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 5d0f6fe1153..1df4f590bcb 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -1,5 +1,5 @@ %h3.page_title - Users + Users (#{@admin_users.count}) = link_to 'New User', new_admin_user_path, class: "btn small right" %br @@ -21,13 +21,16 @@ %table %thead - %th Admin - %th Name - %th Username - %th Email - %th Projects - %th Edit - %th.cred Danger Zone! + %tr + %th Admin + %th + Name + %i.icon-sort-down + %th Username + %th Email + %th Projects + %th Edit + %th.cred Danger Zone! - @admin_users.each do |user| %tr @@ -38,10 +41,13 @@ %td= user.users_projects.count %td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small" %td.bgred - - if user.blocked - = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success" + - if user == current_user + %span.cred It's you! - else - = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger" - = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn small danger" + - if user.blocked + = 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" + = 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" diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 6a42f787bab..852aead79e2 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -40,6 +40,12 @@ %tr %td %b + Created at: + %td + = @admin_user.created_at.stamp("March 1, 1999") + %tr + %td + %b Projects limit: %td = @admin_user.projects_limit @@ -66,7 +72,7 @@ = @admin_user.twitter %br -%h3 Add User to Projects +%h5 Add User to Projects %br = form_tag team_update_admin_user_path(@admin_user), class: "bulk_import", method: :put do %table @@ -76,7 +82,7 @@ %th Project Access: %tr - %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' + %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' %td= select_tag :project_access, options_for_select(Project.access_options), class: "project-access-select chosen span3" %tr @@ -86,8 +92,22 @@ %strong= link_to "here", help_permissions_path, class: "vlink" %br +- if @admin_user.groups.present? + %h5 Owner of groups: + %br + + %table.zebra-striped + %thead + %tr + %th Name + + - @admin_user.groups.each do |group| + %tr + %td= link_to group.name, admin_group_path(group) + + - if @admin_user.projects.present? - %h3 Projects + %h5 Projects: %br %table.zebra-striped @@ -101,7 +121,7 @@ - @admin_user.users_projects.each do |tm| - project = tm.project %tr - %td= link_to project.name, admin_project_path(project) + %td= link_to project.name_with_namespace, admin_project_path(project) %td= tm.project_access_human %td= link_to 'Edit Access', edit_admin_team_member_path(tm), class: "btn small" %td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn small danger" diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml index c3c7d49ce74..c9217989884 100644 --- a/app/views/commits/_commits.html.haml +++ b/app/views/commits/_commits.html.haml @@ -3,4 +3,4 @@ %h5.small %i.icon-calendar = day.stamp("28 Aug, 2010") - %ul.unstyled= render commits + %ul.well-list= render commits diff --git a/app/views/compare/_form.html.haml b/app/views/compare/_form.html.haml index 07f1c818e4d..7e3a2a0e1f5 100644 --- a/app/views/compare/_form.html.haml +++ b/app/views/compare/_form.html.haml @@ -1,23 +1,30 @@ %div - %p.slead - Fill input field with commit id like - %code.label_branch 4eedf23 - or branch/tag name like - %code.label_branch master - and press compare button for commits list, code diff. + - unless params[:to] + %p.slead + Fill input field with commit id like + %code.label_branch 4eedf23 + or branch/tag name like + %code.label_branch master + and press compare button for commits list, code diff. - %br + %br = form_tag project_compare_index_path(@project), method: :post do .clearfix - = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge" - = "..." - = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge" + .pull-left + - if params[:to] && params[:from] + = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} + = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge" + = "..." + = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge" + .pull-left + + = submit_tag "Compare", class: "btn primary wide commits-compare-btn" - if @refs_are_same .alert %span Refs are the same - .actions - = submit_tag "Compare", class: "btn primary wide commits-compare-btn" + + :javascript $(function() { diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml index 528c8b44af4..2abbd3fc0ee 100644 --- a/app/views/compare/show.html.haml +++ b/app/views/compare/show.html.haml @@ -9,7 +9,7 @@ - if @commits.present? %div.ui-box %h5.small Commits (#{@commits.count}) - %ul.unstyled= render @commits + %ul.well-list= render @commits - unless @diffs.empty? %h4 Diff diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml new file mode 100644 index 00000000000..c63ef24fca5 --- /dev/null +++ b/app/views/dashboard/_activities.html.haml @@ -0,0 +1,13 @@ += render "events/event_last_push", event: @last_push + +.event_filter + = event_filter_link EventFilter.push, 'Push events' + = event_filter_link EventFilter.merged, 'Merge events' + = event_filter_link EventFilter.comments, 'Comments' + = event_filter_link EventFilter.team, 'Team' + +- if @events.any? + .content_list= render @events +- else + %p.nothing_here_message Projects activity will be displayed here +.loading.hide diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml index 8f66742098a..9e3401e51b8 100644 --- a/app/views/dashboard/_groups.html.haml +++ b/app/views/dashboard/_groups.html.haml @@ -8,11 +8,11 @@ = link_to new_admin_group_path, class: "btn very_small info" do %i.icon-plus New Group - %ul.unstyled + %ul.well-list - groups.each do |group| - %li.wll + %li = link_to group_path(id: group.path), class: dom_class(group) do - %strong.group_name= truncate(group.name, length: 25) + %strong.well-title= truncate(group.name, length: 35) %span.arrow → %span.last_activity diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml index fac0a074691..cffafb5445c 100644 --- a/app/views/dashboard/_projects.html.haml +++ b/app/views/dashboard/_projects.html.haml @@ -16,18 +16,21 @@ = nav_tab :scope, 'joined' do = link_to "Joined", dashboard_path(scope: 'joined') - %ul.unstyled + %ul.well-list - projects.each do |project| - %li.wll + %li = link_to project_path(project), class: dom_class(project) do - if project.namespace = project.namespace.human_name \/ - %strong.project_name + %strong.well-title = truncate(project.name, length: 25) %span.arrow → %span.last_activity %strong Last activity: %span= project_last_activity(project) + - if projects.blank? + %li + %h3.nothing_here_message There are no projects here. .bottom= paginate projects, theme: "gitlab" diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml new file mode 100644 index 00000000000..ca57cd30732 --- /dev/null +++ b/app/views/dashboard/_sidebar.html.haml @@ -0,0 +1,14 @@ +- if @groups.present? + = render "groups", groups: @groups += render "projects", projects: @projects +%div + %span.rss-icon + = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do + = image_tag "rss_ui.png", title: "feed" + %strong News Feed + +%hr +.gitlab-promo + = link_to "Homepage", "http://gitlabhq.com" + = link_to "Blog", "http://blog.gitlabhq.com" + = link_to "@gitlabhq", "https://twitter.com/gitlabhq" diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml new file mode 100644 index 00000000000..d1676ed11fa --- /dev/null +++ b/app/views/dashboard/_zero_authorized_projects.html.haml @@ -0,0 +1,12 @@ +%h3.nothing_here_message + There are no projects you have access to. + %br + - if current_user.can_create_project? + You can create up to + = current_user.projects_limit + projects. Click on button below to add a new one + .link_holder + = link_to new_project_path, class: "btn primary" do + New Project » + - else + If you will be added to project - it will be displayed here diff --git a/app/views/dashboard/index.atom.builder b/app/views/dashboard/index.atom.builder index ffa15258f07..2bb42a65bac 100644 --- a/app/views/dashboard/index.atom.builder +++ b/app/views/dashboard/index.atom.builder @@ -7,7 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| - if event.allowed? + if event.proper? event = EventDecorator.decorate(event) xml.entry do event_link = event.feed_url diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 6b360dc1fef..b64aa86cf73 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -1,50 +1,11 @@ -- if @projects.any? +- if @has_authorized_projects .projects .activities.span8 - = render "events/event_last_push", event: @last_push - - .event_filter - = event_filter_link EventFilter.push, 'Push events' - = event_filter_link EventFilter.merged, 'Merge events' - = event_filter_link EventFilter.comments, 'Comments' - = event_filter_link EventFilter.team, 'Team' - - - if @events.any? - .content_list= render @events - - else - %p.nothing_here_message Projects activity will be displayed here - .loading.hide - .side - - if @groups.present? - = render "groups", groups: @groups - = render "projects", projects: @projects - %div - %span.rss-icon - = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do - = image_tag "rss_ui.png", title: "feed" - %strong News Feed - - %hr - .gitlab-promo - = link_to "Homepage", "http://gitlabhq.com" - = link_to "Blog", "http://blog.gitlabhq.com" - = link_to "@gitlabhq", "https://twitter.com/gitlabhq" - + = render 'activities' + .side.span4 + = render 'sidebar' - else - %h3.nothing_here_message There are no projects you have access to. - %br - %h4.nothing_here_message - - if current_user.can_create_project? - You can create up to - = current_user.projects_limit - projects. Click on button below to add a new one - .link_holder - = link_to new_project_path, class: "btn primary" do - New Project » - - else - If you will be added to project - it will be displayed here - - + = render "zero_authorized_projects" :javascript $(function(){ Pager.init(20); }); diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index e3093bcfe2a..52863229644 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -13,8 +13,8 @@ - @issues.group_by(&:project).each do |group| %div.ui-box - @project = group[0] - %h5= link_to(@project.name, project_path(@project)) - %ul.unstyled.issues_table + %h5= link_to_project @project + %ul.well-list.issues_table - group[1].each do |issue| = render(partial: 'issues/show', locals: {issue: issue}) %hr diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 8454cfdc120..ea7c8c9a3d5 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -10,11 +10,12 @@ .span9 - if @merge_requests.any? - @merge_requests.group_by(&:project).each do |group| - %ul.unstyled.ui-box + .ui-box - @project = group[0] - %h5= @project.name - - group[1].each do |merge_request| - = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request}) + %h5= link_to_project @project + %ul.well-list + - group[1].each do |merge_request| + = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request}) %hr = paginate @merge_requests, theme: "gitlab" diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 38192d7107d..474e7ef746c 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -3,7 +3,7 @@ - else = form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f| = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo" - = f.text_field :email, :class => "text top", :placeholder => "Email" + = f.email_field :email, :class => "text top", :placeholder => "Email", :autofocus => "autofocus" = f.password_field :password, :class => "text bottom", :placeholder => "Password" - if devise_mapping.rememberable? .clearfix.inputs-list diff --git a/app/views/errors/gitolite.html.haml b/app/views/errors/gitolite.html.haml index 2670f2d3fda..590bca71dd4 100644 --- a/app/views/errors/gitolite.html.haml +++ b/app/views/errors/gitolite.html.haml @@ -21,5 +21,5 @@ Permissions: %pre = preserve do - sudo chmod -R 770 #{Gitlab.config.git_base_path} - sudo chown -R git:git #{Gitlab.config.git_base_path} + sudo chown -R git:git #{Gitlab.config.gitolite.repos_path} + sudo chmod -R ug+rwXs #{Gitlab.config.gitolite.repos_path} diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index 2446b764e4d..191aed0747e 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -1,15 +1,15 @@ -- if event.allowed? +- if event.proper? %div.event-item - = event_image(event) + %span.cgray.right + #{time_ago_in_words(event.created_at)} ago. + = image_tag gravatar_icon(event.author_email), class: "avatar s24" - if event.push? = render "events/event/push", event: event + .clearfix + - elsif event.note? + = render "events/event/note", event: event - else = render "events/event/common", event: event - .clearfix - %span.cgray.right - = time_ago_in_words(event.created_at) - ago. - .clearfix diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index e15f1ac063c..b2376019c8e 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -6,7 +6,7 @@ = link_to project_commits_path(event.project, event.ref_name) do %strong= truncate(event.ref_name, length: 28) at - %strong= link_to event.project.name, event.project + %strong= link_to_project event.project %span = time_ago_in_words(event.created_at) ago. diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml new file mode 100644 index 00000000000..8c12969345f --- /dev/null +++ b/app/views/events/event/_note.html.haml @@ -0,0 +1,25 @@ +.event-title + %span.author_name= link_to_author event + %span.event_label commented on #{event.note_target_type} + - if event.note_target + - if event.note_commit? + = link_to event.note_short_commit_id, project_commit_path(event.project, event.note_commit_id), class: "commit_short_id" + - else + = link_to [event.project, event.note_target] do + %strong= truncate event.note_target_id + + - elsif event.wall_note? + -# nothing here + - else + %strong (deleted) + at + - if event.project + = link_to_project event.project + - else + = event.project_name + +.event-body + %span.hint + + %i.icon-comment + = truncate event.target.note, length: 70 diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 869321ed699..119b8e828d0 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -7,12 +7,12 @@ = link_to project_commits_path(event.project, event.ref_name) do %strong= event.ref_name at - %strong= link_to event.project.name, event.project + %strong= link_to_project event.project - if event.push_with_commits? - project = event.project .event-body - %ul.unstyled.event_commits + %ul.well-list.event_commits - few_commits = event.commits[0...2] - few_commits.each do |commit| = render "events/commit", commit: commit, project: project diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml index 39c0b6af685..0b491879fe0 100644 --- a/app/views/groups/_projects.html.haml +++ b/app/views/groups/_projects.html.haml @@ -8,13 +8,13 @@ = link_to new_project_path(namespace_id: @group.id), class: "btn very_small info" do %i.icon-plus New Project - %ul.unstyled + %ul.well-list - if projects.blank? %p.nothing_here_message This groups has no projects yet - projects.each do |project| - %li.wll + %li = link_to project_path(project), class: dom_class(project) do - %strong.project_name= truncate(project.name, length: 25) + %strong.well-title= truncate(project.name, length: 25) %span.arrow → %span.last_activity diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index cc488d57e9e..0daf4d752a8 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -10,7 +10,7 @@ %div.ui-box - @project = group[0] %h5= @project.name - %ul.unstyled.issues_table + %ul.well-list.issues_table - group[1].each do |issue| = render(partial: 'issues/show', locals: {issue: issue}) %hr diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 23a7e7222d7..72aa4ad11e1 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -6,7 +6,7 @@ %br - if @merge_requests.any? - @merge_requests.group_by(&:project).each do |group| - %ul.unstyled.ui-box + %ul.well-list.ui-box - @project = group[0] %h5= @project.name - group[1].each do |merge_request| diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml index 68102b6a85a..be3dd7a4d78 100644 --- a/app/views/groups/people.html.haml +++ b/app/views/groups/people.html.haml @@ -9,9 +9,9 @@ Team %small (#{@users.size}) - %ul.unstyled + %ul.well-list - @users.each do |user| - %li.wll + %li = image_tag gravatar_icon(user.email, 16), class: "avatar s16" %strong= user.name %span.cgray= user.email diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder index fa3bfade28b..9aa52ea5593 100644 --- a/app/views/groups/show.atom.builder +++ b/app/views/groups/show.atom.builder @@ -7,7 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| - if event.allowed? + if event.proper? event = EventDecorator.decorate(event) xml.entry do event_link = event.feed_url diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index b929b267e8b..76bc2639d61 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -11,7 +11,7 @@ - else %p.nothing_here_message Projects activity will be displayed here .loading.hide - .side + .side.span4 = render "projects", projects: @projects %div %span.rss-icon diff --git a/app/views/help/permissions.html.haml b/app/views/help/permissions.html.haml index f9287fa0996..c9ec701add7 100644 --- a/app/views/help/permissions.html.haml +++ b/app/views/help/permissions.html.haml @@ -4,61 +4,66 @@ ← to index %hr -.row - .ui-box.span2 - %h5 Guest - %ul.unstyled - %li Create new issue - %li Leave comments - %li Write on project wall +%fieldset + %legend Guest + %ul + %li Create new issue + %li Leave comments + %li Write on project wall - .ui-box.span3 - %h5 Reporter - %ul.unstyled - %li Create new issue - %li Leave comments - %li Write on project wall - %li Pull project code - %li Download project - %li Create new merge request - %li Create a code snippets +%fieldset + %legend Reporter + %ul + %li Create new issue + %li Leave comments + %li Write on project wall + %li Pull project code + %li Download project + %li Create new merge request + %li Create a code snippets - .ui-box.span3 - %h5 Developer - %ul.unstyled - %li Create new issue - %li Leave comments - %li Write on project wall - %li Pull project code - %li Download project - %li Create new merge request - %li Create a code snippets - %li Create new branches - %li Push to non-protected branches - %li Remove non-protected branches - %li Add tags - %li Write a wiki +%fieldset + %legend Developer + %ul + %li Create new issue + %li Leave comments + %li Write on project wall + %li Pull project code + %li Download project + %li Create new merge request + %li Create a code snippets + %li Create new branches + %li Push to non-protected branches + %li Remove non-protected branches + %li Add tags + %li Write a wiki - .ui-box.span3 - %h5 Master - %ul.unstyled - %li Create new issue - %li Leave comments - %li Write on project wall - %li Pull project code - %li Download project - %li Create new merge request - %li Create a code snippets - %li Create new branches - %li Push to non-protected branches - %li Remove non-protected branches - %li Add tags - %li Write a wiki - %li Add new team members - %li Push to protected branches - %li Remove protected branches - %li Push with force option - %li Edit project - %li Add Deploy Keys to project - %li Configure Project Hooks +%fieldset + %legend Master + %ul + %li Create new issue + %li Leave comments + %li Write on project wall + %li Pull project code + %li Download project + %li Create new merge request + %li Create a code snippets + %li Create new branches + %li Push to non-protected branches + %li Remove non-protected branches + %li Add tags + %li Write a wiki + %li Add new team members + %li Push to protected branches + %li Remove protected branches + %li Push with force option + %li Edit project + %li Add Deploy Keys to project + %li Configure Project Hooks + +%fieldset + %legend Owner + %ul + %li Transfer project to another namespace + %li Remove project diff --git a/app/views/hooks/index.html.haml b/app/views/hooks/index.html.haml index 1b59c8e81ab..6a36c749123 100644 --- a/app/views/hooks/index.html.haml +++ b/app/views/hooks/index.html.haml @@ -22,22 +22,21 @@ %hr -if @hooks.any? - %h3 - Hooks - %small (#{@hooks.count}) + %h3.page_title + Hooks (#{@hooks.count}) %br %table %thead %tr %th URL - %th Method %th - @hooks.each do |hook| %tr %td + %span.badge.badge-info POST = link_to project_hook_path(@project, hook) do %strong= hook.url - = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small right" - %td POST %td - = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right" + .right + = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small grouped" + = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small grouped" diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml index 670b4e059f4..030f797c088 100644 --- a/app/views/issues/_form.html.haml +++ b/app/views/issues/_form.html.haml @@ -1,18 +1,18 @@ %div.issue-form-holder %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}" - = form_for [@project, @issue], remote: request.xhr? do |f| + = form_for [@project, @issue] do |f| -if @issue.errors.any? .alert-message.block-message.error - %ul - - @issue.errors.full_messages.each do |msg| - %li= msg + - @issue.errors.full_messages.each do |msg| + %span= msg + %br .issue_form_box .issue_title .clearfix = f.label :title do %strong= "Subject *" .input - = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true + = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true .issue_middle_block .issue_assignee = f.label :assignee_id do @@ -47,11 +47,38 @@ -else = f.submit 'Save changes', class: "save-btn btn" - - cancel_class = 'btn cancel-btn' - - if request.xhr? - = link_to "Cancel", "#back", onclick: "backToIssues();", class: cancel_class - - else - - if @issue.new_record? - = link_to "Cancel", project_issues_path(@project), class: cancel_class - - else - = link_to "Cancel", project_issue_path(@project, @issue), class: cancel_class + - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue) + = link_to "Cancel", cancel_path, class: 'btn cancel-btn' + + + + +:javascript + $(function(){ + $("#issue_label_list") + .bind( "keydown", function( event ) { + if ( event.keyCode === $.ui.keyCode.TAB && + $( this ).data( "autocomplete" ).menu.active ) { + event.preventDefault(); + } + }) + .autocomplete({ + minLength: 0, + source: function( request, response ) { + response( $.ui.autocomplete.filter( + #{raw labels_autocomplete_source}, extractLast( request.term ) ) ); + }, + focus: function() { + return false; + }, + select: function(event, ui) { + var terms = split( this.value ); + terms.pop(); + terms.push( ui.item.value ); + terms.push( "" ); + this.value = terms.join( ", " ); + return false; + } + }); + }); + diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml index f82ae8bde58..d7ba4300ce7 100644 --- a/app/views/issues/_issues.html.haml +++ b/app/views/issues/_issues.html.haml @@ -6,7 +6,7 @@ .row .span7= paginate @issues, remote: true, theme: "gitlab" .span3.right - %span.cgray.right + %span.cgray.right %span.issue_counter #{@issues.total_count} issues for this filter - else diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml index 8aa92ebfd6a..4641e8bdc63 100644 --- a/app/views/issues/_show.html.haml +++ b/app/views/issues/_show.html.haml @@ -1,4 +1,4 @@ -%li.wll{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) } +%li{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) } - if controller.controller_name == 'issues' .issue_check = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue) @@ -16,7 +16,7 @@ = 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 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true - = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped", remote: true do + = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped" do %i.icon-edit Edit @@ -28,7 +28,7 @@ %p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title" %span.update-author - %small.cdark= "##{issue.id}" + %span.cdark= "##{issue.id}" - if issue.assignee assigned to #{issue.assignee_name} - else diff --git a/app/views/issues/create.js.haml b/app/views/issues/create.js.haml deleted file mode 100644 index d90cbf0d30c..00000000000 --- a/app/views/issues/create.js.haml +++ /dev/null @@ -1,10 +0,0 @@ -- if @issue.valid? - :plain - switchFromNewIssue(); - $("#issues-table").prepend("#{escape_javascript(render(partial: 'show', locals: {issue: @issue}))}"); - $.ajax({type: "GET", url: location.href, dataType: "script"}); -- else - :plain - $("#new_issue_dialog").empty(); - $("#new_issue_dialog").append("#{escape_javascript(render('form'))}"); - $('select#issue_assignee_id').chosen(); diff --git a/app/views/issues/edit.js.haml b/app/views/issues/edit.js.haml deleted file mode 100644 index a994572f9b9..00000000000 --- a/app/views/issues/edit.js.haml +++ /dev/null @@ -1,4 +0,0 @@ -:plain - $("#edit_issue_dialog").html("#{escape_javascript(render('form'))}"); - switchToEditIssue(); - diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml index d89b183d360..08d4393b201 100644 --- a/app/views/issues/index.html.haml +++ b/app/views/issues/index.html.haml @@ -6,7 +6,7 @@ .right .span5 - if can? current_user, :write_issue, @project - = link_to new_project_issue_path(@project), class: "right btn", title: "New Issue", remote: true, id: "new_issue_link" do + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "right btn", title: "New Issue", id: "new_issue_link" do %i.icon-plus New Issue = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do @@ -27,7 +27,7 @@ .left = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status") = select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") - = select_tag('update[milestone_id]', options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") + = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone") = hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag :f, params[:f] = button_tag "Save", class: "btn update_selected_issues" @@ -51,16 +51,13 @@ = form_tag project_issues_path(@project), method: :get, class: :right do = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels") = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") - = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") + = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone") = hidden_field_tag :f, params[:f] .clearfix - %ul#issues-table.unstyled.issues_table + %ul#issues-table.well-list.issues_table = render "issues" -#new_issue_dialog -#edit_issue_dialog - :javascript $(function(){ issuesPage(); diff --git a/app/views/issues/new.js.haml b/app/views/issues/new.js.haml deleted file mode 100644 index 4cbcc563e28..00000000000 --- a/app/views/issues/new.js.haml +++ /dev/null @@ -1,3 +0,0 @@ -:plain - $("#new_issue_dialog").html("#{escape_javascript(render('form'))}"); - switchToNewIssue(); diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 3d3164fed20..b1014edc6c5 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -26,22 +26,16 @@ .main_box .top_box_content - %h4 + %h4.box-title - if @issue.closed - .alert-message.error.status_info Closed - - else - .alert-message.success.status_info Open + .error.status_info Closed = gfm escape_once(@issue.title) .middle_box_content - %cite.cgray Created by - = image_tag gravatar_icon(@issue.author_email), width: 16, class: "lil_av" - %strong.author= link_to_issue_author(@issue) - - - if @issue.assignee - %cite.cgray and currently assigned to - = image_tag gravatar_icon(@issue.assignee_email), width: 16, class: "lil_av" - %strong.author= link_to_issue_assignee(@issue) + %cite.cgray + Created by #{link_to_member(@project, @issue.author)} + - if @issue.assignee + \ and currently assigned to #{link_to_member(@project, @issue.assignee)} - if @issue.milestone - milestone = @issue.milestone diff --git a/app/views/issues/update.js.haml b/app/views/issues/update.js.haml index 44722895025..7f66022a2de 100644 --- a/app/views/issues/update.js.haml +++ b/app/views/issues/update.js.haml @@ -2,13 +2,3 @@ - if @issue.valid? :plain $("##{dom_id(@issue)}").fadeOut(); -- else - - if @issue.valid? - :plain - updatePage(); - switchFromEditIssue(); - - else - :plain - $("#edit_issue_dialog").empty(); - $("#edit_issue_dialog").append("#{escape_javascript(render('form'))}"); - $('select#issue_assignee_id').chosen(); diff --git a/app/views/kaminari/admin/_gap.html.haml b/app/views/kaminari/admin/_gap.html.haml index f82f185ac35..3ffd12f8587 100644 --- a/app/views/kaminari/admin/_gap.html.haml +++ b/app/views/kaminari/admin/_gap.html.haml @@ -4,5 +4,6 @@ -# num_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote -%span.page.gap - = raw(t 'views.pagination.truncate') +%li{class: "page"} + %span.page.gap + = raw(t 'views.pagination.truncate') diff --git a/app/views/labels/_label.html.haml b/app/views/labels/_label.html.haml index 8a465a9e02c..6e223e8e61d 100644 --- a/app/views/labels/_label.html.haml +++ b/app/views/labels/_label.html.haml @@ -1,4 +1,4 @@ -%li.wll +%li %strong %i.icon-tag = label.name diff --git a/app/views/labels/index.html.haml b/app/views/labels/index.html.haml index 4e41d375d6a..6eb2c00e56d 100644 --- a/app/views/labels/index.html.haml +++ b/app/views/labels/index.html.haml @@ -4,7 +4,7 @@ Labels %br %div.ui-box - %ul.unstyled.labels-table + %ul.well-list.labels-table - @labels.each do |label| = render 'label', label: label diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 7b2a291d05c..8f8c7d8885e 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -1,6 +1,6 @@ :javascript $(function() { - GitLab.GfmAutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.path}/members" if @project }"; + GitLab.GfmAutoComplete.Members.url = "#{ "/api/v3/projects/#{@project.id}/members" if @project }"; GitLab.GfmAutoComplete.Members.params.private_token = "#{current_user.private_token}"; GitLab.GfmAutoComplete.Emoji.data = #{raw emoji_autocomplete_source}; diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 35bf5577e1c..c418e1dbc68 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -3,14 +3,7 @@ %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"} %title GitLab - :css - .header h1 {color: #BBBBBB !important; font: bold 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;} - .header p {color: #c6c6c6; font: normal 12px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 18px;} - .content h2 {color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; } - .content p {color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif;} - .content a {color: #0eb6ce; text-decoration: none;} - .footer p {font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;} - .footer a {color: #0eb6ce; text-decoration: none;} + %body{bgcolor: "#EAEAEA", style: "margin: 0; padding: 0; background: #EAEAEA"} %table{align: "center", border: "0", cellpadding: "0", cellspacing: "0", style: "padding: 35px 0; background: #EAEAEA;", width: "100%"} %tr @@ -19,11 +12,11 @@ %tr %td{style: "font-size: 0px;", width: "20"} \ - %td{align: "left", style: "padding: 18px 0 10px;", width: "580"} - %h1{style: "color: #BBBBBB; font: normal 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"} + %td{align: "left", style: "padding: 10px 0", width: "580"} + %h1{style: "font-size: 24px; color: #BBBBBB; font: normal 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"} GITLAB - if @project - | #{@project.name} + → #{@project.name_with_namespace} %table{align: "center", bgcolor: "#fff", border: "0", cellpadding: "0", cellspacing: "0", style: "font-family: Helvetica, Arial, sans-serif; background: #fff;", width: "600"} %tr= yield %tr @@ -35,5 +28,5 @@ %p{style: "font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;"} You're receiving this notification because you are a member of the - if @project - #{@project.name} + #{@project.name_with_namespace} project team. diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml index ab8e88c07cd..709807456c8 100644 --- a/app/views/layouts/project_resource.html.haml +++ b/app/views/layouts/project_resource.html.haml @@ -1,9 +1,9 @@ !!! 5 %html{ lang: "en"} - = render "layouts/head", title: @project.name + = render "layouts/head", title: @project.name_with_namespace %body{class: "#{app_theme} project"} = render "layouts/flash" - = render "layouts/head_panel", title: @project.name + = render "layouts/head_panel", title: project_title(@project) - if can?(current_user, :download_code, @project) = render 'shared/no_ssh' .container diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml index 302e75cfb00..9606e2e53b3 100644 --- a/app/views/merge_requests/_form.html.haml +++ b/app/views/merge_requests/_form.html.haml @@ -32,7 +32,7 @@ .top_box_content = f.label :title do %strong= "Title *" - .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5 + .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true .merge_requests_middle_box .merge_requests_assignee = f.label :assignee_id do diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml index 4f68c5f2620..7369f3dd061 100644 --- a/app/views/merge_requests/_merge_request.html.haml +++ b/app/views/merge_requests/_merge_request.html.haml @@ -1,4 +1,4 @@ -%li.wll{ class: mr_css_classes(merge_request) } +%li{ class: mr_css_classes(merge_request) } .right .left - if merge_request.merged? diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml index 138f65105f7..8285a56d184 100644 --- a/app/views/merge_requests/_show.html.haml +++ b/app/views/merge_requests/_show.html.haml @@ -2,6 +2,8 @@ = render "merge_requests/show/how_to_merge" = render "merge_requests/show/mr_box" = render "merge_requests/show/mr_accept" +- if @project.gitlab_ci? + = render "merge_requests/show/mr_ci" = render "merge_requests/show/commits" - if @commits.present? @@ -26,6 +28,8 @@ MergeRequest.init({ url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}", check_enable: #{@merge_request.state == MergeRequest::UNCHECKED ? "true" : "false"}, + url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", + ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, current_state: "#{@merge_request.human_state}", action: "#{controller.action_name}" }); diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml index 7bcb7a81e1a..5b234bfbe02 100644 --- a/app/views/merge_requests/index.html.haml +++ b/app/views/merge_requests/index.html.haml @@ -30,7 +30,7 @@ = hidden_field_tag :f, params[:f] .clearfix - %ul.unstyled + %ul.well-list = render @merge_requests - if @merge_requests.blank? %li diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml index d25e707c64e..796922776d9 100644 --- a/app/views/merge_requests/show/_commits.html.haml +++ b/app/views/merge_requests/show/_commits.html.haml @@ -5,19 +5,19 @@ Commits (#{@commits.count}) .merge-request-commits - if @commits.count > 8 - %ul.first_mr_commits.unstyled + %ul.first_mr_commits.well-list - @commits.first(8).each do |commit| = render "commits/commit", commit: commit %li.bottom 8 of #{@commits.count} commits displayed. %strong %a.mr_show_all_commits Click here to show all - %ul.all_mr_commits.hide.unstyled + %ul.all_mr_commits.hide.well-list - @commits.each do |commit| = render "commits/commit", commit: commit - else - %ul.unstyled + %ul.well-list - @commits.each do |commit| = render "commits/commit", commit: commit diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml index b4b4be2980a..cd33732d191 100644 --- a/app/views/merge_requests/show/_mr_box.html.haml +++ b/app/views/merge_requests/show/_mr_box.html.haml @@ -1,25 +1,20 @@ .main_box .top_box_content - %h4 - - if @merge_request.closed - .alert-message.error.status_info Closed - - else - .alert-message.success.status_info Open + %h4.box-title + - if @merge_request.merged + .error.status_info + %i.icon-ok + Merged + - elsif @merge_request.closed + .error.status_info Closed = gfm escape_once(@merge_request.title) - - if @project.gitlab_ci? - .right - = image_tag ci_status_path, class: 'status-badge' .middle_box_content %div - %cite.cgray Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by - = image_tag gravatar_icon(@merge_request.author_email), width: 16, class: "lil_av" - %strong.author= link_to_merge_request_author(@merge_request) - - - if @merge_request.assignee - %cite.cgray , currently assigned to - = image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av" - %strong.author= link_to_merge_request_assignee(@merge_request) + %cite.cgray + Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by #{link_to_member(@project, @merge_request.author)} + - if @merge_request.assignee + \, currently assigned to #{link_to_member(@project, @merge_request.assignee)} - if @merge_request.milestone - milestone = @merge_request.milestone %cite.cgray and attached to milestone @@ -30,10 +25,10 @@ .bottom_box_content - if @merge_request.merged? %span - Merged by #{@merge_request.merge_event.author_name} + Merged by #{link_to_member(@project, @merge_request.merge_event.author)} %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago. - elsif @merge_request.closed_event %span - Closed by #{@merge_request.closed_event.author_name} + Closed by #{link_to_member(@project, @merge_request.closed_event.author)} %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago. diff --git a/app/views/merge_requests/show/_mr_ci.html.haml b/app/views/merge_requests/show/_mr_ci.html.haml new file mode 100644 index 00000000000..d46b606ef7f --- /dev/null +++ b/app/views/merge_requests/show/_mr_ci.html.haml @@ -0,0 +1,35 @@ +- if @merge_request.open? && @commits.any? + .ci_widget.ci-success{style: "display:none"} + .alert.alert-success + %i.icon-ok + %strong CI build passed + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + + .ci_widget.ci-failed{style: "display:none"} + .alert.alert-error + %i.icon-remove + %strong CI build failed + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + - [:running, :pending].each do |status| + .ci_widget{class: "ci-#{status}", style: "display:none"} + .alert + %i.icon-time + %strong CI build #{status} + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + .ci_widget + .alert-message + %strong + %i.icon-refresh + Checking for CI status for #{@merge_request.last_commit_short_sha} + + .ci_widget.ci-error{style: "display:none"} + .alert.alert-error + %i.icon-remove + %strong Cannot connect to CI server. Please check your setting + diff --git a/app/views/merge_requests/show/_mr_title.html.haml b/app/views/merge_requests/show/_mr_title.html.haml index a5275650d86..c2ffe8e3770 100644 --- a/app/views/merge_requests/show/_mr_title.html.haml +++ b/app/views/merge_requests/show/_mr_title.html.haml @@ -6,11 +6,6 @@ %span.label_branch= @merge_request.target_branch %span.right - - if @merge_request.merged? - %span.btn.small.disabled.grouped - %strong - %i.icon-ok - = "MERGED" - if can?(current_user, :modify_merge_request, @merge_request) - if @merge_request.open? .left.btn-group diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 7c4c0e67d7c..3864792f7e8 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -1,22 +1,27 @@ -%li{class: "milestone", id: dom_id(milestone) } +%li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) } .right - - if can? current_user, :admin_milestone, milestone.project + - if can?(current_user, :admin_milestone, milestone.project) and milestone.open? = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do %i.icon-edit Edit %h4 = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) + - if milestone.expired? and not milestone.closed + %span.cred (Expired) %small = milestone.expires_at - .row - .span4 - .progress.progress-info - .bar{style: "width: #{milestone.percent_complete}%;"} - .span6 - = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do - = pluralize milestone.issues.count, 'Issue' - - = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do - = pluralize milestone.merge_requests.count, 'Merge Request' - - %span.light #{milestone.percent_complete}% complete + - if milestone.is_empty? + %span.muted Empty + - else + .row + .span4 + .progress.progress-info + .bar{style: "width: #{milestone.percent_complete}%;"} + .span6 + = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.issues.count, 'Issue' + + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.merge_requests.count, 'Merge Request' + + %span.light #{milestone.percent_complete}% complete diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml index c5333b08fdc..3089595fe0b 100644 --- a/app/views/milestones/index.html.haml +++ b/app/views/milestones/index.html.haml @@ -11,15 +11,18 @@ %li{class: ("active" if (params[:f] == "active" || !params[:f]))} = link_to project_milestones_path(@project, f: "active") do Active + %li{class: ("active" if params[:f] == "closed")} + = link_to project_milestones_path(@project, f: "closed") do + Closed %li{class: ("active" if params[:f] == "all")} = link_to project_milestones_path(@project, f: "all") do All - %ul.unstyled + %ul.well-list = render @milestones - if @milestones.present? - %li.bottom= paginate @milestones, remote: true, theme: "gitlab" + %li.bottom= paginate @milestones, theme: "gitlab" - else %li %h3.nothing_here_message Nothing to show here diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml index b8bc788c953..c4975c72ef2 100644 --- a/app/views/milestones/show.html.haml +++ b/app/views/milestones/show.html.haml @@ -1,31 +1,41 @@ -%h3.page_title - Milestone ##{@milestone.id} - %small - = @milestone.expires_at +.row + .span6 + %h3.page_title + Milestone ##{@milestone.id} + %small + = @milestone.expires_at + .back_link + = link_to project_milestones_path(@project) do + ← To milestones list + .span6 + .right + - unless @milestone.closed + = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do + %i.icon-plus + New Issue + = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" + - if can?(current_user, :admin_milestone, @project) + = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do + %i.icon-edit + Edit - %span.right - = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do - %i.icon-plus - New Issue - = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" - - if can?(current_user, :admin_milestone, @project) - = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do - %i.icon-edit - Edit -.back_link - = link_to project_milestones_path(@project) do - ← To milestones list + +- if @milestone.can_be_closed? + %hr + %p + %span All issues for this milestone are closed. You may close milestone now. + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn small danger" .main_box .top_box_content - %h5 + %h4.box-title - if @milestone.closed - .alert-message.error.status_info Closed - - else - .alert-message.success.status_info Open + .error.status_info Closed + - elsif @milestone.expired? + .error.status_info Expired + = gfm escape_once(@milestone.title) - %small.right= @milestone.expires_at .middle_box_content %h5 @@ -34,6 +44,7 @@ #{@milestone.closed_items_count} closed – #{@milestone.open_items_count} open + %span.right= @milestone.expires_at .progress.progress-info .bar{style: "width: #{@milestone.percent_complete}%;"} @@ -43,14 +54,16 @@ = preserve do = markdown @milestone.description + .row .span6 %table.milestone-issue-filter %thead - %th - %ul.nav.nav-pills - %li.active= link_to('Open Issues', '#') - %li=link_to('All Issues', '#') + %tr + %th + %ul.nav.nav-pills + %li.active= link_to('Open Issues', '#') + %li=link_to('All Issues', '#') - @issues.each do |issue| %tr{data: {closed: issue.closed}} %td @@ -62,10 +75,11 @@ .span6 %table.milestone-merge-requests-filter %thead - %th - %ul.nav.nav-pills - %li.active= link_to('Open Merge Requests', '#') - %li=link_to('All Merge Requests', '#') + %tr + %th + %ul.nav.nav-pills + %li.active= link_to('Open Merge Requests', '#') + %li=link_to('All Merge Requests', '#') - @merge_requests.each do |merge_request| %tr{data: {closed: merge_request.closed}} %td diff --git a/app/views/notes/_form.html.haml b/app/views/notes/_form.html.haml index 57811daf919..c310fac47ca 100644 --- a/app/views/notes/_form.html.haml +++ b/app/views/notes/_form.html.haml @@ -1,6 +1,7 @@ = form_for [@project, @note], remote: true, html: { multipart: true, id: nil, class: "new_note js-new-note-form" } do |f| = note_target_fields + = f.hidden_field :commit_id = f.hidden_field :line_code = f.hidden_field :noteable_id = f.hidden_field :noteable_type diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml index 59130f79d6c..c433e80c9e5 100644 --- a/app/views/notify/issue_status_changed_email.html.haml +++ b/app/views/notify/issue_status_changed_email.html.haml @@ -9,7 +9,7 @@ %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %td{align: "left", style: "padding: 20px 0 0;"} - %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} + %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "} = "Issue ##{@issue.id}" = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title %br diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index 654d6cd12be..fba4b865487 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -9,7 +9,7 @@ %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %td{align: "left", style: "padding: 20px 0 0;"} - %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} + %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "} = "Issue ##{@issue.id}" = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title %br diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 151aac451fb..9819767011e 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -5,7 +5,8 @@ %td{align: "left", style: "padding: 20px 0 0;"} %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} = "New Merge Request !#{@merge_request.id}" - = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request) + %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "} + = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request) %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} diff --git a/app/views/notify/project_access_granted_email.html.haml b/app/views/notify/project_access_granted_email.html.haml index 72b3f0658fc..11117bf0b33 100644 --- a/app/views/notify/project_access_granted_email.html.haml +++ b/app/views/notify/project_access_granted_email.html.haml @@ -1,14 +1,15 @@ %td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"} %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"} %tr - %td{style: "font-size: 1px; line-height: 1px;", width: "21"} - %td{align: "left", style: "padding: 20px 0 0;"} - %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} + %td{width: "21"} + %td + %h2{style: "color:#646464;" } = "You have been granted #{@users_project.project_access_human} access to project" %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %tr - %td{style: "font-size: 1px; line-height: 1px;", width: "21"} - %td{align: "left", style: "padding: 20px 0 0;"} - %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} - = link_to_gfm truncate(@project.name, length: 45), project_url(@project), title: @project.name + %td{width: "21"} + %td + %h3 + = link_to project_url(@project) do + = @project.name_with_namespace %br diff --git a/app/views/notify/project_was_moved_email.html.haml b/app/views/notify/project_was_moved_email.html.haml new file mode 100644 index 00000000000..222bd0fecea --- /dev/null +++ b/app/views/notify/project_was_moved_email.html.haml @@ -0,0 +1,25 @@ +%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"} + %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #555; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"} + %tr + %td{width: "21"} + %td + %h2 + = "Project was moved to another location" + %td{width: "21"} + %tr + %td{width: "21"} + %td + %p + The project is now located under + = link_to project_url(@project) do + = @project.name_with_namespace + %p + To update the remote url in your local repository run: + %br + %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"} + %tr + %td{valign: "top"} + %p{ style: "background:#f5f5f5; padding:10px; border:1px solid #ddd" } + git remote set-url origin #{@project.ssh_url_to_repo} + %br + %td{ width: "21"} diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml index c7896af3a54..31a5d23242c 100644 --- a/app/views/notify/reassigned_issue_email.html.haml +++ b/app/views/notify/reassigned_issue_email.html.haml @@ -5,7 +5,7 @@ %td{align: "left", style: "padding: 20px 0 0;"} %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} = "Reassigned Issue ##{@issue.id}" - = link_to_gfm truncate(@issue.title, length: 16), project_issue_url(@issue.project, @issue) + = link_to_gfm truncate(@issue.title, length: 30), project_issue_url(@issue.project, @issue) %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml index e49b783635c..8f7308b3dba 100644 --- a/app/views/notify/reassigned_merge_request_email.html.haml +++ b/app/views/notify/reassigned_merge_request_email.html.haml @@ -5,7 +5,7 @@ %td{align: "left", style: "padding: 20px 0 0;"} %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} = "Reassigned Merge Request !#{@merge_request.id}" - = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request) + = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.project, @merge_request) %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml index 1c51f48f401..3c290948d6c 100644 --- a/app/views/profiles/account.html.haml +++ b/app/views/profiles/account.html.haml @@ -1,4 +1,4 @@ -- if Gitlab.config.omniauth_enabled? +- if Gitlab.config.omniauth.enabled %fieldset %legend Social Accounts .oauth_select_holder @@ -71,6 +71,9 @@ %span.update-failed.cred.hide %i.icon-ok Failed + %ul.cred + %li It will change web url for personal projects. + %li It will change the git path to repositories for personal projects. .input = f.submit 'Save username', class: "btn save-btn" diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index ac36fa3aa55..934c1fdf7c4 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -33,11 +33,11 @@ %ul %li %p You can change your password on Account page - -unless Gitlab.config.disable_gravatar? + - if Gitlab.config.gravatar.enabled %li %p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"} - - if Gitlab.config.omniauth_enabled? && @user.provider? + - if Gitlab.config.omniauth.enabled && @user.provider? %li %p You can login through #{@user.provider.titleize}! diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 9bb411ada3e..7044d1f20be 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -17,13 +17,6 @@ .controls = text_field_tag :ppath, @project.path_to_repo, class: "xxlarge", readonly: true - .control-group - = f.label :namespace_id do - %span Namespace - .controls - = f.select :namespace_id, namespaces_options(@project.namespace_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'} - - %span.cred Be careful. Changing project namespace can have unintended side effects - unless @project.heads.empty? .clearfix @@ -57,11 +50,28 @@ = f.check_box :wiki_enabled %span.descr Pages for project documentation + + - if can? current_user, :change_namespace, @project + %fieldset.features + %legend Transfer: + .control-group + = f.label :namespace_id do + %span Namespace + .controls + = f.select :namespace_id, namespaces_options(@project.namespace_id || Namespace::global_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'} + %br + %ul.prepend-top-10.cred + %li Be careful. Changing project namespace can have unintended side effects + %li You can transfer project only to namespaces you can manage + %li You will need to update your local repositories to point to the new location. + + %br .actions = f.submit 'Save', class: "btn save-btn" = link_to 'Cancel', @project, class: "btn" - unless @project.new_record? - .right - = link_to 'Remove', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger" + - if can?(current_user, :remove_project, @project) + .right + = link_to 'Remove', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml index ce73fe0cf01..d388988676d 100644 --- a/app/views/projects/create.js.haml +++ b/app/views/projects/create.js.haml @@ -9,3 +9,4 @@ $('.project_new_holder').show(); $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); $('.save-project-loader').hide(); + new Projects(); diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index f331ae7fadc..52dff687a3a 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -29,6 +29,6 @@ git remote add origin #{@project.url_to_repo} git push -u origin master - - if can? current_user, :admin_project, @project + - if can? current_user, :remove_project, @project .prepend-top-20 = link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger right" diff --git a/app/views/projects/files.html.haml b/app/views/projects/files.html.haml index 9f7efcdc515..d108308318e 100644 --- a/app/views/projects/files.html.haml +++ b/app/views/projects/files.html.haml @@ -17,7 +17,6 @@ = time_ago_in_words(note.created_at) ago - else - .alert-message.block-message - %span All files attached to project wall, issues etc will be displayed here + %p.slead All files attached to project wall, issues etc will be displayed here diff --git a/app/views/projects/graph.html.haml b/app/views/projects/graph.html.haml index 07f038d28a2..4e0b0e36c34 100644 --- a/app/views/projects/graph.html.haml +++ b/app/views/projects/graph.html.haml @@ -2,13 +2,15 @@ %br .graph_holder %h4 - %small You can move around the graph by using arrow keys. + %small You can move around the graph by using the arrow keys. #holder.graph + .loading.loading-gray + :javascript - var chunk1={commits:#{@commits_json}}; - var days=#{@days_json}; - initGraph(); + var branch_graph; $(function(){ - branchGraph($("#holder")[0]); - GraphNav.init(); + branch_graph = new BranchGraph($("#holder"), { + url: '#{url_for controller: 'projects', action: 'graph', format: :json}', + commit_url: '#{url_for controller: 'projects', action: 'show'}/commits/%s' + }); }); diff --git a/app/views/projects/update_failed.js.haml b/app/views/projects/update_failed.js.haml new file mode 100644 index 00000000000..a3ac5f4088f --- /dev/null +++ b/app/views/projects/update_failed.js.haml @@ -0,0 +1,2 @@ +:plain + $(".save-project-loader").replaceWith(errorMessage('#{escape_javascript(@error.message)}')); diff --git a/app/views/services/_gitlab_ci.html.haml b/app/views/services/_gitlab_ci.html.haml index 4c1ec5bc348..649c5cc4c3c 100644 --- a/app/views/services/_gitlab_ci.html.haml +++ b/app/views/services/_gitlab_ci.html.haml @@ -1,16 +1,19 @@ %h3.page_title - Services → GitLab CI Integration - + GitLab CI + %small Continuous integration server from GitLab .right - .thumbnail - - if @service.active - = image_tag 'service-gitlab-ci.png', class: 'small' - - else - = image_tag 'service-disabled-gitlab-ci.png', class: 'small' + - if @service.active + %small.cgreen Enabled + - else + %small.cgray Disabled -%hr +.back_link + = link_to project_services_path(@project) do + ← to services + +%hr = form_for(@service, :as => :service, :url => project_service_path(@project, :gitlab_ci), :method => :put) do |f| - if @service.errors.any? .alert-message.block-message.error diff --git a/app/views/services/index.html.haml b/app/views/services/index.html.haml index 3894fcee369..2c94f965eec 100644 --- a/app/views/services/index.html.haml +++ b/app/views/services/index.html.haml @@ -1,15 +1,31 @@ = render "projects/project_head" %h3.page_title Services -%hr - -.row - .span6 - .padded - %p.slead Continuous integration server from GitLab - .thumbnail.left - = link_to edit_project_service_path(@project, :gitlab_ci) do - - if @gitlab_ci_service.try :active - = image_tag 'service-gitlab-ci.png' - - else - = image_tag 'service-disabled-gitlab-ci.png' +%br +%ul.ui-box.well-list + %li + %h4.cgreen + = link_to edit_project_service_path(@project, :gitlab_ci) do + GitLab CI + %small Continuous integration server from GitLab + .right + - if @gitlab_ci_service.try(:active) + %small.cgreen + %i.icon-ok + Enabled + - else + %small.cgray + %i.icon-off + Disabled + %li.disabled + %h4 + Jenkins CI + %small An extendable open source continuous integration server + .right + %small Not implemented yet + %li.disabled + %h4 + Campfire + %small Web-based group chat tool + .right + %small Not implemented yet diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index f632e1221f9..e283d9b3085 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -1,4 +1,4 @@ .input-prepend.project_clone_holder %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH - %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase + %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge" diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml index 981c7cf0c12..baef737b565 100644 --- a/app/views/snippets/_form.html.haml +++ b/app/views/snippets/_form.html.haml @@ -1,28 +1,41 @@ %h3.page_title = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" %hr -= form_for [@project, @snippet] do |f| - -if @snippet.errors.any? - .alert-message.block-message.error - %ul - - @snippet.errors.full_messages.each do |msg| - %li= msg +.snippet-form-holder + = form_for [@project, @snippet] do |f| + -if @snippet.errors.any? + .alert-message.block-message.error + %ul + - @snippet.errors.full_messages.each do |msg| + %li= msg - .clearfix - = f.label :title - .input= f.text_field :title, placeholder: "Example Snippet" - .clearfix - = f.label :file_name - .input= f.text_field :file_name, placeholder: "example.rb" - .clearfix - = f.label "Lifetime" - .input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'} - .clearfix - = f.label :content, "Code" - .input= f.text_area :content, class: "span8" + .clearfix + = f.label :title + .input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true + .clearfix + = f.label "Lifetime" + .input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'} + .clearfix + .file-editor + = f.label :file_name, "File" + .input + .file_holder.snippet + .file_title + = f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true + .file_content.code + %pre#editor= @snippet.content + = f.hidden_field :content, class: 'snippet-file-content' + + .form-actions + = f.submit 'Save', class: "save-btn btn" + = link_to "Cancel", project_snippets_path(@project), class: " btn" + - unless @snippet.new_record? + .right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" + + +:javascript + var editor = ace.edit("editor"); + $(".snippet-form-holder form").submit(function(){ + $(".snippet-file-content").val(editor.getValue()); + }); - .form-actions - = f.submit 'Save', class: "primary btn" - = link_to "Cancel", project_snippets_path(@project), class: " btn" - - unless @snippet.new_record? - .right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml index a2d3a65e6cb..a576500c15d 100644 --- a/app/views/snippets/_snippet.html.haml +++ b/app/views/snippets/_snippet.html.haml @@ -1,12 +1,13 @@ %tr %td + = image_tag gravatar_icon(snippet.author_email), class: "avatar s24" %a{href: project_snippet_path(snippet.project, snippet)} %strong= truncate(snippet.title, length: 60) %td = snippet.file_name %td %span.cgray - - if snippet.expires_at + - if snippet.expires_at = snippet.expires_at.to_date.to_s(:short) - else Never diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index 515daec6207..7b8f94de7dd 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,21 +1,21 @@ = render "projects/project_head" -- if can? current_user, :write_snippet, @project - .alert-message.block-message +%h3.page_title + Snippets + %small share code pastes with others out of git repository + + - if can? current_user, :write_snippet, @project = link_to new_project_snippet_path(@project), class: "btn small add_new right", title: "New Snippet" do Add new snippet - Share code pastes with others if it can't be in a git repository - %br - To add new snippet - click on button. - +%br %table %thead %tr %th Title %th File Name %th Expires At - = render @snippets.fresh - - if @snippets.fresh.empty? + = render @snippets + - if @snippets.empty? %tr %td{colspan: 3} %h3.nothing_here_message Nothing here. diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 5b9d3d5d623..02022185f9a 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -1,6 +1,6 @@ = render "projects/project_head" -%h3 +%h3.page_title = @snippet.title %small= @snippet.file_name - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user diff --git a/app/views/team_members/_form.html.haml b/app/views/team_members/_form.html.haml index 92167138081..e5d9a4a4b5e 100644 --- a/app/views/team_members/_form.html.haml +++ b/app/views/team_members/_form.html.haml @@ -11,7 +11,7 @@ %h6 1. Choose people you want in the team .clearfix = f.label :user_ids, "People" - .input= select_tag(:user_ids, options_from_collection_for_select(User.not_in_project(@project).all, :id, :name), {data: {placeholder: "Select users"}, class: "chosen xxlarge", multiple: true}) + .input= select_tag(:user_ids, options_from_collection_for_select(User.active.not_in_project(@project).all, :id, :name), {data: {placeholder: "Select users"}, class: "chosen xxlarge", multiple: true}) %h6 2. Set access level for them .clearfix diff --git a/app/views/team_members/_show.html.haml b/app/views/team_members/_show.html.haml index 8938c7d8a6d..8082f47fca8 100644 --- a/app/views/team_members/_show.html.haml +++ b/app/views/team_members/_show.html.haml @@ -1,6 +1,6 @@ - user = member.user - allow_admin = can? current_user, :admin_project, @project -%li.wll{id: dom_id(member), class: "team_member_row user_#{user.id}"} +%li{id: dom_id(member), class: "team_member_row user_#{user.id}"} .row .span6 = link_to project_team_member_path(@project, member), title: user.name, class: "dark" do diff --git a/app/views/team_members/_team.html.haml b/app/views/team_members/_team.html.haml index 65f17864814..462e75af183 100644 --- a/app/views/team_members/_team.html.haml +++ b/app/views/team_members/_team.html.haml @@ -1,10 +1,10 @@ - grouper_project_members(@project).each do |access, members| - %fieldset - %legend + .ui-box + %h5 = Project.access_options.key(access).pluralize %small= members.size - %ul.unstyled - - members.each do |up| + %ul.well-list + - members.sort_by(&:user_name).each do |up| = render(partial: 'team_members/show', locals: {member: up}) diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml index 9d03cd2cb1f..af9a6e6b92d 100644 --- a/app/views/team_members/show.html.haml +++ b/app/views/team_members/show.html.haml @@ -6,7 +6,7 @@ = link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn danger" .profile_avatar_holder = image_tag gravatar_icon(user.email, 60), class: "borders" - %h3 + %h3.page_title = user.name %small = user.email diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml index 02ae3d90c40..a632bb3b0d7 100644 --- a/app/views/tree/_tree.html.haml +++ b/app/views/tree/_tree.html.haml @@ -16,10 +16,11 @@ - else %table#tree-slider{class: "table_#{@hex_path} tree-table" } %thead - %th Name - %th Last Update - %th Last Commit - %th= link_to "history", project_commits_path(@project, @id), class: "btn very_small right" + %tr + %th Name + %th Last Update + %th Last Commit + %th= link_to "history", project_commits_path(@project, @id), class: "btn very_small right" - if tree.up_dir? %tr.tree-item diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 4f4f69c4ece..1414ed490c9 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -1,12 +1,16 @@ class PostReceive @queue = :post_receive - def self.perform(reponame, oldrev, newrev, ref, identifier) - project = Project.find_by_path(reponame) + def self.perform(repo_path, oldrev, newrev, ref, identifier) + repo_path.gsub!(Gitlab.config.gitolite.repos_path.to_s, "") + repo_path.gsub!(/.git$/, "") + repo_path.gsub!(/^\//, "") + + project = Project.find_with_namespace(repo_path) return false if project.nil? # Ignore push from non-gitlab users - user = if identifier.eql? Gitlab.config.gitolite_admin_key + user = if identifier.eql? Gitlab.config.gitolite.admin_key email = project.commit(newrev).author.email rescue nil User.find_by_email(email) if email elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier) |
