summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/fonts/OFL.txt92
-rw-r--r--app/assets/fonts/YanoneKaffeesatz-Light.ttfbin0 -> 77296 bytes
-rw-r--r--app/assets/fonts/korolev-medium-compressed.otfbin28736 -> 0 bytes
-rw-r--r--app/assets/images/download.pngbin674 -> 0 bytes
-rw-r--r--app/assets/javascripts/dashboard.js.coffee30
-rw-r--r--app/assets/javascripts/issues.js2
-rw-r--r--app/assets/javascripts/merge_requests.js132
-rw-r--r--app/assets/javascripts/merge_requests.js.coffee97
-rw-r--r--app/assets/javascripts/milestones.js.coffee8
-rw-r--r--app/assets/javascripts/pager.js11
-rw-r--r--app/assets/stylesheets/common.scss34
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/blocks.scss113
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/buttons.scss4
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/common.scss37
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/fonts.scss8
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/lists.scss12
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/mixins.scss6
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/tables.scss2
-rw-r--r--app/assets/stylesheets/sections/commits.scss82
-rw-r--r--app/assets/stylesheets/sections/events.scss6
-rw-r--r--app/assets/stylesheets/sections/header.scss37
-rw-r--r--app/assets/stylesheets/sections/issues.scss50
-rw-r--r--app/assets/stylesheets/sections/merge_requests.scss37
-rw-r--r--app/assets/stylesheets/sections/notes.scss2
-rw-r--r--app/assets/stylesheets/sections/projects.scss12
-rw-r--r--app/assets/stylesheets/themes/ui_basic.scss13
-rw-r--r--app/assets/stylesheets/themes/ui_color.scss9
-rw-r--r--app/assets/stylesheets/themes/ui_gray.scss9
-rw-r--r--app/assets/stylesheets/themes/ui_mars.scss13
-rw-r--r--app/assets/stylesheets/themes/ui_modern.scss9
-rw-r--r--app/contexts/commit_load_context.rb6
-rw-r--r--app/contexts/filter_context.rb31
-rw-r--r--app/contexts/issues_list_context.rb2
-rw-r--r--app/contexts/notes/load_context.rb4
-rw-r--r--app/contexts/test_hook_context.rb2
-rw-r--r--app/controllers/admin/dashboard_controller.rb4
-rw-r--r--app/controllers/admin/groups_controller.rb11
-rw-r--r--app/controllers/admin/projects_controller.rb6
-rw-r--r--app/controllers/admin/users_controller.rb10
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/commits_controller.rb4
-rw-r--r--app/controllers/dashboard_controller.rb28
-rw-r--r--app/controllers/groups_controller.rb21
-rw-r--r--app/controllers/merge_requests_controller.rb6
-rw-r--r--app/controllers/project_resource_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb10
-rw-r--r--app/controllers/refs_controller.rb10
-rw-r--r--app/controllers/repositories_controller.rb10
-rw-r--r--app/controllers/search_controller.rb2
-rw-r--r--app/controllers/services_controller.rb2
-rw-r--r--app/controllers/snippets_controller.rb2
-rw-r--r--app/controllers/team_members_controller.rb9
-rw-r--r--app/controllers/tree_controller.rb2
-rw-r--r--app/decorators/tree_decorator.rb8
-rw-r--r--app/helpers/application_helper.rb20
-rw-r--r--app/helpers/commits_helper.rb8
-rw-r--r--app/helpers/events_helper.rb19
-rw-r--r--app/helpers/groups_helper.rb17
-rw-r--r--app/helpers/merge_requests_helper.rb2
-rw-r--r--app/helpers/namespaces_helper.rb2
-rw-r--r--app/mailers/notify.rb12
-rw-r--r--app/models/ability.rb34
-rw-r--r--app/models/commit.rb18
-rw-r--r--app/models/concerns/issuable.rb (renamed from app/roles/issue_commonality.rb)41
-rw-r--r--app/models/event.rb162
-rw-r--r--app/models/gitlab_ci_service.rb8
-rw-r--r--app/models/group.rb12
-rw-r--r--app/models/issue.rb3
-rw-r--r--app/models/key.rb2
-rw-r--r--app/models/merge_request.rb5
-rw-r--r--app/models/milestone.rb10
-rw-r--r--app/models/namespace.rb31
-rw-r--r--app/models/note.rb15
-rw-r--r--app/models/project.rb356
-rw-r--r--app/models/protected_branch.rb6
-rw-r--r--app/models/repository.rb (renamed from app/roles/repository.rb)112
-rw-r--r--app/models/service.rb4
-rw-r--r--app/models/system_hook.rb2
-rw-r--r--app/models/team.rb118
-rw-r--r--app/models/tree.rb7
-rw-r--r--app/models/user.rb167
-rw-r--r--app/models/users_project.rb131
-rw-r--r--app/models/wiki.rb1
-rw-r--r--app/observers/issue_observer.rb6
-rw-r--r--app/observers/key_observer.rb6
-rw-r--r--app/observers/merge_request_observer.rb4
-rw-r--r--app/observers/note_observer.rb4
-rw-r--r--app/observers/user_observer.rb4
-rw-r--r--app/observers/users_project_observer.rb2
-rw-r--r--app/roles/account.rb124
-rw-r--r--app/roles/authority.rb58
-rw-r--r--app/roles/git_host.rb5
-rw-r--r--app/roles/namespaced_project.rb59
-rw-r--r--app/roles/note_event.rb37
-rw-r--r--app/roles/push_event.rb100
-rw-r--r--app/roles/push_observer.rb144
-rw-r--r--app/roles/static_model.rb47
-rw-r--r--app/roles/team.rb52
-rw-r--r--app/roles/votes.rb33
-rw-r--r--app/uploaders/attachment_uploader.rb42
-rw-r--r--app/views/admin/dashboard/index.html.haml31
-rw-r--r--app/views/admin/groups/show.html.haml62
-rw-r--r--app/views/admin/projects/_form.html.haml18
-rw-r--r--app/views/admin/projects/index.html.haml8
-rw-r--r--app/views/admin/projects/show.html.haml81
-rw-r--r--app/views/admin/resque/show.html.haml4
-rw-r--r--app/views/admin/users/index.html.haml9
-rw-r--r--app/views/admin/users/show.html.haml6
-rw-r--r--app/views/commit/show.html.haml9
-rw-r--r--app/views/commits/_commit.html.haml4
-rw-r--r--app/views/commits/_commit_box.html.haml35
-rw-r--r--app/views/commits/_commits.html.haml2
-rw-r--r--app/views/commits/_head.html.haml6
-rw-r--r--app/views/commits/_text_diff.html.haml2
-rw-r--r--app/views/compare/_form.html.haml2
-rw-r--r--app/views/compare/show.html.haml3
-rw-r--r--app/views/dashboard/_activities.html.haml2
-rw-r--r--app/views/dashboard/_groups.html.haml4
-rw-r--r--app/views/dashboard/_projects.html.haml2
-rw-r--r--app/views/dashboard/index.html.haml2
-rw-r--r--app/views/dashboard/issues.html.haml3
-rw-r--r--app/views/dashboard/merge_requests.html.haml3
-rw-r--r--app/views/events/event/_note.html.haml5
-rw-r--r--app/views/groups/_filter.html.haml33
-rw-r--r--app/views/groups/_new_group_member.html.haml18
-rw-r--r--app/views/groups/_new_member.html.haml2
-rw-r--r--app/views/groups/_projects.html.haml2
-rw-r--r--app/views/groups/issues.html.haml32
-rw-r--r--app/views/groups/merge_requests.html.haml30
-rw-r--r--app/views/groups/people.html.haml6
-rw-r--r--app/views/groups/search.html.haml68
-rw-r--r--app/views/groups/show.html.haml4
-rw-r--r--app/views/help/index.html.haml48
-rw-r--r--app/views/help/markdown.html.haml4
-rw-r--r--app/views/help/raketasks.html.haml11
-rw-r--r--app/views/hooks/_data_ex.html.erb78
-rw-r--r--app/views/issues/_filter.html.haml20
-rw-r--r--app/views/issues/_form.html.haml31
-rw-r--r--app/views/issues/_issues.html.haml10
-rw-r--r--app/views/issues/_show.html.haml9
-rw-r--r--app/views/issues/index.html.haml70
-rw-r--r--app/views/issues/show.html.haml10
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/layouts/_head_panel.html.haml3
-rw-r--r--app/views/layouts/admin.html.haml2
-rw-r--r--app/views/layouts/application.html.haml2
-rw-r--r--app/views/layouts/group.html.haml2
-rw-r--r--app/views/layouts/notify.html.haml4
-rw-r--r--app/views/layouts/project_resource.html.haml4
-rw-r--r--app/views/merge_requests/_filter.html.haml20
-rw-r--r--app/views/merge_requests/_form.html.haml84
-rw-r--r--app/views/merge_requests/_show.html.haml55
-rw-r--r--app/views/merge_requests/automerge.js.haml2
-rw-r--r--app/views/merge_requests/commits.js.haml2
-rw-r--r--app/views/merge_requests/diffs.js.haml3
-rw-r--r--app/views/merge_requests/index.html.haml65
-rw-r--r--app/views/merge_requests/show.js.haml2
-rw-r--r--app/views/merge_requests/show/_commits.html.haml10
-rw-r--r--app/views/merge_requests/show/_mr_accept.html.haml19
-rw-r--r--app/views/merge_requests/show/_mr_box.html.haml8
-rw-r--r--app/views/milestones/show.html.haml53
-rw-r--r--app/views/notes/_note.html.haml2
-rw-r--r--app/views/notify/issue_status_changed_email.html.haml4
-rw-r--r--app/views/notify/new_issue_email.html.haml8
-rw-r--r--app/views/notify/new_merge_request_email.html.haml2
-rw-r--r--app/views/notify/note_merge_request_email.html.haml28
-rw-r--r--app/views/notify/reassigned_issue_email.html.haml2
-rw-r--r--app/views/profiles/account.html.haml2
-rw-r--r--app/views/profiles/show.html.haml2
-rw-r--r--app/views/projects/_form.html.haml6
-rw-r--r--app/views/projects/_new_form.html.haml2
-rw-r--r--app/views/protected_branches/index.html.haml99
-rw-r--r--app/views/repositories/_branch.html.haml4
-rw-r--r--app/views/repositories/_feed.html.haml2
-rw-r--r--app/views/repositories/_filter.html.haml (renamed from app/views/repositories/_branches_head.html.haml)7
-rw-r--r--app/views/repositories/branches.html.haml27
-rw-r--r--app/views/repositories/show.html.haml23
-rw-r--r--app/views/repositories/stats.html.haml2
-rw-r--r--app/views/repositories/tags.html.haml10
-rw-r--r--app/views/search/_result.html.haml84
-rw-r--r--app/views/search/show.html.haml85
-rw-r--r--app/views/team_members/_form.html.haml2
-rw-r--r--app/views/team_members/_team.html.haml2
-rw-r--r--app/views/team_members/import.html.haml2
-rw-r--r--app/views/team_members/show.html.haml3
-rw-r--r--app/views/tree/_tree.html.haml10
-rw-r--r--app/views/tree/blob/_download.html.haml6
-rw-r--r--app/views/wikis/_form.html.haml8
-rw-r--r--app/workers/post_receive.rb8
-rw-r--r--app/workers/system_hook_worker.rb6
190 files changed, 2425 insertions, 2270 deletions
diff --git a/app/assets/fonts/OFL.txt b/app/assets/fonts/OFL.txt
new file mode 100644
index 00000000000..3ce219f0126
--- /dev/null
+++ b/app/assets/fonts/OFL.txt
@@ -0,0 +1,92 @@
+Copyright (c) 2010, Jan Gerner (post@yanone.de)
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/app/assets/fonts/YanoneKaffeesatz-Light.ttf b/app/assets/fonts/YanoneKaffeesatz-Light.ttf
new file mode 100644
index 00000000000..5026d3bdbe2
--- /dev/null
+++ b/app/assets/fonts/YanoneKaffeesatz-Light.ttf
Binary files differ
diff --git a/app/assets/fonts/korolev-medium-compressed.otf b/app/assets/fonts/korolev-medium-compressed.otf
deleted file mode 100644
index a9cd3cbffff..00000000000
--- a/app/assets/fonts/korolev-medium-compressed.otf
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/download.png b/app/assets/images/download.png
deleted file mode 100644
index 5791e723de9..00000000000
--- a/app/assets/images/download.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/dashboard.js.coffee b/app/assets/javascripts/dashboard.js.coffee
new file mode 100644
index 00000000000..b0ae6bf8a02
--- /dev/null
+++ b/app/assets/javascripts/dashboard.js.coffee
@@ -0,0 +1,30 @@
+$ ->
+ dashboardPage()
+
+dashboardPage = ->
+ Pager.init 20, true
+ $(".event_filter_link").bind "click", (event) ->
+ event.preventDefault()
+ toggleFilter $(this)
+ reloadActivities()
+
+reloadActivities = ->
+ $(".content_list").html ''
+ Pager.init 20, true
+
+toggleFilter = (sender) ->
+ sender.parent().toggleClass "inactive"
+ event_filters = $.cookie("event_filter")
+ filter = sender.attr("id").split("_")[0]
+ if event_filters
+ event_filters = event_filters.split(",")
+ else
+ event_filters = new Array()
+
+ index = event_filters.indexOf(filter)
+ if index is -1
+ event_filters.push filter
+ else
+ event_filters.splice index, 1
+
+ $.cookie "event_filter", event_filters.join(",")
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
index 719d2c176c1..9ba1a3f1bba 100644
--- a/app/assets/javascripts/issues.js
+++ b/app/assets/javascripts/issues.js
@@ -11,7 +11,7 @@ function initIssuesSearch() {
last_terms = terms;
if (terms.length >= 2 || terms.length == 0) {
- $.get(href, { 'f': status, 'terms': terms, 'milestone_id': milestone_id }, function(response) {
+ $.get(href, { 'status': status, 'terms': terms, 'milestone_id': milestone_id }, function(response) {
$('#issues-table').html(response);
});
}
diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js
deleted file mode 100644
index ee714f9cabb..00000000000
--- a/app/assets/javascripts/merge_requests.js
+++ /dev/null
@@ -1,132 +0,0 @@
-var MergeRequest = {
- diffs_loaded: false,
- commits_loaded: false,
- opts: false,
-
- init:
- function(opts) {
- var self = this;
- self.opts = opts;
-
- self.initTabs();
- self.initMergeWidget();
-
- $(".mr_show_all_commits").bind("click", function() {
- self.showAllCommits();
- });
- },
-
- initMergeWidget:
- function() {
- var self = this;
- self.showState(self.opts.current_state);
-
- if($(".automerge_widget").length && self.opts.check_enable){
- $.get(self.opts.url_to_automerge_check, function(data){
- 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:
- function() {
- $(".mr_nav_tabs a").live("click", function() {
- $(".mr_nav_tabs a").parent().removeClass("active");
- $(this).parent().addClass("active");
- });
-
- var current_tab;
- if(this.opts.action == "diffs") {
- current_tab = $(".mr_nav_tabs .merge-diffs-tab");
- } else {
- current_tab = $(".mr_nav_tabs .merge-notes-tab");
- }
- current_tab.parent().addClass("active");
-
- this.initNotesTab();
- this.initDiffTab();
- },
-
- initNotesTab:
- function() {
- $(".mr_nav_tabs a.merge-notes-tab").live("click", function(e) {
- $(".merge-request-diffs").hide();
- $(".merge_request_notes").show();
- var mr_path = $(".merge-notes-tab").attr("data-url");
- history.pushState({ path: mr_path }, '', mr_path);
- e.preventDefault();
- });
- },
-
- initDiffTab:
- function() {
- $(".mr_nav_tabs a.merge-diffs-tab").live("click", function(e) {
- if(!MergeRequest.diffs_loaded) {
- MergeRequest.loadDiff();
- }
- $(".merge_request_notes").hide();
- $(".merge-request-diffs").show();
- var mr_diff_path = $(".merge-diffs-tab").attr("data-url");
- history.pushState({ path: mr_diff_path }, '', mr_diff_path);
- e.preventDefault();
- });
-
- },
-
- showState:
- function(state){
- $(".automerge_widget").hide();
- $(".automerge_widget." + state).show();
- },
-
- showCiState:
- function(state){
- $(".ci_widget").hide();
- $(".ci_widget.ci-" + state).show();
- },
-
- loadDiff:
- function() {
- $(".dashboard-loader").show();
- $.ajax({
- type: "GET",
- url: $(".merge-diffs-tab").attr("data-url"),
- beforeSend: function(){ $('.status').addClass("loading")},
- complete: function(){
- MergeRequest.diffs_loaded = true;
- $(".merge_request_notes").hide();
- $('.status').removeClass("loading");
- },
- dataType: "script"});
- },
-
- showAllCommits:
- function() {
- $(".first_mr_commits").remove();
- $(".all_mr_commits").removeClass("hide");
- },
-
- already_cannot_be_merged:
- function(){
- $(".automerge_widget").hide();
- $(".merge_in_progress").hide();
- $(".automerge_widget.already_cannot_be_merged").show();
- }
-};
-
-/*
- * Filter merge requests
- */
-function merge_requestsPage() {
- $("#assignee_id").chosen();
- $("#milestone_id").chosen();
- $("#milestone_id, #assignee_id").on("change", function(){
- $(this).closest("form").submit();
- });
-}
diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee
new file mode 100644
index 00000000000..cdc685f2c09
--- /dev/null
+++ b/app/assets/javascripts/merge_requests.js.coffee
@@ -0,0 +1,97 @@
+#
+# * Filter merge requests
+#
+@merge_requestsPage = ->
+ $('#assignee_id').chosen()
+ $('#milestone_id').chosen()
+ $('#milestone_id, #assignee_id').on 'change', ->
+ $(this).closest('form').submit()
+
+class MergeRequest
+
+ constructor: (@opts) ->
+ this.$el = $('.merge-request')
+ @diffs_loaded = false
+ @commits_loaded = false
+
+ this.activateTab(@opts.action)
+
+ this.bindEvents()
+
+ this.initMergeWidget()
+ this.$('.show-all-commits').on 'click', =>
+ this.showAllCommits()
+
+ # Local jQuery finder
+ $: (selector) ->
+ this.$el.find(selector)
+
+ initMergeWidget: ->
+ this.showState( @opts.current_state )
+
+ if this.$('.automerge_widget').length and @opts.check_enable
+ $.get @opts.url_to_automerge_check, (data) =>
+ this.showState( data.state )
+ , 'json'
+
+ if @opts.ci_enable
+ $.get @opts.url_to_ci_check, (data) =>
+ this.showCiState data.status
+ , 'json'
+
+ bindEvents: ->
+ this.$('.nav-tabs').on 'click', 'a', (event) =>
+ a = $(event.currentTarget)
+
+ href = a.attr('href')
+ History.replaceState {path: href}, document.title, href
+
+ event.preventDefault()
+
+ this.$('.nav-tabs').on 'click', 'li', (event) =>
+ this.activateTab($(event.currentTarget).data('action'))
+
+ activateTab: (action) ->
+ this.$('.nav-tabs li').removeClass 'active'
+ this.$('.tab-content').hide()
+ switch action
+ when 'diffs'
+ this.$('.nav-tabs .diffs-tab').addClass 'active'
+ this.loadDiff() unless @diffs_loaded
+ this.$('.diffs').show()
+ else
+ this.$('.nav-tabs .notes-tab').addClass 'active'
+ this.$('.notes').show()
+
+ showState: (state) ->
+ $('.automerge_widget').hide()
+ $('.automerge_widget.' + state).show()
+
+ showCiState: (state) ->
+ $('.ci_widget').hide()
+ $('.ci_widget.ci-' + state).show()
+
+ loadDiff: (event) ->
+ $('.dashboard-loader').show()
+ $.ajax
+ type: 'GET'
+ url: this.$('.nav-tabs .diffs-tab a').attr('href')
+ beforeSend: =>
+ this.$('.status').addClass 'loading'
+
+ complete: =>
+ @diffs_loaded = true
+ this.$('.status').removeClass 'loading'
+
+ dataType: 'script'
+
+ showAllCommits: ->
+ this.$('.first-commits').remove()
+ this.$('.all-commits').removeClass 'hide'
+
+ alreadyOrCannotBeMerged: ->
+ this.$('.automerge_widget').hide()
+ this.$('.merge-in-progress').hide()
+ this.$('.automerge_widget.already_cannot_be_merged').show()
+
+this.MergeRequest = MergeRequest
diff --git a/app/assets/javascripts/milestones.js.coffee b/app/assets/javascripts/milestones.js.coffee
index e40a69ebaa5..99a52bf4d3f 100644
--- a/app/assets/javascripts/milestones.js.coffee
+++ b/app/assets/javascripts/milestones.js.coffee
@@ -1,14 +1,14 @@
$ ->
- $('.milestone-issue-filter tr[data-closed]').addClass('hide')
+ $('.milestone-issue-filter li[data-closed]').addClass('hide')
$('.milestone-issue-filter ul.nav li a').click ->
$('.milestone-issue-filter li').toggleClass('active')
- $('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
+ $('.milestone-issue-filter li[data-closed]').toggleClass('hide')
false
- $('.milestone-merge-requests-filter tr[data-closed]').addClass('hide')
+ $('.milestone-merge-requests-filter li[data-closed]').addClass('hide')
$('.milestone-merge-requests-filter ul.nav li a').click ->
$('.milestone-merge-requests-filter li').toggleClass('active')
- $('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
+ $('.milestone-merge-requests-filter li[data-closed]').toggleClass('hide')
false
diff --git a/app/assets/javascripts/pager.js b/app/assets/javascripts/pager.js
index 769e8a62343..7edd6bd6186 100644
--- a/app/assets/javascripts/pager.js
+++ b/app/assets/javascripts/pager.js
@@ -4,9 +4,16 @@ var Pager = {
disable:false,
init:
- function(limit) {
+ function(limit, preload) {
this.limit=limit;
- this.offset=limit;
+
+ if(preload) {
+ this.offset = 0;
+ this.getOld();
+ } else {
+ this.offset = limit;
+ }
+
this.initLoadMore();
},
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 6d4c815106b..e192bb426a1 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -117,34 +117,10 @@ span.update-author {
}
.label {
- background-color: #474D57;
-
- &.label-tag {
- background: none;
- border: none;
- padding: 4px 6px;
- color: #444;
- text-shadow: 0 0 1px #fff;
-
- &.grouped {
- float: left;
- margin-right: 6px;
- padding: 6px;
- }
- }
- &.label-issue {
- background-color: #eee;
- border: 1px solid #ccc;
- padding: 4px 6px;
- color: #444;
- text-shadow: 0 0 1px #fff;
-
- &.grouped {
- float: left;
- margin-right: 6px;
- padding: 6px;
- }
- }
+ padding: 0px 4px;
+ font-size: 10px;
+ font-style: normal;
+ background-color: $link_color;
&.label-success {
background-color: #8D8;
@@ -425,7 +401,7 @@ li.note {
.supp_diff_link,
-.mr_show_all_commits {
+.show-all-commits {
cursor: pointer;
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
index f9c8b7b05ea..8cb1c045778 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -1,23 +1,24 @@
/**
* ===================================
- * Contain 3 main UI block elements:
- * .main_box - for show pages
- * .ui-box - for simple block & widgets
+ * Contain UI block elements:
+ * .ui-box - for any block & widgets
* ===================================
*/
/**
- * UI box element
- * contains top, middle, bottom blocks
+ * UI Block
*
*/
-.main_box {
- @extend .borders;
- @extend .prepend-top-20;
- @extend .append-bottom-20;
- border-width: 1px;
+.ui-box {
+ background: #F9F9F9;
+ margin-bottom: 25px;
+ border: 1px solid #CCC;
@include solid-shade;
+ &.ui-box-show {
+ margin:20px 0;
+ background: #FFF;
+ }
img { max-width: 100%; }
@@ -27,9 +28,9 @@
}
}
- .top_box_content,
- .middle_box_content,
- .bottom_box_content {
+ .ui-box-head,
+ .ui-box-body,
+ .ui-box-bottom {
padding: 15px;
word-wrap: break-word;
@@ -39,19 +40,25 @@
border: none;
padding: 0;
}
+
+ .clearfix {
+ margin: 0;
+ }
}
- .top_box_content {
+ .ui-box-head {
.box-title {
color: $style_color;
font-size: 18px;
font-weight: normal;
line-height: 28px;
}
+ h3 {
+ margin: 0;
+ }
}
- .middle_box_content {
- @include border-radius(0);
+ .ui-box-body {
border: none;
font-size: 12px;
background-color: #f5f5f5;
@@ -59,24 +66,9 @@
border-top: 1px solid #eee;
}
- .bottom_box_content {
+ .ui-box-bottom {
border-top: 1px solid #eee;
}
-}
-
-/**
- * Big UI Block for show page content
- *
- */
-.ui-box {
- background: #F9F9F9;
- margin-bottom: 25px;
-
- border: 1px solid #eaeaea;
- @include border-radius(4px);
-
- border-color: #CCC;
- @include solid-shade;
&.white {
background: #fff;
@@ -86,47 +78,47 @@
margin: 0;
}
- h5, .title {
- padding: 0 10px;
- @include border-radius(4px 4px 0 0);
+ .title {
@include bg-gray-gradient;
- border-top: 1px solid #eaeaea;
- border-bottom: 1px solid #bbb;
+ border-bottom: 1px solid #CCC;
+ color: #456;
+ font-size: 16px;
+ text-shadow: 0 1px 1px #fff;
+ padding: 0px 10px;
+ line-height: 36px;
+ font-size: 14px;
+ font-weight: normal;
> a {
text-shadow: 0 1px 1px #fff;
}
- &.small {
- line-height: 28px;
- font-size: 14px;
- line-height: 28px;
- text-shadow: 0 1px 1px white;
- }
-
form {
- padding: 9px 0;
- margin: 0px;
+ margin-bottom: 0;
+ margin-top: 3px;
}
.nav-pills {
- li {
- padding: 3px 0;
- &.active a { background-color: $style_color; }
- a {
- @include border-radius(7px);
+ > li {
+ > a {
+ padding: 13px;
+ margin: 0;
+ font-size: 13px;
+ }
+ &.active {
+ > a {
+ background: #D5D5D5;
+ color: $style_color;
+ @include border-radius(0);
+ border-radius: 0;
+ border-left: 1px solid #CCC;
+ border-right: 1px solid #CCC;
+ }
}
}
}
}
- .bottom {
- @include bg-gray-gradient;
- @include border-radius(0 0 4px 4px);
- border-bottom: none;
- border-top: 1px solid #bbb;
- }
-
&.padded {
h5, .title {
margin: -20px;
@@ -143,6 +135,7 @@
color: #777;
}
}
+
.row_title {
font-weight: bold;
color: #444;
@@ -151,8 +144,4 @@
text-decoration: underline;
}
}
-
- .ui-box-body {
- padding: 10px;
- }
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
index 883a8773962..2b5ecce4246 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
@@ -7,6 +7,10 @@
color: #333;
}
+ &.btn-white {
+ background: #FFF;
+ }
+
&.primary {
background: #2a79A3;
@include linear-gradient(#47A7b7, #2585b5);
diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss
index 3bb7cdbf706..f088766afbd 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/common.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -17,20 +17,43 @@
.padded { padding:20px }
.ipadded { padding:20px!important }
.lborder { border-left:1px solid #eee }
-.no-padding { padding:0 !important; }
-.underlined { border-bottom: 1px solid #CCC; }
-.no-borders { border: none; }
-.vlink { color: $link_color !important; }
.underlined_link { text-decoration: underline; }
-.borders { border: 1px solid #ccc; @include shade; }
.hint { font-style: italic; color: #999; }
.light { color: #888 }
.tiny { font-weight: normal }
/** PILLS & TABS**/
-.nav-pills a:hover { background-color: #888; }
-.nav-pills .active a { background-color: $style_color; }
+.nav-pills {
+ .active a {
+ background: $primary_color;
+ }
+
+ > li > a {
+ @include border-radius(0);
+ }
+ &.nav-stacked {
+ > li > a {
+ border-left: 4px solid #EEE;
+ padding: 12px;
+ }
+ > .active > a {
+ border-color: #29B;
+ border-radius: 0;
+ background: #F1F1F1;
+ color: $style_color;
+ font-weight: bold;
+ }
+ }
+}
+
.nav-pills > .active > a > i[class^="icon-"] { background: inherit; }
+
+
+
+/**
+ * nav-tabs
+ *
+ */
.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; }
.nav.nav-tabs {
li {
diff --git a/app/assets/stylesheets/gitlab_bootstrap/fonts.scss b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss
index 88c966d18f7..b4217fa9cfa 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/fonts.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss
@@ -1,7 +1,7 @@
-@font-face{
- font-family: Korolev;
- src: font-url('korolev-medium-compressed.otf');
+@font-face{
+ font-family: Yanone;
+ src: font-url('YanoneKaffeesatz-Light.ttf');
}
/** Typo **/
-$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace; \ No newline at end of file
+$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
index edaf3cef2cf..0f893a553ee 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
@@ -23,14 +23,12 @@
border-bottom: 1px solid #ADF;
}
- &:first-child {
- @include border-radius(4px 4px 0 0);
- border-top: none;
- }
-
&:last-child {
- @include border-radius(0 0 4px 4px);
- border: none;
+ border-bottom: none;
+
+ &.bottom {
+ background: #f5f5f5;
+ }
}
.author { color: #999; }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/mixins.scss b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss
index 81830368c4c..9b1e2f2c728 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/mixins.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss
@@ -62,8 +62,8 @@
@mixin header-font {
color: $style_color;
text-shadow: 0 1px 1px #FFF;
- font-family: 'Korolev', sans-serif;
- font-size: 28px;
- line-height: 48px;
+ font-family: 'Yanone', sans-serif;
+ font-size: 26px;
+ line-height: 42px;
font-weight: normal;
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/tables.scss b/app/assets/stylesheets/gitlab_bootstrap/tables.scss
index 5905efd3aae..7a9eac82566 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/tables.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/tables.scss
@@ -25,7 +25,7 @@ table {
}
th, td {
- padding: 8px;
+ padding: 10px;
line-height: 18px;
text-align: left;
}
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 1cae7b0c6b1..c60aae49eaa 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -1,74 +1,17 @@
-.commit-box {
- @extend .main_box;
-
- .commit-head {
- @extend .top_box_content;
-
- .commit-title {
- line-height: 26px;
- margin: 0;
- }
-
- .commit-description {
- font-size: 14px;
- border: none;
- background-color: white;
- padding-top: 10px;
- }
-
- .browse-button {
- @extend .btn;
- @extend .btn-small;
- float: right;
- }
- }
-
- .commit-info {
- @extend .middle_box_content;
- @extend .clearfix;
-
- .sha-block {
- text-align: right;
- &:first-child {
- padding-bottom: 6px;
- }
-
- a {
- border-bottom: 1px solid #aaa;
- margin-left: 9px;
- }
- }
-
- &.merge-commit .sha-block {
- clear: right;
- }
-
- .committer {
- padding-left: 32px;
- }
-
- .author a,
- .committer a {
- font-size: 14px;
- line-height: 22px;
- text-shadow: 0 1px 1px #fff;
- color: #777;
- &:hover {
- color: #999;
- }
- }
-
- .avatar {
- margin-right: 10px;
- }
- }
-}
-
/**
*
* COMMIT SHOw
*
*/
+.commit-committer-link,
+.commit-author-link {
+ font-size: 13px;
+ color: #555;
+ &:hover {
+ color: #999;
+ }
+}
+
.diff_file {
border: 1px solid #CCC;
margin-bottom: 1em;
@@ -258,13 +201,6 @@
min-width: 65px;
font-family: $monospace;
}
-
- .commit-author-name {
- color: #777;
- &:hover {
- color: #999;
- }
- }
}
.diff_file_header a,
diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss
index 071a9c35468..2d41de25103 100644
--- a/app/assets/stylesheets/sections/events.scss
+++ b/app/assets/stylesheets/sections/events.scss
@@ -47,6 +47,12 @@
.event-info {
color: #666;
}
+ .event-note {
+ padding-top: 5px;
+ padding-left: 5px;
+ display: inline-block;
+ color: #777;
+ }
}
.avatar {
position: relative;
diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss
index c1b210be1ab..048a3ffcbb2 100644
--- a/app/assets/stylesheets/sections/header.scss
+++ b/app/assets/stylesheets/sections/header.scss
@@ -33,22 +33,29 @@ header {
*
*/
.app_logo {
- width: 170px;
float: left;
+ margin-right: 15px;
+ position: relative;
+ top: -5px;
+ padding-top: 5px;
+
a {
float: left;
padding: 0px;
+ margin: 0 10px;
h1 {
- width: 90px;
background: url('logo_dark.png') no-repeat 0px 2px;
float: left;
- margin-left: 2px;
- padding-left: 45px;
height: 40px;
+ width: 40px;
@include header-font;
+ text-indent: -9999px;
}
}
+ &:hover {
+ background-color: #EEE;
+ }
}
/**
@@ -60,7 +67,7 @@ header {
position: relative;
float: left;
margin: 0;
- margin-right: 30px;
+ margin-left: 15px;
@include header-font;
}
@@ -233,7 +240,7 @@ header {
.app_logo {
a {
h1 {
- background: url('logo_white.png') no-repeat 0px 2px;
+ background: url('logo_white.png') no-repeat center center;
color: #fff;
text-shadow: 0 1px 1px #111;
}
@@ -244,5 +251,23 @@ header {
text-shadow: 0 1px 1px #111;
}
}
+
+ .app_logo {
+ .separator {
+ margin-left: 0;
+ margin-right: 0;
+ }
+ }
+
+ .separator {
+ float: left;
+ height: 60px;
+ width: 1px;
+ background: white;
+ border-left: 1px solid #DDD;
+ margin-top: -10px;
+ margin-left: 10px;
+ margin-right: 10px;
+ }
}
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index fd995728978..351f2404492 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -1,34 +1,6 @@
-.issue_form_box {
- @extend .main_box;
- .issue_title {
- @extend .top_box_content;
- .clearfix {
- margin-bottom: 0px;
- input {
- @extend .span8;
- }
- }
- }
- .issue_middle_block {
- @extend .middle_box_content;
- height: 30px;
- .issue_assignee {
- @extend .span6;
- float: left;
- }
- .issue_milestone {
- @extend .span4;
- float: left;
- }
- }
- .issue_description {
- @extend .bottom_box_content;
- }
-}
-
.issues_table {
.issue {
- padding: 7px 10px;
+ padding: 10px;
.issue_check {
float: left;
@@ -82,38 +54,34 @@ input.check_all_issues {
}
}
-@media (min-width: 800px) { .issues_filters select { width: 160px; } }
-@media (min-width: 1000px) { .issues_filters select { width: 200px; } }
+@media (min-width: 800px) { .issues_filters select { width: 160px; } }
@media (min-width: 1200px) { .issues_filters select { width: 220px; } }
+@media (min-width: 800px) { .issues_bulk_update select { width: 120px; } }
+@media (min-width: 1200px) { .issues_bulk_update select { width: 160px; } }
#issues-table-holder {
.issues_filters {
- form {
- padding: 0;
- margin: 0;
- margin-top:7px
- }
}
.issues_bulk_update {
margin: 0;
form {
- padding: 0;
- margin: 0;
- margin-top:7px
+ float:left;
}
+
.update_selected_issues {
position: relative;
- top:-2px;
+ top:5px;
margin-left: 4px;
float: left;
}
.update_issues_text {
padding: 3px;
- line-height: 18px;
+ line-height: 28px;
float: left;
+ color: #479;
}
}
}
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index 4808117d02a..5225a242726 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -1,17 +1,3 @@
-/**
- * MR form
- *
- */
-
-.mr_branch_box {
- @extend .ui-box;
- margin-bottom: 20px;
-
- .body {
- background: #f1f1f1;
- }
-
-}
/**
* MR -> show: Automerge widget
@@ -47,6 +33,7 @@
}
label {
color: #444;
+ text-align: left
}
}
@@ -56,7 +43,7 @@
}
}
-.mr_nav_tabs {
+.merge-request .nav-tabs{
li {
a {
font-weight: bold;
@@ -67,7 +54,7 @@
}
li.merge_request {
- padding: 7px 10px;
+ padding: 10px;
img.avatar {
width: 32px;
margin-top: 1px;
@@ -78,7 +65,7 @@ li.merge_request {
}
}
-.merge_in_progress {
+.merge-in-progress {
@extend .padded;
@extend .append-bottom-10;
}
@@ -120,19 +107,3 @@ li.merge_request {
.mr_direction_tip {
margin-top:40px
}
-
-.merge_requests_form_box {
- @extend .main_box;
- .merge_requests_middle_box {
- @extend .middle_box_content;
- height: 30px;
- .merge_requests_assignee {
- @extend .span6;
- float: left;
- }
- .merge_requests_milestone {
- @extend .span4;
- float: left;
- }
- }
-}
diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss
index 465d578f3b7..93ad0d45037 100644
--- a/app/assets/stylesheets/sections/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -294,6 +294,8 @@ ul.notes {
padding: 4px 6px;
}
.note_text {
+ border: 1px solid #DDD;
+ box-shadow: none;
font-size: 14px;
height: 80px;
width: 98.6%;
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index 717f85024cc..072ade80ad3 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -8,16 +8,12 @@
.groups_box,
.projects_box {
- > h5 {
- color: $style_color;
- font-size: 16px;
- text-shadow: 0 1px 1px #fff;
- padding: 2px 10px;
- line-height: 32px;
- font-size: 14px;
+ > .title {
+ padding: 2px 15px;
}
.nav-projects-tabs li { padding: 0; }
.well-list {
+ li { padding: 15px; }
.arrow {
float: right;
padding: 10px;
@@ -109,7 +105,7 @@ ul.nav.nav-projects-tabs {
li {
a {
- padding: 4px 20px;
+ padding: 6px 25px;
margin-top: 2px;
border-color: #DDD;
background-color: #EEE;
diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss
index b377727779a..4e34e8b1b6b 100644
--- a/app/assets/stylesheets/themes/ui_basic.scss
+++ b/app/assets/stylesheets/themes/ui_basic.scss
@@ -4,21 +4,8 @@
*
*/
.ui_basic {
- .app_logo {
- .separator {
- margin-left: 0;
- margin-right: 0;
- }
- }
-
.separator {
- float: left;
- height: 60px;
- width: 1px;
background: white;
border-left: 1px solid #DDD;
- margin-top: -10px;
- margin-left: 10px;
- margin-right: 10px;
}
}
diff --git a/app/assets/stylesheets/themes/ui_color.scss b/app/assets/stylesheets/themes/ui_color.scss
index 8c60fabb3a7..d7a554ff9e5 100644
--- a/app/assets/stylesheets/themes/ui_color.scss
+++ b/app/assets/stylesheets/themes/ui_color.scss
@@ -17,6 +17,15 @@
&.navbar-gitlab {
.navbar-inner {
background: #657;
+ .app_logo {
+ &:hover {
+ background-color: #6A5A7A;
+ }
+ }
+ .separator {
+ background: #546;
+ border-left: 1px solid #706080;
+ }
}
}
}
diff --git a/app/assets/stylesheets/themes/ui_gray.scss b/app/assets/stylesheets/themes/ui_gray.scss
index e80137a69c8..f0547c72157 100644
--- a/app/assets/stylesheets/themes/ui_gray.scss
+++ b/app/assets/stylesheets/themes/ui_gray.scss
@@ -17,6 +17,15 @@
&.navbar-gitlab {
.navbar-inner {
background: #708090;
+ .app_logo {
+ &:hover {
+ background-color: #6A7A8A;
+ }
+ }
+ .separator {
+ background: #607080;
+ border-left: 1px solid #8090A0;
+ }
}
}
}
diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss
index 9e6433c5f9e..0a78c5c09f5 100644
--- a/app/assets/stylesheets/themes/ui_mars.scss
+++ b/app/assets/stylesheets/themes/ui_mars.scss
@@ -46,21 +46,26 @@
.app_logo {
a {
h1 {
- background: url('logo_white.png') no-repeat 0px 2px;
+ background: url('logo_white.png') no-repeat center center;
color: #eee;
text-shadow: 0 1px 1px #111;
}
}
- .separator {
- display: none;
+ &:hover {
+ background-color: #41464e;
}
-
}
.project_name {
color: #eee;
text-shadow: 0 1px 1px #111;
}
}
+
+ .separator {
+ background: #31363E;
+ border-left: 1px solid #666;
+ }
+
/*
* End of Application Header
*
diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss
index 32b5ad7d968..a5bf414c443 100644
--- a/app/assets/stylesheets/themes/ui_modern.scss
+++ b/app/assets/stylesheets/themes/ui_modern.scss
@@ -17,6 +17,15 @@
&.navbar-gitlab {
.navbar-inner {
background: #567;
+ .app_logo {
+ &:hover {
+ background-color: #516171;
+ }
+ }
+ .separator {
+ background: #456;
+ border-left: 1px solid #678;
+ }
}
}
}
diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb
index e43e5a07805..1f23f633af3 100644
--- a/app/contexts/commit_load_context.rb
+++ b/app/contexts/commit_load_context.rb
@@ -9,16 +9,16 @@ class CommitLoadContext < BaseContext
status: :ok
}
- commit = project.commit(params[:id])
+ commit = project.repository.commit(params[:id])
if commit
commit = CommitDecorator.decorate(commit)
- line_notes = project.commit_line_notes(commit)
+ line_notes = project.notes.for_commit_id(commit.id).inline
result[:commit] = commit
result[:note] = project.build_commit_note(commit)
result[:line_notes] = line_notes
- result[:notes_count] = line_notes.count + project.commit_notes(commit).count
+ result[:notes_count] = project.notes.for_commit_id(commit.id).count
begin
result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
diff --git a/app/contexts/filter_context.rb b/app/contexts/filter_context.rb
new file mode 100644
index 00000000000..401d19b31c8
--- /dev/null
+++ b/app/contexts/filter_context.rb
@@ -0,0 +1,31 @@
+class FilterContext
+ attr_accessor :items, :params
+
+ def initialize(items, params)
+ @items = items
+ @params = params
+ end
+
+ def execute
+ apply_filter(items)
+ end
+
+ def apply_filter items
+ if params[:project_id]
+ items = items.where(project_id: params[:project_id])
+ end
+
+ if params[:search].present?
+ items = items.search(params[:search])
+ end
+
+ case params[:status]
+ when 'closed'
+ items.closed
+ when 'all'
+ items
+ else
+ items.opened
+ end
+ end
+end
diff --git a/app/contexts/issues_list_context.rb b/app/contexts/issues_list_context.rb
index 9bbdfe1db39..0cc73f99535 100644
--- a/app/contexts/issues_list_context.rb
+++ b/app/contexts/issues_list_context.rb
@@ -4,7 +4,7 @@ class IssuesListContext < BaseContext
attr_accessor :issues
def execute
- @issues = case params[:f]
+ @issues = case params[:status]
when issues_filter[:all] then @project.issues
when issues_filter[:closed] then @project.issues.closed
when issues_filter[:to_me] then @project.issues.opened.assigned(current_user)
diff --git a/app/contexts/notes/load_context.rb b/app/contexts/notes/load_context.rb
index 4e2f35040fd..e3875e1d4e2 100644
--- a/app/contexts/notes/load_context.rb
+++ b/app/contexts/notes/load_context.rb
@@ -9,7 +9,7 @@ module Notes
@notes = case target_type
when "commit"
- project.commit_notes(project.commit(target_id)).fresh
+ project.notes.for_commit_id(target_id).not_inline.fresh
when "issue"
project.issues.find(target_id).notes.inc_author.fresh
when "merge_request"
@@ -18,7 +18,7 @@ module Notes
project.snippets.find(target_id).notes.fresh
when "wall"
# this is the only case, where the order is DESC
- project.common_notes.order("created_at DESC, id DESC").limit(50)
+ project.notes.common.inc_author_project.order("created_at DESC, id DESC").limit(50)
end
@notes = if after_id
diff --git a/app/contexts/test_hook_context.rb b/app/contexts/test_hook_context.rb
index cba5d1f87c2..d2d82a52cf5 100644
--- a/app/contexts/test_hook_context.rb
+++ b/app/contexts/test_hook_context.rb
@@ -1,7 +1,7 @@
class TestHookContext < BaseContext
def execute
hook = project.hooks.find(params[:id])
- commits = project.commits(project.default_branch, nil, 3)
+ commits = project.repository.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
hook.execute(data)
end
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index 827dd0cf7cd..f97c56b0b31 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -3,10 +3,6 @@ class Admin::DashboardController < AdminController
@projects = Project.order("created_at DESC").limit(10)
@users = User.order("created_at DESC").limit(10)
- @resque_accessible = true
- @workers = Resque.workers
- @pending_jobs = Resque.size(:post_receive)
-
rescue Redis::InheritedError
@resque_accessible = false
end
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index a492e66611f..90dbda3eeea 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -1,5 +1,5 @@
class Admin::GroupsController < AdminController
- before_filter :group, only: [:edit, :show, :update, :destroy, :project_update]
+ before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :project_teams_update]
def index
@groups = Group.order('name ASC')
@@ -12,6 +12,8 @@ class Admin::GroupsController < AdminController
@projects = @projects.not_in_group(@group) if @group.projects.present?
@projects = @projects.all
@projects.reject!(&:empty_repo?)
+
+ @users = User.active
end
def new
@@ -65,7 +67,14 @@ class Admin::GroupsController < AdminController
redirect_to :back, notice: 'Group was successfully updated.'
end
+ def project_teams_update
+ @group.add_users_to_project_teams(params[:user_ids], params[:project_access])
+ redirect_to [:admin, @group], notice: 'Users was successfully added.'
+ end
+
def destroy
+ @group.truncate_teams
+
@group.destroy
redirect_to admin_groups_path, notice: 'Group was successfully deleted.'
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 4fea8709b70..d5e6f3cdc0e 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -10,6 +10,7 @@ class Admin::ProjectsController < AdminController
end
def show
+ @repository = @project.repository
@users = User.active
@users = @users.not_in_project(@project) if @project.users.present?
@users = @users.all
@@ -19,7 +20,7 @@ class Admin::ProjectsController < AdminController
end
def team_update
- @project.add_users_ids_to_team(params[:user_ids], params[:project_access])
+ @project.team.add_users_ids(params[:user_ids], params[:project_access])
redirect_to [:admin, @project], notice: 'Project was successfully updated.'
end
@@ -35,6 +36,9 @@ class Admin::ProjectsController < AdminController
end
def destroy
+ # Delete team first in order to prevent multiple gitolite calls
+ @project.team.truncate
+
@project.destroy
redirect_to admin_projects_path, notice: 'Project was successfully deleted.'
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 5f259bd7e27..8669f5d1d38 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -3,13 +3,13 @@ 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("name ASC").page(params[:page])
+ @admin_users = @admin_users.alphabetically.page(params[:page])
end
def show
@admin_user = User.find(params[:id])
- @projects = if @admin_user.projects.empty?
+ @projects = if @admin_user.authorized_projects.empty?
Project
else
Project.without_user(@admin_user)
@@ -19,9 +19,9 @@ class Admin::UsersController < AdminController
def team_update
@admin_user = User.find(params[:id])
- UsersProject.user_bulk_import(
- @admin_user,
+ UsersProject.add_users_into_projects(
params[:project_ids],
+ [@admin_user.id],
params[:project_access]
)
@@ -98,7 +98,7 @@ class Admin::UsersController < AdminController
def destroy
@admin_user = User.find(params[:id])
- if @admin_user.my_own_projects.count > 0
+ if @admin_user.personal_projects.count > 0
redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return
end
@admin_user.destroy
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 75cd8f15605..3457a1ab1b4 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -76,6 +76,12 @@ class ApplicationController < ActionController::Base
end
end
+ def repository
+ @repository ||= project.repository
+ rescue Grit::NoSuchPathError
+ nil
+ end
+
def add_abilities
abilities << Ability
end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 3b8ebdb5ddc..534ae1edd31 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -9,10 +9,10 @@ class CommitsController < ProjectResourceController
before_filter :require_non_empty_project
def show
- @repo = @project.repo
+ @repo = @project.repository
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
- @commits = @project.commits(@ref, @path, @limit, @offset)
+ @commits = @repo.commits(@ref, @path, @limit, @offset)
@commits = CommitDecorator.decorate(@commits)
respond_to do |format|
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 1fcadbfefba..c0ec4708e0a 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -20,7 +20,7 @@ class DashboardController < ApplicationController
@projects = @projects.page(params[:page]).per(30)
- @events = Event.in_projects(current_user.project_ids)
+ @events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@@ -36,14 +36,14 @@ class DashboardController < ApplicationController
# Get authored or assigned open merge requests
def merge_requests
@merge_requests = current_user.cared_merge_requests
- @merge_requests = dashboard_filter(@merge_requests)
+ @merge_requests = FilterContext.new(@merge_requests, params).execute
@merge_requests = @merge_requests.recent.page(params[:page]).per(20)
end
# Get only assigned issues
def issues
@issues = current_user.assigned_issues
- @issues = dashboard_filter(@issues)
+ @issues = FilterContext.new(@issues, params).execute
@issues = @issues.recent.page(params[:page]).per(20)
@issues = @issues.includes(:author, :project)
@@ -60,25 +60,7 @@ class DashboardController < ApplicationController
end
def event_filter
- @event_filter ||= EventFilter.new(params[:event_filter])
- end
-
- def dashboard_filter items
- if params[:project_id]
- items = items.where(project_id: params[:project_id])
- end
-
- if params[:search].present?
- items = items.search(params[:search])
- end
-
- case params[:status]
- when 'closed'
- items.closed
- when 'all'
- items
- else
- items.opened
- end
+ filters = cookies['event_filter'].split(',') if cookies['event_filter']
+ @event_filter ||= EventFilter.new(filters)
end
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index c82edb4c168..c25fc32a62c 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -21,15 +21,16 @@ class GroupsController < ApplicationController
# Get authored or assigned open merge requests
def merge_requests
- @merge_requests = current_user.cared_merge_requests.opened
- @merge_requests = @merge_requests.of_group(@group).recent.page(params[:page]).per(20)
+ @merge_requests = current_user.cared_merge_requests.of_group(@group)
+ @merge_requests = FilterContext.new(@merge_requests, params).execute
+ @merge_requests = @merge_requests.recent.page(params[:page]).per(20)
end
# Get only assigned issues
def issues
- @user = current_user
- @issues = current_user.assigned_issues.opened
- @issues = @issues.of_group(@group).recent.page(params[:page]).per(20)
+ @issues = current_user.assigned_issues.of_group(@group)
+ @issues = FilterContext.new(@issues, params).execute
+ @issues = @issues.recent.page(params[:page]).per(20)
@issues = @issues.includes(:author, :project)
respond_to do |format|
@@ -44,6 +45,7 @@ class GroupsController < ApplicationController
@projects = result[:projects]
@merge_requests = result[:merge_requests]
@issues = result[:issues]
+ @wiki_pages = result[:wiki_pages]
end
def people
@@ -53,9 +55,16 @@ class GroupsController < ApplicationController
if @project
@team_member = @project.users_projects.new
+ else
+ @team_member = UsersProject.new
end
end
+ def team_members
+ @group.add_users_to_project_teams(params[:user_ids], params[:project_access])
+ redirect_to people_group_path(@group), notice: 'Users was successfully added.'
+ end
+
protected
def group
@@ -63,7 +72,7 @@ class GroupsController < ApplicationController
end
def projects
- @projects ||= group.projects.authorized_for(current_user).sorted_by_activity
+ @projects ||= current_user.authorized_projects.where(namespace_id: group.id).sorted_by_activity
end
def project_ids
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 355f4d79d67..ab6bf595982 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -74,6 +74,8 @@ class MergeRequestsController < ProjectResourceController
@merge_request.check_if_can_be_merged
end
render json: {state: @merge_request.human_state}
+ rescue Gitlab::SatelliteNotExistError
+ render json: {state: :no_satellite}
end
def automerge
@@ -88,12 +90,12 @@ class MergeRequestsController < ProjectResourceController
end
def branch_from
- @commit = project.commit(params[:ref])
+ @commit = @repository.commit(params[:ref])
@commit = CommitDecorator.decorate(@commit)
end
def branch_to
- @commit = project.commit(params[:ref])
+ @commit = @repository.commit(params[:ref])
@commit = CommitDecorator.decorate(@commit)
end
diff --git a/app/controllers/project_resource_controller.rb b/app/controllers/project_resource_controller.rb
index 81bc3a91bd1..ea78b3ff7c4 100644
--- a/app/controllers/project_resource_controller.rb
+++ b/app/controllers/project_resource_controller.rb
@@ -1,3 +1,4 @@
class ProjectResourceController < ApplicationController
before_filter :project
+ before_filter :repository
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 17b0921ba6c..6f1180eaa6b 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -2,6 +2,7 @@ require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
class ProjectsController < ProjectResourceController
skip_before_filter :project, only: [:new, :create]
+ skip_before_filter :repository, only: [:new, :create]
# Authorize
before_filter :authorize_read_project!, except: [:index, :new, :create]
@@ -58,7 +59,7 @@ class ProjectsController < ProjectResourceController
respond_to do |format|
format.html do
- unless @project.empty_repo?
+ if @project.repository && !@project.repository.empty?
@last_push = current_user.recent_push(@project.id)
render :show
else
@@ -102,11 +103,10 @@ class ProjectsController < ProjectResourceController
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)
+ # Delete team first in order to prevent multiple gitolite calls
+ project.team.truncate
+
project.destroy
- UsersProject.set_callback(:destroy, :after, :update_repository)
respond_to do |format|
format.html { redirect_to root_path }
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index b48d5ec7027..09d9eb51b82 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -12,7 +12,7 @@ class RefsController < ProjectResourceController
respond_to do |format|
format.html do
new_path = if params[:destination] == "tree"
- project_tree_path(@project, @ref)
+ project_tree_path(@project, (@ref + "/" + params[:path]))
else
project_commits_path(@project, @ref)
end
@@ -31,7 +31,7 @@ class RefsController < ProjectResourceController
contents = @tree.contents
@logs = contents.map do |content|
file = params[:path] ? File.join(params[:path], content.name) : content.name
- last_commit = @project.commits(@commit.id, file, 1).last
+ last_commit = @repo.commits(@commit.id, file, 1).last
last_commit = CommitDecorator.decorate(last_commit)
{
file_name: content.name,
@@ -45,10 +45,10 @@ class RefsController < ProjectResourceController
def define_tree_vars
params[:path] = nil if params[:path].blank?
- @repo = project.repo
- @commit = project.commit(@ref)
+ @repo = project.repository
+ @commit = @repo.commit(@ref)
@commit = CommitDecorator.decorate(@commit)
- @tree = Tree.new(@commit.tree, project, @ref, params[:path])
+ @tree = Tree.new(@commit.tree, @ref, params[:path])
@tree = TreeDecorator.new(@tree)
@hex_path = Digest::SHA1.hexdigest(params[:path] || "")
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 7678fbff3f1..229cb36949b 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -5,19 +5,19 @@ class RepositoriesController < ProjectResourceController
before_filter :require_non_empty_project
def show
- @activities = @project.commits_with_refs(20)
+ @activities = @repository.commits_with_refs(20)
end
def branches
- @branches = @project.branches
+ @branches = @repository.branches
end
def tags
- @tags = @project.tags
+ @tags = @repository.tags
end
def stats
- @stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
+ @stats = Gitlab::GitStats.new(@repository.raw, @repository.root_ref)
@graph = @stats.graph
end
@@ -27,7 +27,7 @@ class RepositoriesController < ProjectResourceController
end
- file_path = @project.archive_repo(params[:ref])
+ file_path = @repository.archive_repo(params[:ref])
if file_path
# Send file to user
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 4f45f9ddccb..a23292396a0 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,6 +1,6 @@
class SearchController < ApplicationController
def show
- result = SearchContext.new(current_user.project_ids, params).execute
+ result = SearchContext.new(current_user.authorized_projects.map(&:id), params).execute
@projects = result[:projects]
@merge_requests = result[:merge_requests]
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index 50f7e97af9f..d0df469b967 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -26,7 +26,7 @@ class ServicesController < ProjectResourceController
end
def test
- commits = project.commits(project.default_branch, nil, 3)
+ commits = project.repository.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
@service = project.gitlab_ci_service
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 977524a4db8..26898abfa82 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.fresh
+ @snippets = @project.snippets.fresh.non_expired
end
def new
diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb
index 311af62b8db..8378a8458ff 100644
--- a/app/controllers/team_members_controller.rb
+++ b/app/controllers/team_members_controller.rb
@@ -16,10 +16,9 @@ class TeamMembersController < ProjectResourceController
end
def create
- @project.add_users_ids_to_team(
- params[:user_ids],
- params[:project_access]
- )
+ users = User.where(id: params[:user_ids])
+
+ @project.team << [users, params[:project_access]]
if params[:redirect_to]
redirect_to params[:redirect_to]
@@ -50,7 +49,7 @@ class TeamMembersController < ProjectResourceController
def apply_import
giver = Project.find(params[:source_project_id])
- status = UsersProject.import_team(giver, project)
+ status = @project.team.import(giver)
notice = status ? "Succesfully imported" : "Import failed"
redirect_to project_team_members_path(project), notice: notice
diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb
index 725f48fa014..2151bd7cbbd 100644
--- a/app/controllers/tree_controller.rb
+++ b/app/controllers/tree_controller.rb
@@ -22,7 +22,7 @@ class TreeController < ProjectResourceController
end
def edit
- @last_commit = @project.last_commit_for(@ref, @path).sha
+ @last_commit = @project.repository.last_commit_for(@ref, @path).sha
end
def update
diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb
index c12227afb5d..0e760f97dee 100644
--- a/app/decorators/tree_decorator.rb
+++ b/app/decorators/tree_decorator.rb
@@ -6,16 +6,14 @@ class TreeDecorator < ApplicationDecorator
part_path = ""
parts = path.split("\/")
- #parts = parts[0...-1] if is_blob?
-
- yield(h.link_to("..", "#")) if parts.count > max_links
+ yield('..', nil) if parts.count > max_links
parts.each do |part|
part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links
- yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
+ yield(part, h.tree_join(ref, part_path))
end
end
end
@@ -26,7 +24,7 @@ class TreeDecorator < ApplicationDecorator
def up_dir_path
file = File.join(path, "..")
- h.project_tree_path(project, h.tree_join(ref, file))
+ h.tree_join(ref, file)
end
def readme
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 52715a265bd..a1eea96be43 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -53,7 +53,7 @@ module ApplicationHelper
def last_commit(project)
if project.repo_exists?
- time_ago_in_words(project.commit.committed_date) + " ago"
+ time_ago_in_words(project.repository.commit.committed_date) + " ago"
else
"Never"
end
@@ -62,9 +62,11 @@ module ApplicationHelper
end
def grouped_options_refs(destination = :tree)
+ repository = @project.repository
+
options = [
- ["Branch", @project.branch_names ],
- [ "Tag", @project.tag_names ]
+ ["Branch", repository.branch_names ],
+ [ "Tag", repository.tag_names ]
]
# If reference is commit id -
@@ -78,7 +80,8 @@ module ApplicationHelper
end
def search_autocomplete_source
- projects = current_user.projects.map{ |p| { label: p.name_with_namespace, url: project_path(p) } }
+ projects = current_user.authorized_projects.map { |p| { label: p.name_with_namespace, url: project_path(p) } }
+ groups = current_user.authorized_groups.map { |group| { label: "<group> #{group.name}", url: group_path(group) } }
default_nav = [
{ label: "My Profile", url: profile_path },
@@ -99,21 +102,21 @@ module ApplicationHelper
]
project_nav = []
- if @project && !@project.new_record?
+ if @project && @project.repository && @project.repository.root_ref
project_nav = [
{ label: "#{@project.name} Issues", url: project_issues_path(@project) },
- { label: "#{@project.name} Commits", url: project_commits_path(@project, @ref || @project.root_ref) },
+ { label: "#{@project.name} Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) },
{ label: "#{@project.name} Merge Requests", url: project_merge_requests_path(@project) },
{ label: "#{@project.name} Milestones", url: project_milestones_path(@project) },
{ label: "#{@project.name} Snippets", url: project_snippets_path(@project) },
{ label: "#{@project.name} Team", url: project_team_index_path(@project) },
- { label: "#{@project.name} Tree", url: project_tree_path(@project, @ref || @project.root_ref) },
+ { label: "#{@project.name} Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) },
{ label: "#{@project.name} Wall", url: wall_project_path(@project) },
{ label: "#{@project.name} Wiki", url: project_wikis_path(@project) },
]
end
- [projects, default_nav, project_nav, help_nav].flatten.to_json
+ [groups, projects, default_nav, project_nav, help_nav].flatten.to_json
end
def emoji_autocomplete_source
@@ -139,6 +142,7 @@ module ApplicationHelper
event.last_push_to_non_root? &&
!event.rm_ref? &&
event.project &&
+ event.project.repository &&
event.project.merge_requests_enabled
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 2349888ed7a..8fc637a2bf6 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -70,4 +70,12 @@ module CommitsHelper
escape_javascript(render 'commits/commit', commit: commit)
end
end
+
+ def diff_line_content(line)
+ if line.blank?
+ " &nbsp;"
+ else
+ line
+ end
+ end
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index a2548a23e5e..9b9d2a913e9 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -20,25 +20,8 @@ module EventsHelper
[event.action_name, target].join(" ")
end
- def event_image event
- event_image_path = if event.push?
- "event_push.png"
- elsif event.merged?
- "event_mr_merged.png"
- end
-
- return nil unless event_image_path
-
- content_tag :div, class: 'event_icon' do
- image_tag event_image_path
- end
- end
-
def event_filter_link key, tooltip
key = key.to_s
-
- filter = @event_filter.options key
-
inactive = if @event_filter.active? key
nil
else
@@ -46,7 +29,7 @@ module EventsHelper
end
content_tag :div, class: "filter_icon #{inactive}" do
- link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do
+ link_to dashboard_path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
image_tag "event_filter_#{key}.png"
end
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
new file mode 100644
index 00000000000..283119bc24c
--- /dev/null
+++ b/app/helpers/groups_helper.rb
@@ -0,0 +1,17 @@
+module GroupsHelper
+ def group_filter_path(entity, options={})
+ exist_opts = {
+ status: params[:status],
+ project_id: params[:project_id],
+ }
+
+ options = exist_opts.merge(options)
+
+ case entity
+ when 'issue' then
+ issues_group_path(@group, options)
+ when 'merge_request'
+ merge_requests_group_path(@group, options)
+ end
+ end
+end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index f48425bd6de..ca0a89c3749 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -4,7 +4,7 @@ module MergeRequestsHelper
event.project,
merge_request: {
source_branch: event.branch_name,
- target_branch: event.project.root_ref,
+ target_branch: event.project.repository.root_ref,
title: event.branch_name.titleize
}
)
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index fdf6725cc13..2d25c8f854d 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -1,6 +1,6 @@
module NamespacesHelper
def namespaces_options(selected = :current_user, scope = :default)
- groups = current_user.namespaces.select {|n| n.type == 'Group'}
+ groups = current_user.owned_groups.select {|n| n.type == 'Group'}
users = if scope == :all
Namespace.root
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 7d68e50b382..706d7a8e4ed 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -1,11 +1,12 @@
class Notify < ActionMailer::Base
- include Resque::Mailer
+
add_template_helper ApplicationHelper
add_template_helper GitlabMarkdownHelper
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_url_options[:script_name] = Gitlab.config.gitlab.relative_url_root
default from: Gitlab.config.gitlab.email_from
@@ -87,7 +88,7 @@ class Notify < ActionMailer::Base
def note_wall_email(recipient_id, note_id)
@note = Note.find(note_id)
@project = @note.project
- mail(to: recipient(recipient_id), subject: subject)
+ mail(to: recipient(recipient_id), subject: subject("note on wall"))
end
@@ -147,12 +148,15 @@ class Notify < ActionMailer::Base
# >> @project = Project.last
# => #<Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
# >> subject('Lorem ipsum')
- # => "GitLab | Lorem ipsum | Ruby on Rails"
+ # => "GitLab | Ruby on Rails | Lorem ipsum "
#
# # Accepts multiple arguments
# >> subject('Lorem ipsum', 'Dolor sit amet')
# => "GitLab | Lorem ipsum | Dolor sit amet"
def subject(*extra)
- "GitLab | " << extra.join(' | ') << (@project ? " | #{@project.name}" : "")
+ subject = "GitLab"
+ subject << (@project ? " | #{@project.name_with_namespace}" : "")
+ subject << " | " + extra.join(' | ') if extra.present?
+ subject
end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 2d80c6720b7..256af1e800b 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -15,35 +15,26 @@ class Ability
def project_abilities(user, project)
rules = []
+ team = project.team
+
# Rules based on role in project
- if project.master_access_for?(user)
+ if team.masters.include?(user)
rules << project_master_rules
- elsif project.dev_access_for?(user)
+ elsif team.developers.include?(user)
rules << project_dev_rules
- elsif project.report_access_for?(user)
+ elsif team.reporters.include?(user)
rules << project_report_rules
- elsif project.guest_access_for?(user)
+ elsif team.guests.include?(user)
rules << project_guest_rules
end
- if project.namespace
- # If user own project namespace
- # (Ex. group owner or account owner)
- if project.namespace.owner == user
- rules << project_admin_rules
- end
- else
- # For compatibility with global projects
- # use projects.owner_id
- if project.owner == user
- rules << project_admin_rules
- end
+ if project.owner == user
+ rules << project_admin_rules
end
-
rules.flatten
end
@@ -107,9 +98,12 @@ class Ability
def group_abilities user, group
rules = []
- rules << [
- :manage_group
- ] if group.owner == user
+ # Only group owner and administrators can manage group
+ if group.owner == user || user.admin?
+ rules << [
+ :manage_group
+ ]
+ end
rules.flatten
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index f11b7fe0202..17d41f27f34 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -11,7 +11,7 @@ class Commit
attr_accessor :commit, :head, :refs
delegate :message, :authored_date, :committed_date, :parents, :sha,
- :date, :committer, :author, :message, :diffs, :tree, :id,
+ :date, :committer, :author, :diffs, :tree, :id, :stats,
:to_patch, to: :commit
class << self
@@ -83,8 +83,8 @@ class Commit
return result unless from && to
- first = project.commit(to.try(:strip))
- last = project.commit(from.try(:strip))
+ first = project.repository.commit(to.try(:strip))
+ last = project.repository.commit(from.try(:strip))
if first && last
result[:same] = (first.id == last.id)
@@ -98,6 +98,8 @@ class Commit
end
def initialize(raw_commit, head = nil)
+ raise "Nil as raw commit passed" unless raw_commit
+
@commit = raw_commit
@head = head
end
@@ -136,17 +138,17 @@ class Commit
end
def prev_commit
- parents.try :first
+ @prev_commit ||= if parents.present?
+ Commit.new(parents.first)
+ else
+ nil
+ end
end
def prev_commit_id
prev_commit.try :id
end
- def parents_count
- parents && parents.count || 0
- end
-
# Shows the diff between the commit's parent and the commit.
#
# Cuts out the header and stats from #to_patch and returns only the diff.
diff --git a/app/roles/issue_commonality.rb b/app/models/concerns/issuable.rb
index 79831cdca67..d1717d3bbee 100644
--- a/app/roles/issue_commonality.rb
+++ b/app/models/concerns/issuable.rb
@@ -1,5 +1,10 @@
+# == Issuable concern
+#
# Contains common functionality shared between Issues and MergeRequests
-module IssueCommonality
+#
+# Used by Issue, MergeRequest
+#
+module Issuable
extend ActiveSupport::Concern
included do
@@ -64,4 +69,38 @@ module IssueCommonality
closed_changed? && !closed
end
+ #
+ # Votes
+ #
+
+ # Return the number of -1 comments (downvotes)
+ def downvotes
+ notes.select(&:downvote?).size
+ end
+
+ def downvotes_in_percent
+ if votes_count.zero?
+ 0
+ else
+ 100.0 - upvotes_in_percent
+ end
+ end
+
+ # Return the number of +1 comments (upvotes)
+ def upvotes
+ notes.select(&:upvote?).size
+ end
+
+ def upvotes_in_percent
+ if votes_count.zero?
+ 0
+ else
+ 100.0 / votes_count * upvotes
+ end
+ end
+
+ # Return the total number of votes
+ def votes_count
+ upvotes + downvotes
+ end
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 90376e73753..d0ba61544d1 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -15,9 +15,6 @@
#
class Event < ActiveRecord::Base
- include NoteEvent
- include PushEvent
-
attr_accessible :project, :action, :data, :author_id, :project_id,
:target_id, :target_type
@@ -113,26 +110,6 @@ class Event < ActiveRecord::Base
target_type == "MergeRequest"
end
- def new_issue?
- target_type == "Issue" &&
- action == Created
- end
-
- def new_merge_request?
- target_type == "MergeRequest" &&
- action == Created
- end
-
- def changed_merge_request?
- target_type == "MergeRequest" &&
- [Closed, Reopened].include?(action)
- end
-
- def changed_issue?
- target_type == "Issue" &&
- [Closed, Reopened].include?(action)
- end
-
def joined?
action == Joined
end
@@ -170,4 +147,143 @@ class Event < ActiveRecord::Base
"opened"
end
end
+
+ def valid_push?
+ data[:ref]
+ rescue => ex
+ false
+ end
+
+ def tag?
+ data[:ref]["refs/tags"]
+ end
+
+ def branch?
+ data[:ref]["refs/heads"]
+ end
+
+ def new_branch?
+ commit_from =~ /^00000/
+ end
+
+ def new_ref?
+ commit_from =~ /^00000/
+ end
+
+ def rm_ref?
+ commit_to =~ /^00000/
+ end
+
+ def md_ref?
+ !(rm_ref? || new_ref?)
+ end
+
+ def commit_from
+ data[:before]
+ end
+
+ def commit_to
+ data[:after]
+ end
+
+ def ref_name
+ if tag?
+ tag_name
+ else
+ branch_name
+ end
+ end
+
+ def branch_name
+ @branch_name ||= data[:ref].gsub("refs/heads/", "")
+ end
+
+ def tag_name
+ @tag_name ||= data[:ref].gsub("refs/tags/", "")
+ end
+
+ # Max 20 commits from push DESC
+ def commits
+ @commits ||= data[:commits].map { |commit| repository.commit(commit[:id]) }.reverse
+ end
+
+ def commits_count
+ data[:total_commits_count] || commits.count || 0
+ end
+
+ def ref_type
+ tag? ? "tag" : "branch"
+ end
+
+ def push_action_name
+ if new_ref?
+ "pushed new"
+ elsif rm_ref?
+ "deleted"
+ else
+ "pushed to"
+ end
+ end
+
+ def repository
+ project.repository
+ end
+
+ def parent_commit
+ repository.commit(commit_from)
+ rescue => ex
+ nil
+ end
+
+ def last_commit
+ repository.commit(commit_to)
+ rescue => ex
+ nil
+ end
+
+ def push_with_commits?
+ md_ref? && commits.any? && parent_commit && last_commit
+ rescue Grit::NoSuchPathError
+ false
+ end
+
+ def last_push_to_non_root?
+ branch? && project.default_branch != branch_name
+ end
+
+ 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/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb
index a2f5634a86f..4eb39c7ef4d 100644
--- a/app/models/gitlab_ci_service.rb
+++ b/app/models/gitlab_ci_service.rb
@@ -23,20 +23,12 @@ class GitlabCiService < Service
after_save :compose_service_hook, if: :activated?
- def activated?
- active
- end
-
def compose_service_hook
hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.save
end
- 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
diff --git a/app/models/group.rb b/app/models/group.rb
index b668f5560ab..8ba92980a9b 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -12,6 +12,14 @@
#
class Group < Namespace
+ def add_users_to_project_teams(user_ids, project_access)
+ UsersProject.add_users_into_projects(
+ projects.map(&:id),
+ user_ids,
+ project_access
+ )
+ end
+
def users
users = User.joins(:users_projects).where(users_projects: {project_id: project_ids})
users = users << owner
@@ -21,4 +29,8 @@ class Group < Namespace
def human_name
name
end
+
+ def truncate_teams
+ UsersProject.truncate_teams(project_ids)
+ end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 1de9d0f9ebc..7381136c979 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -17,8 +17,7 @@
#
class Issue < ActiveRecord::Base
- include IssueCommonality
- include Votes
+ include Issuable
attr_accessible :title, :assignee_id, :closed, :position, :description,
:milestone_id, :label_list, :author_id_of_changes
diff --git a/app/models/key.rb b/app/models/key.rb
index 5dac1c1c9fd..2bf50f56565 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -73,7 +73,7 @@ class Key < ActiveRecord::Base
if is_deploy_key
[project]
else
- user.projects
+ user.authorized_projects
end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 052e0850d96..b6ea85f6507 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -20,11 +20,10 @@
#
require Rails.root.join("app/models/commit")
-require Rails.root.join("app/roles/static_model")
+require Rails.root.join("lib/static_model")
class MergeRequest < ActiveRecord::Base
- include IssueCommonality
- include Votes
+ include Issuable
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id,
:author_id_of_changes
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 4fac9bec259..8b4c895dc17 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -29,7 +29,7 @@ class Milestone < ActiveRecord::Base
def expired?
if due_date
- due_date < Date.today
+ due_date.past?
else
false
end
@@ -58,7 +58,13 @@ class Milestone < ActiveRecord::Base
end
def expires_at
- "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
+ if due_date
+ if due_date.past?
+ "expired at #{due_date.stamp("Aug 21, 2011")}"
+ else
+ "expires at #{due_date.stamp("Aug 21, 2011")}"
+ end
+ end
end
def can_be_closed?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 8c90f5aee26..89c1f9adb5a 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -27,10 +27,13 @@ class Namespace < ActiveRecord::Base
after_create :ensure_dir_exist
after_update :move_dir
+ after_commit :update_gitolite, on: :update, if: :require_update_gitolite
after_destroy :rm_dir
scope :root, where('type IS NULL')
+ attr_accessor :require_update_gitolite
+
def self.search query
where("name LIKE :query OR path LIKE :query", query: "%#{query}%")
end
@@ -48,8 +51,17 @@ class Namespace < ActiveRecord::Base
end
def ensure_dir_exist
- namespace_dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
- system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path)
+ unless dir_exists?
+ FileUtils.mkdir( namespace_full_path, mode: 0770 )
+ end
+ end
+
+ def dir_exists?
+ File.exists?(namespace_full_path)
+ end
+
+ def namespace_full_path
+ @namespace_full_path ||= File.join(Gitlab.config.gitolite.repos_path, path)
end
def move_dir
@@ -59,16 +71,25 @@ class Namespace < ActiveRecord::Base
if File.exists?(new_path)
raise "Already exists"
end
-
- if system("mv #{old_path} #{new_path}")
+
+ begin
+ FileUtils.mv( old_path, new_path )
send_update_instructions
+ @require_update_gitolite = true
+ rescue Exception => e
+ raise "Namespace move error #{old_path} #{new_path}"
end
end
end
+ def update_gitolite
+ @require_update_gitolite = false
+ projects.each(&:update_repository)
+ end
+
def rm_dir
dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
- system("rm -rf #{dir_path}")
+ FileUtils.rm_r( dir_path, force: true )
end
def send_update_instructions
diff --git a/app/models/note.rb b/app/models/note.rb
index b62b3fe61d5..3ad03cc601b 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -4,7 +4,6 @@
#
# id :integer not null, primary key
# note :text
-# noteable_id :string(255)
# noteable_type :string(255)
# author_id :integer
# created_at :datetime not null
@@ -12,6 +11,8 @@
# project_id :integer
# attachment :string(255)
# line_code :string(255)
+# commit_id :string(255)
+# noteable_id :integer
#
require 'carrierwave/orm/activerecord'
@@ -41,11 +42,11 @@ class Note < ActiveRecord::Base
mount_uploader :attachment, AttachmentUploader
# Scopes
- 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)) }
+ scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
+ scope :inline, where("line_code IS NOT NULL")
+ scope :not_inline, where("line_code IS NULL")
+
+ scope :common, ->{ where(noteable_type: ["", nil]) }
scope :fresh, ->{ order("created_at ASC, id ASC") }
scope :inc_author_project, ->{ includes(:project, :author) }
scope :inc_author, ->{ includes(:author) }
@@ -126,7 +127,7 @@ class Note < ActiveRecord::Base
# override to return commits, which are not active record
def noteable
if for_commit?
- project.commit(commit_id)
+ project.repository.commit(commit_id)
else
super
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 251f497548e..32b951349a9 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -9,7 +9,7 @@
# created_at :datetime not null
# updated_at :datetime not null
# private_flag :boolean default(TRUE), not null
-# owner_id :integer
+# creator_id :integer
# default_branch :string(255)
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
@@ -21,18 +21,14 @@
require "grit"
class Project < ActiveRecord::Base
- include Repository
- include PushObserver
- include Authority
- include Team
- include NamespacedProject
+ include Gitolited
class TransferError < StandardError; end
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
- attr_accessible :namespace_id, :owner_id, as: :admin
+ attr_accessible :namespace_id, :creator_id, as: :admin
attr_accessor :error_code
@@ -40,10 +36,10 @@ class Project < ActiveRecord::Base
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"
+ belongs_to :creator,
+ class_name: "User",
+ foreign_key: "creator_id"
+
has_many :users, through: :users_projects
has_many :events, dependent: :destroy
has_many :merge_requests, dependent: :destroy
@@ -62,9 +58,11 @@ class Project < ActiveRecord::Base
delegate :name, to: :owner, allow_nil: true, prefix: true
# Validations
- validates :owner, presence: true
+ validates :creator, presence: true
validates :description, length: { within: 0..2000 }
- validates :name, presence: true, length: { within: 0..255 }
+ validates :name, presence: true, length: { within: 0..255 },
+ format: { with: Gitlab::Regex.project_name_regex,
+ message: "only letters, digits, spaces & '_' '-' '.' allowed. Letter should be first" }
validates :path, presence: true, length: { within: 0..255 },
format: { with: Gitlab::Regex.path_regex,
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
@@ -77,19 +75,14 @@ class Project < ActiveRecord::Base
validate :check_limit, :repo_name
# Scopes
- scope :public_only, where(private_flag: false)
- scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.projects.map(&:id) ) }
+ scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) }
scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) }
+ scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
class << self
- def authorized_for user
- projects = includes(:users_projects, :namespace)
- projects = projects.where("users_projects.user_id = :user_id or projects.owner_id = :user_id or namespaces.owner_id = :user_id", user_id: user.id)
- end
-
def active
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
end
@@ -101,8 +94,10 @@ class Project < ActiveRecord::Base
def find_with_namespace(id)
if id.include?("/")
id = id.split("/")
- namespace_id = Namespace.find_by_path(id.first).id
- where(namespace_id: namespace_id).find_by_path(id.last)
+ namespace = Namespace.find_by_path(id.first)
+ return nil unless namespace
+
+ where(namespace_id: namespace.id).find_by_path(id.second)
else
where(path: id, namespace_id: nil).last
end
@@ -122,7 +117,7 @@ class Project < ActiveRecord::Base
#
project.path = project.name.dup.parameterize
- project.owner = user
+ project.creator = user
# Apply namespace if user has access to it
# else fallback to user namespace
@@ -162,6 +157,20 @@ class Project < ActiveRecord::Base
end
end
+ def team
+ @team ||= Team.new(self)
+ end
+
+ def repository
+ if path
+ @repository ||= Repository.new(path_with_namespace, default_branch)
+ else
+ nil
+ end
+ rescue Grit::NoSuchPathError
+ nil
+ end
+
def git_error?
error_code == :gitolite
end
@@ -171,8 +180,8 @@ class Project < ActiveRecord::Base
end
def check_limit
- unless owner.can_create_project?
- errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
+ unless creator.can_create_project?
+ errors[:base] << ("Your own projects limit is #{creator.projects_limit}! Please contact administrator to increase it")
end
rescue
errors[:base] << ("Can't check your ability to create project")
@@ -198,30 +207,10 @@ class Project < ActiveRecord::Base
[Gitlab.config.gitlab.url, path_with_namespace].join("/")
end
- def common_notes
- notes.where(noteable_type: ["", nil]).inc_author_project
- end
-
def build_commit_note(commit)
notes.new(commit_id: commit.id, noteable_type: "Commit")
end
- def commit_notes(commit)
- 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(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
- end
-
- def public?
- !private_flag
- end
-
- def private?
- private_flag
- end
-
def last_activity
last_event
end
@@ -262,7 +251,282 @@ class Project < ActiveRecord::Base
def send_move_instructions
self.users_projects.each do |member|
- Notify.project_was_moved_email(member.id).deliver
+ Notify.delay.project_was_moved_email(member.id)
+ end
+ end
+
+ def owner
+ if namespace
+ namespace_owner
+ else
+ creator
+ end
+ end
+
+ def team_member_by_name_or_email(name = nil, email = nil)
+ user = users.where("name like ? or email like ?", name, email).first
+ users_projects.where(user: user) if user
+ end
+
+ # Get Team Member record by user id
+ def team_member_by_id(user_id)
+ users_projects.find_by_user_id(user_id)
+ 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
+
+ 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
+
+ gitolite.move_repository(old_repo, self)
+
+ save!
+ end
+ rescue Gitlab::ProjectMover::ProjectMoveError => ex
+ raise Project::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 path_with_namespace
+ if namespace
+ namespace.path + '/' + path
+ else
+ path
+ end
+ end
+
+ # This method will be called after each post receive and only if the provided
+ # user is present in GitLab.
+ #
+ # All callbacks for post receive should be placed here.
+ def trigger_post_receive(oldrev, newrev, ref, user)
+ data = post_receive_data(oldrev, newrev, ref, user)
+
+ # Create push event
+ self.observe_push(data)
+
+ if push_to_branch? ref, oldrev
+ # Close merged MR
+ self.update_merge_requests(oldrev, newrev, ref, user)
+
+ # Execute web hooks
+ self.execute_hooks(data.dup)
+
+ # Execute project services
+ self.execute_services(data.dup)
+ end
+
+ # Create satellite
+ self.satellite.create unless self.satellite.exists?
+
+ # Discover the default branch, but only if it hasn't already been set to
+ # something else
+ if repository && default_branch.nil?
+ update_attributes(default_branch: self.repository.discover_default_branch)
+ end
+ end
+
+ def push_to_branch? ref, oldrev
+ ref_parts = ref.split('/')
+
+ # Return if this is not a push to a branch (e.g. new commits)
+ !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
+ end
+
+ def observe_push(data)
+ Event.create(
+ project: self,
+ action: Event::Pushed,
+ data: data,
+ author_id: data[:user_id]
+ )
+ end
+
+ def execute_hooks(data)
+ hooks.each { |hook| hook.execute(data) }
+ end
+
+ def execute_services(data)
+ services.each do |service|
+
+ # Call service hook only if it is active
+ service.execute(data) if service.active
+ end
+ end
+
+ # Produce a hash of post-receive data
+ #
+ # data = {
+ # before: String,
+ # after: String,
+ # ref: String,
+ # user_id: String,
+ # user_name: String,
+ # repository: {
+ # name: String,
+ # url: String,
+ # description: String,
+ # homepage: String,
+ # },
+ # commits: Array,
+ # total_commits_count: Fixnum
+ # }
+ #
+ def post_receive_data(oldrev, newrev, ref, user)
+
+ push_commits = repository.commits_between(oldrev, newrev)
+
+ # Total commits count
+ push_commits_count = push_commits.size
+
+ # Get latest 20 commits ASC
+ push_commits_limited = push_commits.last(20)
+
+ # Hash to be passed as post_receive_data
+ data = {
+ before: oldrev,
+ after: newrev,
+ ref: ref,
+ user_id: user.id,
+ user_name: user.name,
+ repository: {
+ name: name,
+ url: url_to_repo,
+ description: description,
+ homepage: web_url,
+ },
+ commits: [],
+ total_commits_count: push_commits_count
+ }
+
+ # For perfomance purposes maximum 20 latest commits
+ # will be passed as post receive hook data.
+ #
+ push_commits_limited.each do |commit|
+ data[:commits] << {
+ id: commit.id,
+ message: commit.safe_message,
+ timestamp: commit.date.xmlschema,
+ url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
+ author: {
+ name: commit.author_name,
+ email: commit.author_email
+ }
+ }
end
+
+ data
+ end
+
+ def update_merge_requests(oldrev, newrev, ref, user)
+ return true unless ref =~ /heads/
+ branch_name = ref.gsub("refs/heads/", "")
+ c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
+
+ # Update code for merge requests
+ mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
+ mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
+
+ # Close merge requests
+ mrs = self.merge_requests.opened.where(target_branch: branch_name).all
+ mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
+ mrs.each { |merge_request| merge_request.merge!(user.id) }
+
+ true
+ end
+
+ def valid_repo?
+ repo
+ rescue
+ errors.add(:path, "Invalid repository path")
+ false
+ end
+
+ def empty_repo?
+ !repository || repository.empty?
+ end
+
+ def satellite
+ @satellite ||= Gitlab::Satellite::Satellite.new(self)
+ end
+
+ def repo
+ repository.raw
+ end
+
+ def url_to_repo
+ gitolite.url_to_repo(path_with_namespace)
+ end
+
+ def namespace_dir
+ namespace.try(:path) || ''
+ end
+
+ def update_repository
+ gitolite.update_repository(self)
+ end
+
+ def destroy_repository
+ gitolite.remove_repository(self)
+ end
+
+ def repo_exists?
+ @repo_exists ||= (repository && repository.branches.present?)
+ rescue
+ @repo_exists = false
+ end
+
+ def open_branches
+ if protected_branches.empty?
+ self.repo.heads
+ else
+ pnames = protected_branches.map(&:name)
+ self.repo.heads.reject { |h| pnames.include?(h.name) }
+ end.sort_by(&:name)
+ end
+
+ def root_ref?(branch)
+ repository.root_ref == branch
+ end
+
+ def ssh_url_to_repo
+ url_to_repo
+ end
+
+ def http_url_to_repo
+ http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
+ end
+
+ # Check if current branch name is marked as protected in the system
+ def protected_branch? branch_name
+ protected_branches.map(&:name).include?(branch_name)
end
end
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index c54aa3ce9a2..3308caf360a 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -10,7 +10,7 @@
#
class ProtectedBranch < ActiveRecord::Base
- include GitHost
+ include Gitolited
attr_accessible :name
@@ -22,10 +22,10 @@ class ProtectedBranch < ActiveRecord::Base
after_destroy :update_repository
def update_repository
- git_host.update_repository(project)
+ gitolite.update_repository(project)
end
def commit
- project.commit(self.name)
+ project.repository.commit(self.name)
end
end
diff --git a/app/roles/repository.rb b/app/models/repository.rb
index 78190ca96d0..cf8ba4530a1 100644
--- a/app/roles/repository.rb
+++ b/app/models/repository.rb
@@ -1,15 +1,35 @@
-module Repository
- include GitHost
+class Repository
+ # Repository directory name with namespace direcotry
+ # Examples:
+ # gitlab/gitolite
+ # diaspora
+ #
+ attr_accessor :path_with_namespace
+
+ # Grit repo object
+ attr_accessor :repo
+
+ # Default branch in the repository
+ attr_accessor :root_ref
+
+ def initialize(path_with_namespace, root_ref = 'master')
+ @root_ref = root_ref || "master"
+ @path_with_namespace = path_with_namespace
- def valid_repo?
+ # Init grit repo object
+ repo
+ end
+
+ def raw
repo
- rescue
- errors.add(:path, "Invalid repository path")
- false
end
- def empty_repo?
- !repo_exists? || !has_commits?
+ def path_to_repo
+ @path_to_repo ||= File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
+ end
+
+ def repo
+ @repo ||= Grit::Repo.new(path_to_repo)
end
def commit(commit_id = nil)
@@ -40,10 +60,6 @@ module Repository
Commit.commits_between(repo, from, to)
end
- def satellite
- @satellite ||= Gitlab::Satellite::Satellite.new(self)
- end
-
def has_post_receive_file?
!!hook_file
end
@@ -88,36 +104,6 @@ module Repository
[branch_names + tag_names].flatten
end
- def repo
- @repo ||= Grit::Repo.new(path_to_repo)
- end
-
- def url_to_repo
- git_host.url_to_repo(path_with_namespace)
- end
-
- def path_to_repo
- File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
- end
-
- def namespace_dir
- namespace.try(:path) || ''
- end
-
- def update_repository
- git_host.update_repository(self)
- end
-
- def destroy_repository
- git_host.remove_repository(self)
- end
-
- def repo_exists?
- @repo_exists ||= (repo && !repo.branches.empty?)
- rescue
- @repo_exists = false
- end
-
def heads
@heads ||= repo.heads
end
@@ -128,13 +114,14 @@ module Repository
path ? (tree / path) : tree
end
- def open_branches
- if protected_branches.empty?
- self.repo.heads
- else
- pnames = protected_branches.map(&:name)
- self.repo.heads.reject { |h| pnames.include?(h.name) }
- end.sort_by(&:name)
+ def has_commits?
+ !!commit
+ rescue Grit::NoSuchPathError
+ false
+ end
+
+ def empty?
+ !has_commits?
end
# Discovers the default branch based on the repository's available branches
@@ -153,20 +140,6 @@ module Repository
end
end
- def has_commits?
- !!commit
- rescue Grit::NoSuchPathError
- false
- end
-
- def root_ref
- default_branch || "master"
- end
-
- def root_ref?(branch)
- root_ref == branch
- end
-
# Archive Project to .tar.gz
#
# Already packed repo archives stored at
@@ -193,17 +166,4 @@ module Repository
file_path
end
-
- def ssh_url_to_repo
- url_to_repo
- end
-
- def http_url_to_repo
- http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
- end
-
- # Check if current branch name is marked as protected in the system
- def protected_branch? branch_name
- protected_branches.map(&:name).include?(branch_name)
- end
end
diff --git a/app/models/service.rb b/app/models/service.rb
index 17a7a656de5..d3486d29200 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -20,4 +20,8 @@ class Service < ActiveRecord::Base
has_one :service_hook
validates :project_id, presence: true
+
+ def activated?
+ active
+ end
end
diff --git a/app/models/system_hook.rb b/app/models/system_hook.rb
index 2ae5b1314e9..5f1bd6477c4 100644
--- a/app/models/system_hook.rb
+++ b/app/models/system_hook.rb
@@ -19,6 +19,6 @@ class SystemHook < WebHook
end
def async_execute(data)
- Resque.enqueue(SystemHookWorker, id, data)
+ Sidekiq::Client.enqueue(SystemHookWorker, id, data)
end
end
diff --git a/app/models/team.rb b/app/models/team.rb
new file mode 100644
index 00000000000..f235d20ebdb
--- /dev/null
+++ b/app/models/team.rb
@@ -0,0 +1,118 @@
+class Team
+ attr_accessor :project
+
+ def initialize(project)
+ @project = project
+ end
+
+ # Shortcut to add users
+ #
+ # Use:
+ # @team << [@user, :master]
+ # @team << [@users, :master]
+ #
+ def << args
+ users = args.first
+
+ if users.respond_to?(:each)
+ add_users(users, args.second)
+ else
+ add_user(users, args.second)
+ end
+ end
+
+ def add_user(user, access)
+ add_users_ids([user.id], access)
+ end
+
+ def add_users(users, access)
+ add_users_ids(users.map(&:id), access)
+ end
+
+ def add_users_ids(user_ids, access)
+ UsersProject.add_users_into_projects(
+ [project.id],
+ user_ids,
+ access
+ )
+ end
+
+ # Remove all users from project team
+ def truncate
+ UsersProject.truncate_team(project)
+ end
+
+ def members
+ project.users_projects
+ end
+
+ def guests
+ members.guests.map(&:user)
+ end
+
+ def reporters
+ members.reporters.map(&:user)
+ end
+
+ def developers
+ members.developers.map(&:user)
+ end
+
+ def masters
+ members.masters.map(&:user)
+ end
+
+ def repository_readers
+ repository_members[UsersProject::REPORTER]
+ end
+
+ def repository_writers
+ repository_members[UsersProject::DEVELOPER]
+ end
+
+ def repository_masters
+ repository_members[UsersProject::MASTER]
+ end
+
+ def repository_members
+ keys = Hash.new {|h,k| h[k] = [] }
+ UsersProject.select("keys.identifier, project_access").
+ joins(user: :keys).where(project_id: project.id).
+ each {|row| keys[row.project_access] << [row.identifier] }
+
+ keys[UsersProject::REPORTER] += project.deploy_keys.pluck(:identifier)
+ keys
+ end
+
+ def import(source_project)
+ target_project = project
+
+ source_team = source_project.users_projects.all
+ target_team = target_project.users_projects.all
+ target_user_ids = target_team.map(&:user_id)
+
+ source_team.reject! do |tm|
+ # Skip if user already present in team
+ target_user_ids.include?(tm.user_id)
+ end
+
+ source_team.map! do |tm|
+ new_tm = tm.dup
+ new_tm.id = nil
+ new_tm.project_id = target_project.id
+ new_tm.skip_git = true
+ new_tm
+ end
+
+ UsersProject.transaction do
+ source_team.each do |tm|
+ tm.save
+ end
+ target_project.update_repository
+ end
+
+ true
+ rescue
+ false
+ end
+end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index c3dfd4c718c..96395a42394 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,12 +1,13 @@
class Tree
include Linguist::BlobHelper
- attr_accessor :path, :tree, :project, :ref
+
+ attr_accessor :path, :tree, :ref
delegate :contents, :basename, :name, :data, :mime_type,
:mode, :size, :text?, :colorize, to: :tree
- def initialize(raw_tree, project, ref = nil, path = nil)
- @project, @ref, @path = project, ref, path
+ def initialize(raw_tree, ref = nil, path = nil)
+ @ref, @path = ref, path
@tree = if path.present?
raw_tree / path
else
diff --git a/app/models/user.rb b/app/models/user.rb
index 1bc070f040d..55d75892fc4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -34,8 +34,6 @@
#
class User < ActiveRecord::Base
- include Account
-
devise :database_authenticatable, :token_authenticatable, :lockable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
@@ -51,7 +49,6 @@ class User < ActiveRecord::Base
has_many :groups, class_name: "Group", foreign_key: :owner_id
has_many :keys, dependent: :destroy
- has_many :projects, through: :users_projects
has_many :users_projects, dependent: :destroy
has_many :issues, foreign_key: :author_id, dependent: :destroy
has_many :notes, foreign_key: :author_id, dependent: :destroy
@@ -70,6 +67,8 @@ class User < ActiveRecord::Base
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
+ validate :namespace_uniq, if: ->(user) { user.username_changed? }
+
before_validation :generate_password, on: :create
before_save :ensure_authentication_token
alias_attribute :private_token, :authentication_token
@@ -77,11 +76,14 @@ class User < ActiveRecord::Base
delegate :path, to: :namespace, allow_nil: true, prefix: true
# Scopes
- scope :not_in_project, ->(project) { where("id not in (:ids)", ids: project.users.map(&:id) ) }
scope :admins, where(admin: true)
scope :blocked, where(blocked: true)
scope :active, where(blocked: false)
+ scope :alphabetically, order('name ASC')
+ #
+ # Class methods
+ #
class << self
def filter filter_name
case filter_name
@@ -93,6 +95,14 @@ class User < ActiveRecord::Base
end
end
+ def not_in_project(project)
+ if project.users.present?
+ where("id not in (:ids)", ids: project.users.map(&:id) )
+ else
+ scoped
+ end
+ end
+
def without_projects
where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
end
@@ -118,9 +128,158 @@ class User < ActiveRecord::Base
end
end
+ #
+ # Instance methods
+ #
def generate_password
if self.force_random_password
self.password = self.password_confirmation = Devise.friendly_token.first(8)
end
end
+
+ def namespace_uniq
+ namespace_name = self.username
+ if Namespace.find_by_path(namespace_name)
+ self.errors.add :username, "already exist"
+ end
+ end
+
+ # Namespaces user has access to
+ def namespaces
+ namespaces = []
+
+ # Add user account namespace
+ namespaces << self.namespace if self.namespace
+
+ # Add groups you can manage
+ namespaces += if admin
+ Group.all
+ else
+ groups.all
+ end
+ namespaces
+ end
+
+ # Groups where user is an owner
+ def owned_groups
+ groups
+ end
+
+ # Groups user has access to
+ def authorized_groups
+ @authorized_groups ||= begin
+ groups = Group.where(id: self.authorized_projects.pluck(:namespace_id)).all
+ groups = groups + self.groups
+ groups.uniq
+ end
+ end
+
+
+ # Projects user has access to
+ def authorized_projects
+ project_ids = users_projects.pluck(:project_id)
+ project_ids = project_ids | owned_projects.pluck(:id)
+ Project.where(id: project_ids)
+ end
+
+ # Projects in user namespace
+ def personal_projects
+ Project.personal(self)
+ end
+
+ # Projects where user is an owner
+ def owned_projects
+ Project.where("(projects.namespace_id IN (:namespaces)) OR
+ (projects.namespace_id IS NULL AND projects.creator_id = :user_id)",
+ namespaces: namespaces.map(&:id), user_id: self.id)
+ end
+
+ # Team membership in personal projects
+ def tm_in_personal_projects
+ UsersProject.where(project_id: personal_projects.map(&:id), user_id: self.id)
+ end
+
+ # Returns a string for use as a Gitolite user identifier
+ #
+ # Note that Gitolite 2.x requires the following pattern for users:
+ #
+ # ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
+ def identifier
+ # Replace non-word chars with underscores, then make sure it starts with
+ # valid chars
+ email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
+ end
+
+ def is_admin?
+ admin
+ end
+
+ def require_ssh_key?
+ keys.count == 0
+ end
+
+ def can_create_project?
+ projects_limit > personal_projects.count
+ end
+
+ def can_create_group?
+ is_admin?
+ end
+
+ def abilities
+ @abilities ||= begin
+ abilities = Six.new
+ abilities << Ability
+ abilities
+ end
+ end
+
+ def can? action, subject
+ abilities.allowed?(self, action, subject)
+ end
+
+ def first_name
+ name.split.first unless name.blank?
+ end
+
+ def cared_merge_requests
+ MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
+ end
+
+ # Remove user from all projects and
+ # set blocked attribute to true
+ def block
+ users_projects.find_each do |membership|
+ return false unless membership.destroy
+ end
+
+ self.blocked = true
+ save
+ end
+
+ def projects_limit_percent
+ return 100 if projects_limit.zero?
+ (personal_projects.count.to_f / projects_limit) * 100
+ end
+
+ def recent_push project_id = nil
+ # Get push events not earlier than 2 hours ago
+ events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
+ events = events.where(project_id: project_id) if project_id
+
+ # Take only latest one
+ events = events.recent.limit(1).first
+ end
+
+ def projects_sorted_by_activity
+ authorized_projects.sorted_by_activity
+ end
+
+ def several_namespaces?
+ namespaces.size > 1
+ end
+
+ def namespace_id
+ namespace.try :id
+ end
end
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index 3d76a4df037..79146289836 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -11,7 +11,7 @@
#
class UsersProject < ActiveRecord::Base
- include GitHost
+ include Gitolited
GUEST = 10
REPORTER = 20
@@ -23,87 +23,96 @@ class UsersProject < ActiveRecord::Base
belongs_to :user
belongs_to :project
- after_save :update_repository
- after_destroy :update_repository
+ attr_accessor :skip_git
+
+ after_save :update_repository, unless: :skip_git?
+ after_destroy :update_repository, unless: :skip_git?
validates :user, presence: true
- validates :user_id, uniqueness: { :scope => [:project_id], message: "already exists in project" }
+ validates :user_id, uniqueness: { scope: [:project_id], message: "already exists in project" }
validates :project_access, inclusion: { in: [GUEST, REPORTER, DEVELOPER, MASTER] }, presence: true
validates :project, presence: true
delegate :name, :email, to: :user, prefix: true
+ scope :guests, where(project_access: GUEST)
+ scope :reporters, where(project_access: REPORTER)
+ scope :developers, where(project_access: DEVELOPER)
+ scope :masters, where(project_access: MASTER)
+ scope :in_project, ->(project) { where(project_id: project.id) }
+
class << self
- def import_team(source_project, target_project)
- UsersProject.without_repository_callback do
- UsersProject.transaction do
- team = source_project.users_projects.all
-
- team.each do |tm|
- # Skip if user already present in team
- next if target_project.users.include?(tm.user)
-
- new_tm = tm.dup
- new_tm.id = nil
- new_tm.project_id = target_project.id
- new_tm.save
+
+ # Add users to project teams with passed access option
+ #
+ # access can be an integer representing a access code
+ # or symbol like :master representing role
+ #
+ # Ex.
+ # add_users_into_projects(
+ # project_ids,
+ # user_ids,
+ # UsersProject::MASTER
+ # )
+ #
+ # add_users_into_projects(
+ # project_ids,
+ # user_ids,
+ # :master
+ # )
+ #
+ def add_users_into_projects(project_ids, user_ids, access)
+ project_access = if roles_hash.has_key?(access)
+ roles_hash[access]
+ elsif roles_hash.values.include?(access.to_i)
+ access
+ else
+ raise "Non valid access"
+ end
+
+ UsersProject.transaction do
+ project_ids.each do |project_id|
+ user_ids.each do |user_id|
+ users_project = UsersProject.new(project_access: project_access, user_id: user_id)
+ users_project.project_id = project_id
+ users_project.skip_git = true
+ users_project.save
end
end
+ Gitlab::Gitolite.new.update_repositories(Project.where(id: project_ids))
end
- target_project.update_repository
true
rescue
false
end
- def without_repository_callback
- UsersProject.skip_callback(:destroy, :after, :update_repository)
- yield
- UsersProject.set_callback(:destroy, :after, :update_repository)
- end
-
- def bulk_delete(project, user_ids)
+ def truncate_teams(project_ids)
UsersProject.transaction do
- UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
+ users_projects = UsersProject.where(project_id: project_ids)
+ users_projects.each do |users_project|
+ users_project.skip_git = true
users_project.destroy
end
+ Gitlab::Gitolite.new.update_repositories(Project.where(id: project_ids))
end
- end
- def bulk_update(project, user_ids, project_access)
- UsersProject.transaction do
- UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
- users_project.project_access = project_access
- users_project.save
- end
- end
+ true
+ rescue
+ false
end
- def bulk_import(project, user_ids, project_access)
- UsersProject.transaction do
- user_ids.each do |user_id|
- users_project = UsersProject.new(
- project_access: project_access,
- user_id: user_id
- )
- users_project.project = project
- users_project.save
- end
- end
+ def truncate_team project
+ truncate_teams [project.id]
end
- def user_bulk_import(user, project_ids, project_access)
- UsersProject.transaction do
- project_ids.each do |project_id|
- users_project = UsersProject.new(
- project_access: project_access,
- )
- users_project.project_id = project_id
- users_project.user_id = user.id
- users_project.save
- end
- end
+ def roles_hash
+ {
+ guest: GUEST,
+ reporter: REPORTER,
+ developer: DEVELOPER,
+ master: MASTER
+ }
end
def access_roles
@@ -116,12 +125,8 @@ class UsersProject < ActiveRecord::Base
end
end
- def role_access
- project_access
- end
-
def update_repository
- git_host.update_repository(project)
+ gitolite.update_repository(project)
end
def project_access_human
@@ -131,4 +136,8 @@ class UsersProject < ActiveRecord::Base
def repo_access_human
self.class.access_roles.invert[self.project_access]
end
+
+ def skip_git?
+ !!@skip_git
+ end
end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index 252a97e8cca..4f113957f99 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -50,5 +50,4 @@ class Wiki < ActiveRecord::Base
def set_slug
self.slug = self.title.parameterize
end
-
end
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 131336be8b6..262d0f892c4 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -3,7 +3,7 @@ class IssueObserver < ActiveRecord::Observer
def after_create(issue)
if issue.assignee && issue.assignee != current_user
- Notify.new_issue_email(issue.id).deliver
+ Notify.delay.new_issue_email(issue.id)
end
end
@@ -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.id).deliver
+ Notify.delay.issue_status_changed_email(recipient.id, issue.id, status, current_user.id)
end
end
end
@@ -27,7 +27,7 @@ class IssueObserver < ActiveRecord::Observer
recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id }
recipient_ids.each do |recipient_id|
- Notify.reassigned_issue_email(recipient_id, issue.id, issue.assignee_id_was).deliver
+ Notify.delay.reassigned_issue_email(recipient_id, issue.id, issue.assignee_id_was)
end
end
end
diff --git a/app/observers/key_observer.rb b/app/observers/key_observer.rb
index a3f17bdec92..bf5fa647647 100644
--- a/app/observers/key_observer.rb
+++ b/app/observers/key_observer.rb
@@ -1,12 +1,12 @@
class KeyObserver < ActiveRecord::Observer
- include GitHost
+ include Gitolited
def after_save(key)
- git_host.set_key(key.identifier, key.key, key.projects)
+ gitolite.set_key(key.identifier, key.key, key.projects)
end
def after_destroy(key)
return if key.is_deploy_key && !key.last_deploy?
- git_host.remove_key(key.identifier, key.projects)
+ gitolite.remove_key(key.identifier, key.projects)
end
end
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index c4040f1542d..6d3c2bdd186 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -3,7 +3,7 @@ class MergeRequestObserver < ActiveRecord::Observer
def after_create(merge_request)
if merge_request.assignee && merge_request.assignee != current_user
- Notify.new_merge_request_email(merge_request.id).deliver
+ Notify.delay.new_merge_request_email(merge_request.id)
end
end
@@ -25,7 +25,7 @@ class MergeRequestObserver < ActiveRecord::Observer
recipients_ids.delete current_user.id
recipients_ids.each do |recipient_id|
- Notify.reassigned_merge_request_email(recipient_id, merge_request.id, merge_request.assignee_id_was).deliver
+ Notify.delay.reassigned_merge_request_email(recipient_id, merge_request.id, merge_request.assignee_id_was)
end
end
end
diff --git a/app/observers/note_observer.rb b/app/observers/note_observer.rb
index 0a353cf1092..2ec644ef7c1 100644
--- a/app/observers/note_observer.rb
+++ b/app/observers/note_observer.rb
@@ -11,7 +11,7 @@ class NoteObserver < ActiveRecord::Observer
notify_team(note)
elsif note.notify_author
# Notify only author of resource
- Notify.note_commit_email(note.noteable.author_email, note.id).deliver
+ Notify.delay.note_commit_email(note.noteable.author_email, note.id)
else
# Otherwise ignore it
nil
@@ -26,7 +26,7 @@ class NoteObserver < ActiveRecord::Observer
if Notify.respond_to? notify_method
team_without_note_author(note).map do |u|
- Notify.send(notify_method, u.id, note.id).deliver
+ Notify.delay.send(notify_method, u.id, note.id)
end
end
end
diff --git a/app/observers/user_observer.rb b/app/observers/user_observer.rb
index 09b3c1d622f..c1179ed7881 100644
--- a/app/observers/user_observer.rb
+++ b/app/observers/user_observer.rb
@@ -2,7 +2,7 @@ class UserObserver < ActiveRecord::Observer
def after_create(user)
log_info("User \"#{user.name}\" (#{user.email}) was created")
- Notify.new_user_email(user.id, user.password).deliver
+ Notify.delay.new_user_email(user.id, user.password)
end
def after_destroy user
@@ -14,7 +14,7 @@ class UserObserver < ActiveRecord::Observer
if user.namespace
user.namespace.update_attributes(path: user.username)
else
- user.create_namespace!(path: user.username, name: user.name)
+ user.create_namespace!(path: user.username, name: user.username)
end
end
end
diff --git a/app/observers/users_project_observer.rb b/app/observers/users_project_observer.rb
index 0c9c2b2614a..b969d6a13ef 100644
--- a/app/observers/users_project_observer.rb
+++ b/app/observers/users_project_observer.rb
@@ -1,7 +1,7 @@
class UsersProjectObserver < ActiveRecord::Observer
def after_commit(users_project)
return if users_project.destroyed?
- Notify.project_access_granted_email(users_project.id).deliver
+ Notify.delay.project_access_granted_email(users_project.id)
end
def after_create(users_project)
diff --git a/app/roles/account.rb b/app/roles/account.rb
deleted file mode 100644
index ede12b6056d..00000000000
--- a/app/roles/account.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-module Account
- # Returns a string for use as a Gitolite user identifier
- #
- # Note that Gitolite 2.x requires the following pattern for users:
- #
- # ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
- def identifier
- # Replace non-word chars with underscores, then make sure it starts with
- # valid chars
- email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
- end
-
- def is_admin?
- admin
- end
-
- def require_ssh_key?
- keys.count == 0
- end
-
- def can_create_project?
- projects_limit > my_own_projects.count
- end
-
- def can_create_group?
- is_admin?
- end
-
- def abilities
- @abilities ||= begin
- abilities = Six.new
- abilities << Ability
- abilities
- end
- end
-
- def can? action, subject
- abilities.allowed?(self, action, subject)
- end
-
- def last_activity_project
- projects.first
- end
-
- def first_name
- name.split.first unless name.blank?
- end
-
- def cared_merge_requests
- MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
- end
-
- def project_ids
- projects.map(&:id)
- end
-
- # Remove user from all projects and
- # set blocked attribute to true
- def block
- users_projects.find_each do |membership|
- return false unless membership.destroy
- end
-
- self.blocked = true
- save
- end
-
- def projects_limit_percent
- return 100 if projects_limit.zero?
- (my_own_projects.count.to_f / projects_limit) * 100
- end
-
- def recent_push project_id = nil
- # Get push events not earlier than 2 hours ago
- events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
- events = events.where(project_id: project_id) if project_id
-
- # Take only latest one
- events = events.recent.limit(1).first
- end
-
- def projects_sorted_by_activity
- projects.sorted_by_activity
- end
-
- def namespaces
- namespaces = []
-
- # Add user account namespace
- namespaces << self.namespace if self.namespace
-
- # Add groups you can manage
- namespaces += if admin
- Group.all
- else
- groups.all
- end
- namespaces
- end
-
- def several_namespaces?
- namespaces.size > 1
- end
-
- 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/authority.rb b/app/roles/authority.rb
deleted file mode 100644
index e0796d5f120..00000000000
--- a/app/roles/authority.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-module Authority
- # Compatible with all access rights
- # Should be rewrited for new access rights
- def add_access(user, *access)
- access = if access.include?(:admin)
- { project_access: UsersProject::MASTER }
- elsif access.include?(:write)
- { project_access: UsersProject::DEVELOPER }
- else
- { project_access: UsersProject::REPORTER }
- end
- opts = { user: user }
- opts.merge!(access)
- users_projects.create(opts)
- end
-
- def reset_access(user)
- users_projects.where(project_id: self.id, user_id: user.id).destroy if self.id
- end
-
- def repository_readers
- keys = Key.joins({user: :users_projects}).
- where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::REPORTER)
- keys.map(&:identifier) + deploy_keys.map(&:identifier)
- end
-
- def repository_writers
- keys = Key.joins({user: :users_projects}).
- where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::DEVELOPER)
- keys.map(&:identifier)
- end
-
- def repository_masters
- keys = Key.joins({user: :users_projects}).
- where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::MASTER)
- keys.map(&:identifier)
- end
-
- def allow_read_for?(user)
- !users_projects.where(user_id: user.id).empty?
- end
-
- def guest_access_for?(user)
- !users_projects.where(user_id: user.id).empty?
- end
-
- def report_access_for?(user)
- !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
- end
-
- def dev_access_for?(user)
- !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
- end
-
- def master_access_for?(user)
- !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty?
- end
-end
diff --git a/app/roles/git_host.rb b/app/roles/git_host.rb
deleted file mode 100644
index aa620f77ea4..00000000000
--- a/app/roles/git_host.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-module GitHost
- def git_host
- Gitlab::Gitolite.new
- end
-end
diff --git a/app/roles/namespaced_project.rb b/app/roles/namespaced_project.rb
deleted file mode 100644
index 8656890a456..00000000000
--- a/app/roles/namespaced_project.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-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
deleted file mode 100644
index db4ced0c095..00000000000
--- a/app/roles/note_event.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-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_event.rb b/app/roles/push_event.rb
deleted file mode 100644
index 8ce71b54045..00000000000
--- a/app/roles/push_event.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-module PushEvent
- def valid_push?
- data[:ref]
- rescue => ex
- false
- end
-
- def tag?
- data[:ref]["refs/tags"]
- end
-
- def branch?
- data[:ref]["refs/heads"]
- end
-
- def new_branch?
- commit_from =~ /^00000/
- end
-
- def new_ref?
- commit_from =~ /^00000/
- end
-
- def rm_ref?
- commit_to =~ /^00000/
- end
-
- def md_ref?
- !(rm_ref? || new_ref?)
- end
-
- def commit_from
- data[:before]
- end
-
- def commit_to
- data[:after]
- end
-
- def ref_name
- if tag?
- tag_name
- else
- branch_name
- end
- end
-
- def branch_name
- @branch_name ||= data[:ref].gsub("refs/heads/", "")
- end
-
- def tag_name
- @tag_name ||= data[:ref].gsub("refs/tags/", "")
- end
-
- # Max 20 commits from push DESC
- def commits
- @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse
- end
-
- def commits_count
- data[:total_commits_count] || commits.count || 0
- end
-
- def ref_type
- tag? ? "tag" : "branch"
- end
-
- def push_action_name
- if new_ref?
- "pushed new"
- elsif rm_ref?
- "deleted"
- else
- "pushed to"
- end
- end
-
- def parent_commit
- project.commit(commit_from)
- rescue => ex
- nil
- end
-
- def last_commit
- project.commit(commit_to)
- rescue => ex
- nil
- end
-
- def push_with_commits?
- md_ref? && commits.any? && parent_commit && last_commit
- rescue Grit::NoSuchPathError
- false
- end
-
- def last_push_to_non_root?
- branch? && project.default_branch != branch_name
- end
-end
diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb
deleted file mode 100644
index dda18267207..00000000000
--- a/app/roles/push_observer.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-# Includes methods for handling Git Push events
-#
-# Triggered by PostReceive job
-module PushObserver
- # This method will be called after each post receive and only if the provided
- # user is present in GitLab.
- #
- # All callbacks for post receive should be placed here.
- def trigger_post_receive(oldrev, newrev, ref, user)
- data = post_receive_data(oldrev, newrev, ref, user)
-
- # Create push event
- self.observe_push(data)
-
- if push_to_branch? ref, oldrev
- # Close merged MR
- self.update_merge_requests(oldrev, newrev, ref, user)
-
- # Execute web hooks
- self.execute_hooks(data.dup)
-
- # Execute project services
- self.execute_services(data.dup)
- end
-
- # Create satellite
- self.satellite.create unless self.satellite.exists?
-
- # Discover the default branch, but only if it hasn't already been set to
- # something else
- if default_branch.nil?
- update_attributes(default_branch: discover_default_branch)
- end
- end
-
- def push_to_branch? ref, oldrev
- ref_parts = ref.split('/')
-
- # Return if this is not a push to a branch (e.g. new commits)
- !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
- end
-
- def observe_push(data)
- Event.create(
- project: self,
- action: Event::Pushed,
- data: data,
- author_id: data[:user_id]
- )
- end
-
- def execute_hooks(data)
- hooks.each { |hook| hook.execute(data) }
- end
-
- def execute_services(data)
- services.each do |service|
-
- # Call service hook only if it is active
- service.execute(data) if service.active
- end
- end
-
- # Produce a hash of post-receive data
- #
- # data = {
- # before: String,
- # after: String,
- # ref: String,
- # user_id: String,
- # user_name: String,
- # repository: {
- # name: String,
- # url: String,
- # description: String,
- # homepage: String,
- # },
- # commits: Array,
- # total_commits_count: Fixnum
- # }
- #
- def post_receive_data(oldrev, newrev, ref, user)
-
- push_commits = commits_between(oldrev, newrev)
-
- # Total commits count
- push_commits_count = push_commits.size
-
- # Get latest 20 commits ASC
- push_commits_limited = push_commits.last(20)
-
- # Hash to be passed as post_receive_data
- data = {
- before: oldrev,
- after: newrev,
- ref: ref,
- user_id: user.id,
- user_name: user.name,
- repository: {
- name: name,
- url: web_url,
- description: description,
- homepage: web_url,
- },
- commits: [],
- total_commits_count: push_commits_count
- }
-
- # For perfomance purposes maximum 20 latest commits
- # will be passed as post receive hook data.
- #
- push_commits_limited.each do |commit|
- data[:commits] << {
- id: commit.id,
- message: commit.safe_message,
- timestamp: commit.date.xmlschema,
- url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
- author: {
- name: commit.author_name,
- email: commit.author_email
- }
- }
- end
-
- data
- end
-
- def update_merge_requests(oldrev, newrev, ref, user)
- return true unless ref =~ /heads/
- branch_name = ref.gsub("refs/heads/", "")
- c_ids = self.commits_between(oldrev, newrev).map(&:id)
-
- # Update code for merge requests
- mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
- mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
-
- # Close merge requests
- mrs = self.merge_requests.opened.where(target_branch: branch_name).all
- mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
- mrs.each { |merge_request| merge_request.merge!(user.id) }
-
- true
- end
-end
diff --git a/app/roles/static_model.rb b/app/roles/static_model.rb
deleted file mode 100644
index 5b64be1f041..00000000000
--- a/app/roles/static_model.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# Provides an ActiveRecord-like interface to a model whose data is not persisted to a database.
-module StaticModel
- extend ActiveSupport::Concern
-
- module ClassMethods
- # Used by ActiveRecord's polymorphic association to set object_id
- def primary_key
- 'id'
- end
-
- # Used by ActiveRecord's polymorphic association to set object_type
- def base_class
- self
- end
- end
-
- # Used by AR for fetching attributes
- #
- # Pass it along if we respond to it.
- def [](key)
- send(key) if respond_to?(key)
- end
-
- def to_param
- id
- end
-
- def new_record?
- false
- end
-
- def persisted?
- false
- end
-
- def destroyed?
- false
- end
-
- def ==(other)
- if other.is_a? StaticModel
- id == other.id
- else
- super
- end
- end
-end
diff --git a/app/roles/team.rb b/app/roles/team.rb
deleted file mode 100644
index a7ba0588cf5..00000000000
--- a/app/roles/team.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module Team
- def team_member_by_name_or_email(name = nil, email = nil)
- user = users.where("name like ? or email like ?", name, email).first
- users_projects.where(user: user) if user
- end
-
- # Get Team Member record by user id
- def team_member_by_id(user_id)
- users_projects.find_by_user_id(user_id)
- end
-
- # Add user to project
- # with passed access role
- def add_user_to_team(user, access_role)
- add_user_id_to_team(user.id, access_role)
- end
-
- # Add multiple users to project
- # with same access role
- def add_users_to_team(users, access_role)
- add_users_ids_to_team(users.map(&:id), access_role)
- end
-
- # Add user to project
- # with passed access role by user id
- def add_user_id_to_team(user_id, access_role)
- users_projects.create(
- user_id: user_id,
- project_access: access_role
- )
- end
-
- # Add multiple users to project
- # with same access role by user ids
- def add_users_ids_to_team(users_ids, access_role)
- UsersProject.bulk_import(self, users_ids, access_role)
- self.update_repository
- end
-
- # Update multiple project users
- # to same access role by user ids
- def update_users_ids_to_role(users_ids, access_role)
- UsersProject.bulk_update(self, users_ids, access_role)
- self.update_repository
- end
-
- # Delete multiple users from project by user ids
- def delete_users_ids_from_team(users_ids)
- UsersProject.bulk_delete(self, users_ids)
- self.update_repository
- end
-end
diff --git a/app/roles/votes.rb b/app/roles/votes.rb
deleted file mode 100644
index 10fa120c6e9..00000000000
--- a/app/roles/votes.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module Votes
-
- # Return the number of -1 comments (downvotes)
- def downvotes
- notes.select(&:downvote?).size
- end
-
- def downvotes_in_percent
- if votes_count.zero?
- 0
- else
- 100.0 - upvotes_in_percent
- end
- end
-
- # Return the number of +1 comments (upvotes)
- def upvotes
- notes.select(&:upvote?).size
- end
-
- def upvotes_in_percent
- if votes_count.zero?
- 0
- else
- 100.0 / votes_count * upvotes
- end
- end
-
- # Return the total number of votes
- def votes_count
- upvotes + downvotes
- end
-end
diff --git a/app/uploaders/attachment_uploader.rb b/app/uploaders/attachment_uploader.rb
index bb7dc0dab10..391731d9470 100644
--- a/app/uploaders/attachment_uploader.rb
+++ b/app/uploaders/attachment_uploader.rb
@@ -1,49 +1,13 @@
# encoding: utf-8
class AttachmentUploader < CarrierWave::Uploader::Base
-
- # Include RMagick or ImageScience support:
- # include CarrierWave::RMagick
- # include CarrierWave::MiniMagick
- # include CarrierWave::ImageScience
-
- # Choose what kind of storage to use for this uploader:
storage :file
- # storage :fog
- # Override the directory where uploaded files will be stored.
- # This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
- # Provide a default URL as a default if there hasn't been a file uploaded:
- # def default_url
- # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
- # end
-
- # Process files as they are uploaded:
- # process scale: [200, 300]
- #
- # def scale(width, height)
- # # do something
- # end
-
- # Create different versions of your uploaded files:
- # version :thumb do
- # process scale: [50, 50]
- # end
-
- # Add a white list of extensions which are allowed to be uploaded.
- # For images you might use something like this:
- # def extension_white_list
- # %w(jpg jpeg gif png)
- # end
-
- # Override the filename of the uploaded files:
- # Avoid using model.id or version_name here, see uploader/store.rb for details.
- # def filename
- # "something.jpg" if original_filename
- # end
-
+ def image?
+ %w(png jpg jpeg).include?(file.extension)
+ end
end
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 4320bda4999..2e572aaba79 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,47 +1,28 @@
.admin_dash.row
- .span3
+ .span4
.ui-box
- %h5 Projects
+ %h5.title Projects
.data.padded
= link_to admin_projects_path do
%h1= Project.count
%hr
= link_to 'New Project', new_project_path, class: "btn small"
- .span3
+ .span4
.ui-box
- %h5 Groups
+ %h5.title Groups
.data.padded
= link_to admin_groups_path do
%h1= Group.count
%hr
= link_to 'New Group', new_admin_group_path, class: "btn small"
- .span3
+ .span4
.ui-box
- %h5 Users
+ %h5.title Users
.data.padded
= link_to admin_users_path do
%h1= User.count
%hr
= link_to 'New User', new_admin_user_path, class: "btn small"
- .span3
- .ui-box
- %h5
- Resque Workers
- .data.padded
- - if @resque_accessible
- = link_to admin_resque_path do
- %h1{class: @workers.present? ? "cgreen" : "cred"}
- = @workers.count
- %hr
- %p
- %strong{class: @pending_jobs > 0 ? "cred" : "cgreen"}
- #{@pending_jobs} post receive jobs waiting
- - else
- = link_to admin_resque_path do
- %h1.cdark ?
- %hr
- %p
- %strong Resque status unknown
.row
.span6
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 41f6d9b3516..0a25b125905 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -44,25 +44,57 @@
%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
+
+- if @group.projects.any?
+ %fieldset
+ %legend Projects (#{@group.projects.count})
+ %table
+ %thead
+ %tr
+ %th Project name
+ %th Path
+ %th Users
+ %th.cred Danger Zone!
+ - @group.projects.each do |project|
+ %tr
+ %td
+ = link_to project.name_with_namespace, [:admin, project]
+ %td
+ %span.monospace= project.path_with_namespace + ".git"
+ %td= project.users.count
+ %td.bgred
+ = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small"
+
+ = form_tag project_teams_update_admin_group_path(@group), id: "new_team_member", class: "bulk_import", method: :put do
+ %table.zebra-striped
+ %thead
+ %tr
+ %th Users
+ %th Project Access:
+
+ - @group.users.each do |u|
+ %tr{class: "user_#{u.id}"}
+ %td.name= link_to u.name, admin_user_path(u)
+ %td.projects_access
+ - u.authorized_projects.in_namespace(@group).each do |project|
+ - u_p = u.users_projects.in_project(project).first
+ - next unless u_p
+ %span
+ = project.name
+ = link_to "(#{ u_p.project_access_human })", edit_admin_team_member_path(u_p)
%tr
- %th Project name
- %th Path
- %th Users
- %th.cred Danger Zone!
- - @group.projects.each do |project|
+ %td.input= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
+ %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"}
+
%tr
+ %td= submit_tag 'Add user to projects in group', class: "btn primary"
%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"
+ Read more about project permissions
+ %strong= link_to "here", help_permissions_path, class: "vlink"
+- else
+ %fieldset
+ %legend Group is empty
= form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do
%fieldset
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
index 27c22872d50..36c0c655cae 100644
--- a/app/views/admin/projects/_form.html.haml
+++ b/app/views/admin/projects/_form.html.haml
@@ -11,18 +11,18 @@
.input
= f.text_field :name, placeholder: "Example Project", class: "xxlarge"
- %fieldset.adv_settings
- %legend Advanced settings:
- .clearfix
- = f.label :path do
- Path
- .input
- = text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
+ - if project.repo_exists?
+ %fieldset.adv_settings
+ %legend Advanced settings:
+ .clearfix
+ = f.label :path do
+ Path
+ .input
+ = text_field_tag :ppath, @project.repository.path_to_repo, class: "xlarge", disabled: true
- - if project.repo_exists?
.clearfix
= f.label :default_branch, "Default Branch"
- .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
+ .input= f.select(:default_branch, @project.repository.heads.map(&:name), {}, style: "width:210px;")
%fieldset.adv_settings
%legend Features:
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 310cfa53890..1f5b31eca5f 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.count})
+ Projects (#{Project.count})
= link_to 'New Project', new_project_path, class: "btn small right"
%br
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
@@ -15,6 +15,7 @@
%i.icon-sort-down
%th Path
%th Team Members
+ %th Owner
%th Last Commit
%th Edit
%th.cred Danger Zone!
@@ -26,6 +27,11 @@
%td
%span.monospace= project.path_with_namespace + ".git"
%td= project.users_projects.count
+ %td
+ - if project.owner
+ = link_to project.owner.name, [:admin, project.owner]
+ - else
+ (deleted)
%td= last_commit(project)
%td= link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"
%td.bgred= link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 634b1836754..5a745f58fe3 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -4,15 +4,15 @@
%i.icon-edit
Edit
-- if @project.has_commits?
- - if !@project.has_post_receive_file?
+- if @repository && @repository.has_commits?
+ - if !@repository.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?
+ - elsif !@repository.valid_post_receive_file?
%br
.alert.alert-error
%span
@@ -49,8 +49,8 @@
%b
Owned by:
%td
- - if @project.chief
- = link_to @project.chief.name, admin_user_path(@project.chief)
+ - if @project.owner
+ = link_to @project.owner_name, admin_user_path(@project.owner)
- else
(deleted)
%tr
@@ -58,49 +58,50 @@
%b
Created by:
%td
- = @project.owner_name || '(deleted)'
+ = @project.creator.try(:name) || '(deleted)'
%tr
%td
%b
Created at:
%td
= @project.created_at.stamp("March 1, 1999")
+ %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
-%table.zebra-striped
- %thead
+- if @repository
+ %table.zebra-striped
+ %thead
+ %tr
+ %th Repository
+ %th
%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
+ %td
+ %b
+ FS Path:
+ %td
+ %code= @repository.path_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, @repository.has_post_receive_file?, disabled: true
%br
%h5
diff --git a/app/views/admin/resque/show.html.haml b/app/views/admin/resque/show.html.haml
index 41254a6b6c2..499738f9a06 100644
--- a/app/views/admin/resque/show.html.haml
+++ b/app/views/admin/resque/show.html.haml
@@ -1,4 +1,4 @@
-%h3.page_title Resque
+%h3.page_title Background Jobs
%br
.ui-box
- %iframe{src: resque_path, width: '100%', height: 600, style: "border: none"}
+ %iframe{src: sidekiq_path, width: '100%', height: 900, style: "border: none"}
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 1df4f590bcb..87290abe7a6 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 (#{@admin_users.count})
+ Users
= link_to 'New User', new_admin_user_path, class: "btn small right"
%br
@@ -8,16 +8,21 @@
= submit_tag "Search", class: "btn submit primary"
%ul.nav.nav-tabs
%li{class: "#{'active' unless params[:filter]}"}
- = link_to "Active", admin_users_path
+ = link_to admin_users_path do
+ Active
+ %span.badge= User.active.count
%li{class: "#{'active' if params[:filter] == "admins"}"}
= link_to admin_users_path(filter: "admins") do
Admins
+ %span.badge= User.admins.count
%li{class: "#{'active' if params[:filter] == "blocked"}"}
= link_to admin_users_path(filter: "blocked") do
Blocked
+ %span.badge= User.blocked.count
%li{class: "#{'active' if params[:filter] == "wop"}"}
= link_to admin_users_path(filter: "wop") do
Without projects
+ %span.badge= User.without_projects.count
%table
%thead
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 852aead79e2..db132359c7f 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -106,8 +106,8 @@
%td= link_to group.name, admin_group_path(group)
-- if @admin_user.projects.present?
- %h5 Projects:
+- if @admin_user.personal_projects.present?
+ %h5 Personal Projects:
%br
%table.zebra-striped
@@ -118,7 +118,7 @@
%th
%th
- - @admin_user.users_projects.each do |tm|
+ - @admin_user.tm_in_personal_projects.each do |tm|
- project = tm.project
%tr
%td= link_to project.name_with_namespace, admin_project_path(project)
diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml
index 5ba43f951dc..f920534e03a 100644
--- a/app/views/commit/show.html.haml
+++ b/app/views/commit/show.html.haml
@@ -1,4 +1,11 @@
= render "commits/commit_box"
+
+%p.right.cgray
+ This commit has
+ %span.cgreen #{@commit.stats.additions} additions
+ and
+ %span.cred #{@commit.stats.deletions} deletions
+
= render "commits/diffs", diffs: @commit.diffs
= render "notes/notes_with_form"
@@ -16,5 +23,7 @@
, h = event.currentTarget.naturalHeight;
$('.image.diff_added .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
}, this));
+
});
+
});
diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml
index 156ff1e9d85..eb0312d01e1 100644
--- a/app/views/commits/_commit.html.haml
+++ b/app/views/commits/_commit.html.haml
@@ -14,8 +14,8 @@
&nbsp;
%span.notes_count
- - notes = @project.commit_notes(commit) + @project.commit_line_notes(commit)
+ - notes = @project.notes.for_commit_id(commit.id)
- if notes.any?
- %span.btn.small.disabled.grouped
+ %span.btn.disabled.grouped
%i.icon-comment
= notes.count
diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commits/_commit_box.html.haml
index 8f7826e0c8d..0544a1d10fe 100644
--- a/app/views/commits/_commit_box.html.haml
+++ b/app/views/commits/_commit_box.html.haml
@@ -1,47 +1,50 @@
-.commit-box{class: @commit.parents_count > 1 ? "merge-commit" : ""}
- .commit-head
+.ui-box.ui-box-show
+ .ui-box-head
.right
- if @notes_count > 0
%span.btn.disabled.grouped
%i.icon-comment
= @notes_count
.left.btn-group
- %a.btn.small.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
+ %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
%i.icon-download-alt
Download as
%span.caret
%ul.dropdown-menu
%li= link_to "Email Patches", project_commit_path(@project, @commit, format: :patch)
%li= link_to "Plain Diff", project_commit_path(@project, @commit, format: :diff)
- = link_to project_tree_path(@project, @commit), class: "browse-button primary grouped" do
- %strong Browse Code »
+ = link_to project_tree_path(@project, @commit), class: "btn primary grouped" do
+ %span Browse Code »
%h3.commit-title.page_title
= gfm escape_once(@commit.title)
- if @commit.description.present?
%pre.commit-description
= gfm escape_once(@commit.description)
- .commit-info
+ .ui-box-body
.row
.span5
.author
- %strong= @commit.author_link avatar: true, size: 40
+ = @commit.author_link avatar: true, size: 32
authored
%time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
#{time_ago_in_words(@commit.authored_date)} ago
- if @commit.different_committer?
.committer
&rarr;
- %strong= @commit.committer_link
+ = @commit.committer_link
committed
%time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
#{time_ago_in_words(@commit.committed_date)} ago
- .span6.right
- .sha-block
- %span.cgray commit
- %code.label_commit= @commit.id
- .sha-block
- %span.cgray= pluralize(@commit.parents.count, "parent")
- - @commit.parents.each do |parent|
- = link_to parent.id[0...10], project_commit_path(@project, parent)
+ .span6.pull-right
+ .pull-right
+ .sha-block
+ %span.cgray commit
+ %span.label_commit= @commit.id
+ .clearfix
+ .pull-right
+ .sha-block
+ %span.cgray= pluralize(@commit.parents.count, "parent")
+ - @commit.parents.each do |parent|
+ = link_to parent.id[0...10], project_commit_path(@project, parent)
diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml
index c9217989884..0dc6664c1d6 100644
--- a/app/views/commits/_commits.html.haml
+++ b/app/views/commits/_commits.html.haml
@@ -1,6 +1,6 @@
- @commits.group_by { |c| c.committed_date.to_date }.each do |day, commits|
%div.ui-box
- %h5.small
+ %h5.title
%i.icon-calendar
= day.stamp("28 Aug, 2010")
%ul.well-list= render commits
diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml
index 2ec1d24bbef..a5f3fdf5c5e 100644
--- a/app/views/commits/_head.html.haml
+++ b/app/views/commits/_head.html.haml
@@ -2,19 +2,19 @@
%li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'}
= nav_link(controller: [:commit, :commits]) do
- = link_to 'Commits', project_commits_path(@project, @project.root_ref)
+ = link_to 'Commits', project_commits_path(@project, @repository.root_ref)
= nav_link(controller: :compare) do
= link_to 'Compare', project_compare_index_path(@project)
= nav_link(html_options: {class: branches_tab_class}) do
= link_to project_repository_path(@project) do
Branches
- %span.badge= @project.branches.length
+ %span.badge= @repository.branches.length
= nav_link(controller: :repositories, action: :tags) do
= link_to tags_project_repository_path(@project) do
Tags
- %span.badge= @project.tags.length
+ %span.badge= @repository.tags.length
= nav_link(controller: :repositories, action: :stats) do
= link_to stats_project_repository_path(@project) do
diff --git a/app/views/commits/_text_diff.html.haml b/app/views/commits/_text_diff.html.haml
index f5784dea511..ce07b87d548 100644
--- a/app/views/commits/_text_diff.html.haml
+++ b/app/views/commits/_text_diff.html.haml
@@ -15,7 +15,7 @@
- if @comments_allowed
= render "notes/diff_note_link", line_code: line_code
%td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
- %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} &nbsp;"
+ %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
- if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
diff --git a/app/views/compare/_form.html.haml b/app/views/compare/_form.html.haml
index 7e3a2a0e1f5..0915782dddc 100644
--- a/app/views/compare/_form.html.haml
+++ b/app/views/compare/_form.html.haml
@@ -28,7 +28,7 @@
:javascript
$(function() {
- var availableTags = #{@project.ref_names.to_json};
+ var availableTags = #{@project.repository.ref_names.to_json};
$("#from, #to").autocomplete({
source: availableTags,
diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml
index 2abbd3fc0ee..d8ea3727d57 100644
--- a/app/views/compare/show.html.haml
+++ b/app/views/compare/show.html.haml
@@ -8,7 +8,8 @@
- if @commits.present?
%div.ui-box
- %h5.small Commits (#{@commits.count})
+ %h5.title
+ Commits (#{@commits.count})
%ul.well-list= render @commits
- unless @diffs.empty?
diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml
index c63ef24fca5..2b7d23c225d 100644
--- a/app/views/dashboard/_activities.html.haml
+++ b/app/views/dashboard/_activities.html.haml
@@ -7,7 +7,7 @@
= event_filter_link EventFilter.team, 'Team'
- if @events.any?
- .content_list= render @events
+ .content_list
- 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 9e3401e51b8..7f544406761 100644
--- a/app/views/dashboard/_groups.html.haml
+++ b/app/views/dashboard/_groups.html.haml
@@ -1,5 +1,5 @@
.groups_box
- %h5
+ %h5.title
Groups
%small
(#{groups.count})
@@ -17,4 +17,4 @@
&rarr;
%span.last_activity
%strong Projects:
- %span= group.projects.authorized_for(current_user).count
+ %span= current_user.authorized_projects.where(namespace_id: group.id).count
diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml
index cffafb5445c..6c1304ee4a8 100644
--- a/app/views/dashboard/_projects.html.haml
+++ b/app/views/dashboard/_projects.html.haml
@@ -1,5 +1,5 @@
.projects_box
- %h5
+ %h5.title
Projects
%small
(#{projects.total_count})
diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml
index b64aa86cf73..abbe3101fc3 100644
--- a/app/views/dashboard/index.html.haml
+++ b/app/views/dashboard/index.html.haml
@@ -7,5 +7,3 @@
- else
= 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 52863229644..68e3b3dcaf5 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -13,7 +13,8 @@
- @issues.group_by(&:project).each do |group|
%div.ui-box
- @project = group[0]
- %h5= link_to_project @project
+ %h5.title
+ = link_to_project @project
%ul.well-list.issues_table
- group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue})
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index ea7c8c9a3d5..c5245da731a 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -12,7 +12,8 @@
- @merge_requests.group_by(&:project).each do |group|
.ui-box
- @project = group[0]
- %h5= link_to_project @project
+ %h5.title
+ = link_to_project @project
%ul.well-list
- group[1].each do |merge_request|
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml
index 8c12969345f..7b57f424d61 100644
--- a/app/views/events/event/_note.html.haml
+++ b/app/views/events/event/_note.html.haml
@@ -19,7 +19,6 @@
= event.project_name
.event-body
- %span.hint
- &nbsp;
- %i.icon-comment
+ %span.event-note
+ %i.icon-comment-alt
= truncate event.target.note, length: 70
diff --git a/app/views/groups/_filter.html.haml b/app/views/groups/_filter.html.haml
new file mode 100644
index 00000000000..c8b0ad0f433
--- /dev/null
+++ b/app/views/groups/_filter.html.haml
@@ -0,0 +1,33 @@
+= form_tag group_filter_path(entity), method: 'get' do
+ %fieldset.dashboard-search-filter
+ = search_field_tag "search", params[:search], { placeholder: 'Search', class: 'search-text-input' }
+ = button_tag type: 'submit', class: 'btn' do
+ %i.icon-search
+
+ %fieldset
+ %legend Status:
+ %ul.nav.nav-pills.nav-stacked
+ %li{class: ("active" if !params[:status])}
+ = link_to group_filter_path(entity, status: nil) do
+ Open
+ %li{class: ("active" if params[:status] == 'closed')}
+ = link_to group_filter_path(entity, status: 'closed') do
+ Closed
+ %li{class: ("active" if params[:status] == 'all')}
+ = link_to group_filter_path(entity, status: 'all') do
+ All
+
+ %fieldset
+ %legend Projects:
+ %ul.nav.nav-pills.nav-stacked
+ - @projects.each do |project|
+ - unless entities_per_project(project, entity).zero?
+ %li{class: ("active" if params[:project_id] == project.id.to_s)}
+ = link_to group_filter_path(entity, project_id: project.id) do
+ = project.name_with_namespace
+ %small.right= entities_per_project(project, entity)
+
+ %fieldset
+ %hr
+ = link_to "Reset", group_filter_path(entity), class: 'btn right'
+
diff --git a/app/views/groups/_new_group_member.html.haml b/app/views/groups/_new_group_member.html.haml
new file mode 100644
index 00000000000..2d599816e2a
--- /dev/null
+++ b/app/views/groups/_new_group_member.html.haml
@@ -0,0 +1,18 @@
+= form_for @team_member, as: :team_member, url: team_members_group_path(@group) do |f|
+ %fieldset
+ %legend= "New Team member(s) for projects in #{@group.name}"
+
+ %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.active.alphabetically, :id, :name), {data: {placeholder: "Select users"}, class: "chosen xxlarge", multiple: true})
+
+ %h6 2. Set access level for them
+ .clearfix
+ = f.label :project_access, "Project Access"
+ .input= select_tag :project_access, options_for_select(Project.access_options, @team_member.project_access), class: "project-access-select chosen"
+
+ .form-actions
+ = hidden_field_tag :redirect_to, people_group_path(@group)
+ = f.submit 'Add', class: "btn save-btn"
+
diff --git a/app/views/groups/_new_member.html.haml b/app/views/groups/_new_member.html.haml
index f48c2c23d83..89ac05e774e 100644
--- a/app/views/groups/_new_member.html.haml
+++ b/app/views/groups/_new_member.html.haml
@@ -5,7 +5,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.not_in_project(@project).alphabetically, :id, :name), {data: {placeholder: "Select users"}, class: "chosen xxlarge", multiple: true})
%h6 2. Set access level for them
.clearfix
diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml
index 0b491879fe0..040d1ae94aa 100644
--- a/app/views/groups/_projects.html.haml
+++ b/app/views/groups/_projects.html.haml
@@ -1,5 +1,5 @@
.projects_box
- %h5
+ %h5.title
Projects
%small
(#{projects.count})
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 0daf4d752a8..ffca2dc75ea 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -3,17 +3,21 @@
%small (assigned to you)
%small.right #{@issues.total_count} issues
-%br
-.clearfix
-- if @issues.any?
- - @issues.group_by(&:project).each do |group|
- %div.ui-box
- - @project = group[0]
- %h5= @project.name
- %ul.well-list.issues_table
- - group[1].each do |issue|
- = render(partial: 'issues/show', locals: {issue: issue})
- %hr
- = paginate @issues, theme: "gitlab"
-- else
- %h3.nothing_here_message Nothing to show here
+%hr
+.row
+ .span3
+ = render 'filter', entity: 'issue'
+ .span9
+ - if @issues.any?
+ - @issues.group_by(&:project).each do |group|
+ %div.ui-box
+ - @project = group[0]
+ %h5.title
+ = link_to_project @project
+ %ul.well-list.issues_table
+ - group[1].each do |issue|
+ = render(partial: 'issues/show', locals: {issue: issue})
+ %hr
+ = paginate @issues, theme: "gitlab"
+ - else
+ %p.nothing_here_message Nothing to show here
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 72aa4ad11e1..c5245da731a 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -3,16 +3,22 @@
%small (authored by or assigned to you)
%small.right #{@merge_requests.total_count} merge requests
-%br
-- if @merge_requests.any?
- - @merge_requests.group_by(&:project).each do |group|
- %ul.well-list.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})
- %hr
- = paginate @merge_requests, theme: "gitlab"
+%hr
+.row
+ .span3
+ = render 'filter', entity: 'merge_request'
+ .span9
+ - if @merge_requests.any?
+ - @merge_requests.group_by(&:project).each do |group|
+ .ui-box
+ - @project = group[0]
+ %h5.title
+ = 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"
-- else
- %h3.nothing_here_message Nothing to show here
+ - else
+ %h3.nothing_here_message Nothing to show here
diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml
index be3dd7a4d78..0bceeaa3ceb 100644
--- a/app/views/groups/people.html.haml
+++ b/app/views/groups/people.html.haml
@@ -2,10 +2,10 @@
.span3
= render 'people_filter'
.span9
- - if @project && can?(current_user, :manage_group, @group)
- = render "new_member"
+ - if can?(current_user, :manage_group, @group)
+ = render (@project ? "new_member" : "new_group_member")
.ui-box
- %h5
+ %h5.title
Team
%small
(#{@users.size})
diff --git a/app/views/groups/search.html.haml b/app/views/groups/search.html.haml
index 6ca5630f43d..1ba4707aa52 100644
--- a/app/views/groups/search.html.haml
+++ b/app/views/groups/search.html.haml
@@ -6,70 +6,4 @@
= search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search"
= submit_tag 'Search', class: "btn primary wide"
- if params[:search].present?
- %br
- %h3
- Search results
- %small (#{@projects.count + @merge_requests.count + @issues.count})
- %hr
- .search_results
- .row
- .span6
- %table
- %thead
- %tr
- %th Projects
- %tbody
- - @projects.each do |project|
- %tr
- %td
- = link_to project do
- %strong.term= project.name
- %small.cgray
- last activity at
- = project.last_activity_date.stamp("Aug 25, 2011")
- - if @projects.blank?
- %tr
- %td
- %h4.nothing_here_message No Projects
- %br
- %table
- %thead
- %tr
- %th Merge Requests
- %tbody
- - @merge_requests.each do |merge_request|
- %tr
- %td
- = link_to [merge_request.project, merge_request] do
- %span.badge.badge-info ##{merge_request.id}
- &ndash;
- %strong.term= truncate merge_request.title, length: 50
- %strong.right
- %span.label= merge_request.project.name
- - if @merge_requests.blank?
- %tr
- %td
- %h4.nothing_here_message No Merge Requests
- .span6
- %table
- %thead
- %tr
- %th Issues
- %tbody
- - @issues.each do |issue|
- %tr
- %td
- = link_to [issue.project, issue] do
- %span.badge.badge-info ##{issue.id}
- &ndash;
- %strong.term= truncate issue.title, length: 40
- %strong.right
- %span.label= issue.project.name
- - if @issues.blank?
- %tr
- %td
- %h4.nothing_here_message No Issues
- :javascript
- $(function() {
- $(".search_results .term").highlight("#{params[:search]}");
- })
+ = render 'search/result'
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 76bc2639d61..d7d3f869895 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -7,7 +7,7 @@
%span.cgray Events and projects are filtered in scope of group
%hr
- if @events.any?
- .content_list= render @events
+ .content_list
- else
%p.nothing_here_message Projects activity will be displayed here
.loading.hide
@@ -26,4 +26,4 @@
= link_to "@gitlabhq", "https://twitter.com/gitlabhq"
:javascript
- $(function(){ Pager.init(20); });
+ $(function(){ Pager.init(20, true); });
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index ebd499c05e0..dc22b672cb7 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -9,31 +9,41 @@
%br
Fast, secure and stable solution based on Ruby on Rails & Gitolite.
-%hr
+%br
+
+.row
+ .span6
+ .ui-box
+ .title
+ %h5 Help
+ %ul.well-list
+ %li
+ %span= link_to "Workflow", help_workflow_path
-%h3 Help
+ %li
+ %span= link_to "Permissions", help_permissions_path
-%ol
- %li
- %h5= link_to "Workflow", help_workflow_path
+ %li
+ %span= link_to "Web Hooks", help_web_hooks_path
- %li
- %h5= link_to "Permissions", help_permissions_path
+ %li
+ %span= link_to "API", help_api_path
- %li
- %h5= link_to "Web Hooks", help_web_hooks_path
+ %li
+ %span= link_to "GitLab Markdown", help_markdown_path
- %li
- %h5= link_to "System Hooks", help_system_hooks_path
+ %li
+ %span= link_to "SSH keys", help_ssh_path
- %li
- %h5= link_to "API", help_api_path
+ .span6
+ .ui-box
+ .title
+ %h5 Admin Guide
+ %ul.well-list
- %li
- %h5= link_to "GitLab Markdown", help_markdown_path
+ %li
+ %span= link_to "GitLab Rake Tasks", help_raketasks_path
- %li
- %h5= link_to "SSH keys", help_ssh_path
+ %li
+ %span= link_to "System Hooks", help_system_hooks_path
- %li
- %h5= link_to "GitLab Rake Tasks", help_raketasks_path
diff --git a/app/views/help/markdown.html.haml b/app/views/help/markdown.html.haml
index aa608ed6d9a..0419f7c131a 100644
--- a/app/views/help/markdown.html.haml
+++ b/app/views/help/markdown.html.haml
@@ -1,6 +1,6 @@
%h3.page_title GitLab Flavored Markdown
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
@@ -120,7 +120,7 @@
for commits
-# this example will only be shown if the user has a project with at least one issue
- - if @project = current_user.projects.first
+ - if @project = current_user.authorized_projects.first
- if issue = @project.issues.first
%p For example in your #{link_to @project.name, project_path(@project)} project, writing:
%pre= "This is related to ##{issue.id}. @#{current_user.name} is working on solving it."
diff --git a/app/views/help/raketasks.html.haml b/app/views/help/raketasks.html.haml
index 62cfa1521a7..f015451a673 100644
--- a/app/views/help/raketasks.html.haml
+++ b/app/views/help/raketasks.html.haml
@@ -16,6 +16,8 @@
= link_to "User Management", "#user_management", 'data-toggle' => 'tab'
%li
= link_to "Backup & Restore", "#backup_restore", 'data-toggle' => 'tab'
+ %li
+ = link_to "Cleanup", "#cleanup", 'data-toggle' => 'tab'
.tab-content
.tab-pane.active#features
@@ -45,6 +47,15 @@
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "user_management.md"))
+ .tab-pane#cleanup
+ .file_holder
+ .file_title
+ %i.icon-file
+ Cleanup
+ .file_content.wiki
+ = preserve do
+ = markdown File.read(Rails.root.join("doc", "raketasks", "cleanup.md"))
+
.tab-pane#backup_restore
.file_holder
.file_title
diff --git a/app/views/hooks/_data_ex.html.erb b/app/views/hooks/_data_ex.html.erb
index 7dd6b9e0750..b4281fa18c7 100644
--- a/app/views/hooks/_data_ex.html.erb
+++ b/app/views/hooks/_data_ex.html.erb
@@ -1,45 +1,43 @@
<% data_ex_str = <<eos
{
- :before => "95790bf891e76fee5e1747ab589903a6a1f80f22",
- :after => "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
- :ref => "refs/heads/master",
- :user_id => 4,
- :user_name => "John Smith",
- :repository => {
- :name => "Diaspora",
- :url => "localhost/diaspora",
- :description => "",
- :homepage => "localhost/diaspora",
- :private => true
+ "before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
+ "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
+ "ref": "refs/heads/master",
+ "user_id": 4,
+ "user_name": "John Smith",
+ "repository": {
+ "name": "Diaspora",
+ "url": "git@localhost:diaspora.git",
+ "description": "",
+ "homepage": "http://localhost/diaspora",
+ },
+ "commits": [
+ {
+ "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
+ "message": "Update Catalan translation to e38cb41.",
+ "timestamp": "2011-12-12T14:27:31+02:00",
+ "url": "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
+ "author": {
+ "name": "Jordi Mallach",
+ "email": "jordi@softcatala.org",
+ }
},
- :commits => [
- [0] {
- :id => "450d0de7532f8b663b9c5cce183b...",
- :message => "Update Catalan translation to e38cb41.",
- :timestamp => "2011-12-12T14:27:31+02:00",
- :url => "http://localhost/diaspora/commits/450d0de7532f...",
- :author => {
- :name => "Jordi Mallach",
- :email => "jordi@softcatala.org"
- }
- },
-
- ....
-
- [3] {
- :id => "da1560886d4f094c3e6c9ef40349...",
- :message => "fixed readme",
- :timestamp => "2012-01-03T23:36:29+02:00",
- :url => "http://localhost/diaspora/commits/da1560886d...",
- :author => {
- :name => "GitLab dev user",
- :email => "gitlabdev@dv6700.(none)"
- }
- }
- ],
- total_commits_count => 4
-}
+ // ...
+ {
+ "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
+ "message": "fixed readme",
+ "timestamp": "2012-01-03T23:36:29+02:00",
+ "url": "http://localhost/diaspora/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
+ "author": {
+ "name": "GitLab dev user",
+ "email": "gitlabdev@dv6700.(none)",
+ },
+ },
+ ],
+ "total_commits_count": 4,
+};
eos
%>
-<% js_lexer = Pygments::Lexer[:js] %>
-<%= raw js_lexer.highlight(data_ex_str) %>
+<div class="<%= user_color_scheme_class%>">
+ <%= raw Pygments::Lexer[:js].highlight(data_ex_str) %>
+</div>
diff --git a/app/views/issues/_filter.html.haml b/app/views/issues/_filter.html.haml
new file mode 100644
index 00000000000..9b710a71772
--- /dev/null
+++ b/app/views/issues/_filter.html.haml
@@ -0,0 +1,20 @@
+= form_tag project_issues_path(@project), method: 'get' do
+ %fieldset
+ %ul.nav.nav-pills.nav-stacked
+ %li{class: ("active" if !params[:status])}
+ = link_to project_issues_path(@project, status: nil) do
+ Open
+ %li{class: ("active" if params[:status] == 'to_me')}
+ = link_to project_issues_path(@project, status: 'to_me') do
+ Assigned To Me
+ %li{class: ("active" if params[:status] == 'closed')}
+ = link_to project_issues_path(@project, status: 'closed') do
+ Closed
+ %li{class: ("active" if params[:status] == 'all')}
+ = link_to project_issues_path(@project, status: 'all') do
+ All
+
+ %fieldset
+ %hr
+ = link_to "Reset", project_issues_path(@project), class: 'btn right'
+
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 030f797c088..bef235f2dea 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -6,26 +6,27 @@
- @issue.errors.full_messages.each do |msg|
%span= msg
%br
- .issue_form_box
- .issue_title
+ .ui-box.ui-box-show
+ .ui-box-head
.clearfix
= f.label :title do
%strong= "Subject *"
.input
= 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
- %i.icon-user
- Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
- .issue_milestone
- = f.label :milestone_id do
- %i.icon-time
- Milestone
- .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
+ .ui-box-body
+ .clearfix
+ .issue_assignee.pull-left
+ = f.label :assignee_id do
+ %i.icon-user
+ Assign to
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
+ .issue_milestone.pull-left
+ = f.label :milestone_id do
+ %i.icon-time
+ Milestone
+ .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
- .issue_description
+ .ui-box-bottom
.clearfix
= f.label :label_list do
%i.icon-tag
@@ -43,7 +44,7 @@
.actions
- if @issue.new_record?
- = f.submit 'Submit new issue', class: "btn save-btn"
+ = f.submit 'Submit new issue', class: "btn success"
-else
= f.submit 'Save changes', class: "save-btn btn"
diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml
index d7ba4300ce7..8821dbb8d98 100644
--- a/app/views/issues/_issues.html.haml
+++ b/app/views/issues/_issues.html.haml
@@ -3,12 +3,10 @@
- if @issues.present?
%li.bottom
- .row
- .span7= paginate @issues, remote: true, theme: "gitlab"
- .span3.right
- %span.cgray.right
- %span.issue_counter #{@issues.total_count}
- issues for this filter
+ .left= paginate @issues, remote: true, theme: "gitlab"
+ .right
+ %span.issue_counter #{@issues.total_count}
+ issues for this filter
- else
%li
%h4.nothing_here_message Nothing to show here
diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml
index 4641e8bdc63..dcef901c15f 100644
--- a/app/views/issues/_show.html.haml
+++ b/app/views/issues/_show.html.haml
@@ -3,10 +3,6 @@
.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)
.right
- - issue.labels.each do |label|
- %span.label.label-tag.grouped
- %i.icon-tag
- = label.name
- if issue.notes.any?
%span.btn.small.disabled.grouped
%i.icon-comment
@@ -36,3 +32,8 @@
- if issue.votes_count > 0
= render 'votes/votes_inline', votable: issue
+ %span
+ - issue.labels.each do |label|
+ %span.label
+ %i.icon-tag
+ = label.name
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 08d4393b201..d5c29c780ce 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -2,61 +2,47 @@
.issues_content
%h3.page_title
Issues
- %small (<span class=issue_counter>#{@issues.total_count}</span>)
+ %span (<span class=issue_counter>#{@issues.total_count}</span>)
.right
.span5
- if can? current_user, :write_issue, @project
- = 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
+ = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "right btn primary", 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
= hidden_field_tag :project_id, @project.id, { id: 'project_id' }
- = hidden_field_tag :status, params[:f]
+ = hidden_field_tag :status, params[:status]
= search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search span3 right neib search-text-input' }
.clearfix
- %div#issues-table-holder.ui-box
- .title
- = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
-
-
- .issues_bulk_update.hide
- = form_tag bulk_update_project_issues_path(@project), method: :post do
- %span.update_issues_text Update selected issues with &nbsp;
- .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(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"
- .issues_filters
- .left
- %ul.nav.nav-pills.left
- %li{class: ("active" if (params[:f] == issues_filter[:open] || !params[:f]))}
- = link_to project_issues_path(@project, f: issues_filter[:open], milestone_id: params[:milestone_id]) do
- Open
- %li{class: ("active" if params[:f] == issues_filter[:closed])}
- = link_to project_issues_path(@project, f: issues_filter[:closed], milestone_id: params[:milestone_id]) do
- Closed
- %li{class: ("active" if params[:f] == issues_filter[:to_me])}
- = link_to project_issues_path(@project, f: issues_filter[:to_me], milestone_id: params[:milestone_id]) do
- To Me
- %li{class: ("active" if params[:f] == issues_filter[:all])}
- = link_to project_issues_path(@project, f: issues_filter[:all], milestone_id: params[:milestone_id]) do
- All
-
- .right
- = 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] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
- = hidden_field_tag :f, params[:f]
+.row
+ .span3
+ = render 'filter', entity: 'issue'
+ .span9
+ %div#issues-table-holder.ui-box
+ .title
+ = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
.clearfix
+ .issues_bulk_update.hide
+ = form_tag bulk_update_project_issues_path(@project), method: :post do
+ %span.update_issues_text Update selected issues with &nbsp;
+ .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(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = hidden_field_tag 'update[issues_ids]', []
+ = hidden_field_tag :status, params[:status]
+ = button_tag "Save", class: "btn update_selected_issues btn-small save-btn"
+ .issues_filters
+ = form_tag project_issues_path(@project), method: :get 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] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = hidden_field_tag :status, params[:status]
- %ul#issues-table.well-list.issues_table
- = render "issues"
+ %ul#issues-table.well-list.issues_table
+ = render "issues"
:javascript
$(function(){
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index b1014edc6c5..55fc0aee0df 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -24,14 +24,14 @@
&larr; To issues list
-.main_box
- .top_box_content
+.ui-box.ui-box-show
+ .ui-box-head
%h4.box-title
- if @issue.closed
.error.status_info Closed
= gfm escape_once(@issue.title)
- .middle_box_content
+ .ui-box-body
%cite.cgray
Created by #{link_to_member(@project, @issue.author)}
- if @issue.assignee
@@ -44,13 +44,13 @@
.right
- @issue.labels.each do |label|
- %span.label.label-issue
+ %span.label
%i.icon-tag
= label.name
&nbsp;
- if @issue.description.present?
- .bottom_box_content
+ .ui-box-bottom
= preserve do
= markdown @issue.description
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 4a0f60d36c2..9d035f0e012 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -1,8 +1,8 @@
%head
%meta{charset: "utf-8"}
%title
+ = "#{title} | " if defined?(title)
GitLab
- = " > #{title}" if defined?(title)
= favicon_link_tag 'favicon.ico'
= stylesheet_link_tag "application"
= javascript_include_tag "application"
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 8fbec43f4a1..f4b2228a41b 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -2,7 +2,8 @@
.navbar-inner
.container
%div.app_logo
- = link_to root_path, class: "home", title: "Home" do
+ %span.separator
+ = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do
%h1 GITLAB
%span.separator
%h1.project_name= title
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 6b643ec8ccb..a60e7febe76 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -19,6 +19,6 @@
= nav_link(controller: :hooks) do
= link_to "Hooks", admin_hooks_path
= nav_link(controller: :resque) do
- = link_to "Resque", admin_resque_path
+ = link_to "Background Jobs", admin_resque_path
.content= yield
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index a41de538436..a197de38749 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -15,7 +15,7 @@
= nav_link(path: 'dashboard#merge_requests') do
= link_to dashboard_merge_requests_path do
Merge Requests
- %span.count= current_user.cared_merge_requests.count
+ %span.count= current_user.cared_merge_requests.opened.count
= nav_link(path: 'search#show') do
= link_to "Search", search_path
= nav_link(path: 'help#index') do
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index d40d9525bb8..f47e8b3e9ff 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -15,7 +15,7 @@
= nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group) do
Merge Requests
- %span.count= current_user.cared_merge_requests.of_group(@group).count
+ %span.count= current_user.cared_merge_requests.opened.of_group(@group).count
= nav_link(path: 'groups#search') do
= link_to "Search", search_group_path(@group)
= nav_link(path: 'groups#people') do
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index c418e1dbc68..3db1f59b54d 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -13,10 +13,10 @@
%td{style: "font-size: 0px;", width: "20"}
\ 
%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;"}
+ %h1{style: "color: #BBBBBB; font: normal 20px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"}
GITLAB
- if @project
- &rarr; #{@project.name_with_namespace}
+ \/ #{@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
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index 709807456c8..e00f96a7723 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -14,9 +14,9 @@
- if @project.repo_exists?
- if can? current_user, :download_code, @project
= nav_link(controller: %w(tree blob blame)) do
- = link_to 'Files', project_tree_path(@project, @ref || @project.root_ref)
+ = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref)
= nav_link(controller: %w(commit commits compare repositories protected_branches)) do
- = link_to "Commits", project_commits_path(@project, @ref || @project.root_ref)
+ = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref)
= nav_link(path: 'projects#graph') do
= link_to "Network", graph_project_path(@project)
diff --git a/app/views/merge_requests/_filter.html.haml b/app/views/merge_requests/_filter.html.haml
new file mode 100644
index 00000000000..86148fbcfee
--- /dev/null
+++ b/app/views/merge_requests/_filter.html.haml
@@ -0,0 +1,20 @@
+= form_tag project_issues_path(@project), method: 'get' do
+ %fieldset
+ %ul.nav.nav-pills.nav-stacked
+ %li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
+ = link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do
+ Open
+ %li{class: ("active" if params[:f] == "closed")}
+ = link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do
+ Closed
+ %li{class: ("active" if params[:f] == 'assigned-to-me')}
+ = link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do
+ Assigned To Me
+ %li{class: ("active" if params[:f] == 'all')}
+ = link_to project_merge_requests_path(@project, f: 'all', milestone_id: params[:milestone_id]) do
+ All
+
+ %fieldset
+ %hr
+ = link_to "Reset", project_merge_requests_path(@project), class: 'btn right'
+
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 9606e2e53b3..9a4f0617a3a 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -1,54 +1,59 @@
-= form_for [@project, @merge_request], html: { class: "new_merge_request form-horizontal" } do |f|
+= form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |f|
-if @merge_request.errors.any?
.alert-message.block-message.error
%ul
- @merge_request.errors.full_messages.each do |msg|
%li= msg
- %h4.cdark 1. Select Branches
- %br
+ %fieldset
+ %legend 1. Select Branches
- .row
- .span5
- .mr_branch_box
- %h5 From (Head Branch)
- .body
- .padded= f.select(:source_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
- .mr_source_commit
+ .row
+ .span5
+ .mr_branch_box
+ %h5.cgray From (Head Branch)
+ .body
+ .padded= f.select(:source_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+ .mr_source_commit
- .span2
- %center= image_tag "merge.png", class: 'mr_direction_tip'
- .span5
- .mr_branch_box
- %h5 To (Base Branch)
- .body
- .padded= f.select(:target_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
- .mr_target_commit
+ .span2
+ %center= image_tag "merge.png", class: 'mr_direction_tip'
+ .span5
+ .mr_branch_box
+ %h5.cgray To (Base Branch)
+ .body
+ .padded= f.select(:target_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+ .mr_target_commit
- %h4.cdark 2. Fill info
+ %fieldset
+ %legend 2. Fill info
- .clearfix
- .merge_requests_form_box
- .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, required: true
- .merge_requests_middle_box
- .merge_requests_assignee
- = f.label :assignee_id do
- %i.icon-user
- Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
- .merge_requests_milestone
- = f.label :milestone_id do
- %i.icon-time
- Milestone
- .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
+ .ui-box.ui-box-show
+ .ui-box-head
+ .clearfix
+ = f.label :title do
+ %strong= "Title *"
+ .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
+ .ui-box-body
+ .clearfix
+ .left
+ = f.label :assignee_id do
+ %i.icon-user
+ Assign to
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
+ .left
+ = f.label :milestone_id do
+ %i.icon-time
+ Milestone
+ .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
.control-group
.form-actions
- = f.submit 'Save', class: "btn save-btn"
+ - if @merge_request.new_record?
+ = f.submit 'Submit merge request', class: "btn success"
+ -else
+ = f.submit 'Save changes', class: "save-btn btn"
- if @merge_request.new_record?
= link_to project_merge_requests_path(@project), class: "btn cancel-btn" do
Cancel
@@ -59,8 +64,9 @@
:javascript
$(function(){
disableButtonIfEmptyField("#merge_request_title", ".save-btn");
- var source_branch = $("#merge_request_source_branch");
- var target_branch = $("#merge_request_target_branch");
+
+ var source_branch = $("#merge_request_source_branch")
+ , target_branch = $("#merge_request_target_branch");
$.get("#{branch_from_project_merge_requests_path(@project)}", {ref: source_branch.val() });
$.get("#{branch_to_project_merge_requests_path(@project)}", {ref: target_branch.val() });
diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml
index 8285a56d184..cefd33c0cdf 100644
--- a/app/views/merge_requests/_show.html.haml
+++ b/app/views/merge_requests/_show.html.haml
@@ -1,31 +1,33 @@
-= render "merge_requests/show/mr_title"
-= 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"
+.merge-request
+ = render "merge_requests/show/mr_title"
+ = 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?
- %ul.nav.nav-tabs.mr_nav_tabs
- %li
- = link_to "#notes", title: "Discussion", "data-url" => project_merge_request_path(@project, @merge_request), class: "merge-notes-tab tab" do
- %i.icon-comments
- Discussion
- %li
- = link_to "#diffs", title: "Diff", "data-url" => diffs_project_merge_request_path(@project, @merge_request), class: "merge-diffs-tab tab" do
- %i.icon-list-alt
- Diff
+ - if @commits.present?
+ %ul.nav.nav-tabs
+ %li.notes-tab{data: {action: 'notes'}}
+ = link_to project_merge_request_path(@project, @merge_request) do
+ %i.icon-comment
+ Discussion
+ %li.diffs-tab{data: {action: 'diffs'}}
+ = link_to diffs_project_merge_request_path(@project, @merge_request) do
+ %i.icon-list-alt
+ Diff
-.merge_request_notes.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
- = render "notes/notes_with_form"
-.merge-request-diffs
- = render "merge_requests/show/diffs" if @diffs
-.status
+ .notes.tab-content.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
+ = render "notes/notes_with_form"
+ .diffs.tab-content
+ = render "merge_requests/show/diffs" if @diffs
+ .status
:javascript
+ var merge_request;
$(function(){
- MergeRequest.init({
+ merge_request = new MergeRequest({
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)}",
@@ -33,10 +35,5 @@
current_state: "#{@merge_request.human_state}",
action: "#{controller.action_name}"
});
-
- $(".edit_merge_request").live("ajax:beforeSend", function() {
- $('.can_be_merged').hide();
- $('.merge_in_progress').show();
- })
- })
+ });
diff --git a/app/views/merge_requests/automerge.js.haml b/app/views/merge_requests/automerge.js.haml
index 93e184455af..e01ff662e7d 100644
--- a/app/views/merge_requests/automerge.js.haml
+++ b/app/views/merge_requests/automerge.js.haml
@@ -3,5 +3,5 @@
location.reload();
-else
:plain
- MergeRequest.already_cannot_be_merged()
+ merge_request.alreadyOrCannotBeMerged()
diff --git a/app/views/merge_requests/commits.js.haml b/app/views/merge_requests/commits.js.haml
index 76322bdb210..923b1ea032f 100644
--- a/app/views/merge_requests/commits.js.haml
+++ b/app/views/merge_requests/commits.js.haml
@@ -1,4 +1,4 @@
:plain
- $(".merge-request-commits").html("#{escape_javascript(render(partial: "commits"))}");
+ merge_request.$(".commits").html("#{escape_javascript(render(partial: "commits"))}");
diff --git a/app/views/merge_requests/diffs.js.haml b/app/views/merge_requests/diffs.js.haml
index c758cf69015..266892c01ef 100644
--- a/app/views/merge_requests/diffs.js.haml
+++ b/app/views/merge_requests/diffs.js.haml
@@ -1,3 +1,2 @@
:plain
- $(".merge-request-diffs").html("#{escape_javascript(render(partial: "merge_requests/show/diffs"))}");
-
+ merge_request.$(".diffs").html("#{escape_javascript(render(partial: "merge_requests/show/diffs"))}");
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index 5b234bfbe02..43651a5ca15 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -1,48 +1,35 @@
+- if can? current_user, :write_issue, @project
+ = link_to new_project_merge_request_path(@project), class: "right btn primary", title: "New Merge Request" do
+ %i.icon-plus
+ New Merge Request
%h3.page_title
Merge Requests
- - if can? current_user, :write_issue, @project
- = link_to new_project_merge_request_path(@project), class: "right btn", title: "New Merge Request" do
- New Merge Request
%br
-.ui-box
- .title
- .left
- %ul.nav.nav-pills
- %li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
- = link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do
- Open
- %li{class: ("active" if params[:f] == "closed")}
- = link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do
- Closed
- %li{class: ("active" if params[:f] == 'assigned-to-me')}
- = link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do
- To Me
- %li{class: ("active" if params[:f] == 'all')}
- = link_to project_merge_requests_path(@project, f: 'all', milestone_id: params[:milestone_id]) do
- All
- .right
- = form_tag project_merge_requests_path(@project), id: "merge_requests_search_form", method: :get, class: :right do
- = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
- = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
- = hidden_field_tag :f, params[:f]
- .clearfix
+.row
+ .span3
+ = render 'filter', entity: 'issue'
+ .span9
+ .ui-box
+ .title
+ = form_tag project_merge_requests_path(@project), id: "merge_requests_search_form", method: :get, class: :left do
+ = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
+ = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = hidden_field_tag :f, params[:f]
+ .clearfix
- %ul.well-list
- = render @merge_requests
- - if @merge_requests.blank?
- %li
- %h4.nothing_here_message Nothing to show here
- - if @merge_requests.present?
- %li.bottom
- .row
- .span7= paginate @merge_requests, theme: "gitlab"
- .span4.right
- %span.cgray.right #{@merge_requests.total_count} merge requests for this filter
+ %ul.well-list
+ = render @merge_requests
+ - if @merge_requests.blank?
+ %li
+ %h4.nothing_here_message Nothing to show here
+ - if @merge_requests.present?
+ %li.bottom
+ .left= paginate @merge_requests, theme: "gitlab"
+ .right
+ %span.cgray.right #{@merge_requests.total_count} merge requests for this filter
:javascript
- $(function() {
- merge_requestsPage();
- })
+ $(merge_requestsPage);
diff --git a/app/views/merge_requests/show.js.haml b/app/views/merge_requests/show.js.haml
index 7f423c786de..2ce6eb63290 100644
--- a/app/views/merge_requests/show.js.haml
+++ b/app/views/merge_requests/show.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".merge-request-notes").html("#{escape_javascript(render notes/notes_with_form")}");
+ merge_request.$(".notes").html("#{escape_javascript(render "notes/notes_with_form")}");
diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml
index 796922776d9..5e27b6dc25a 100644
--- a/app/views/merge_requests/show/_commits.html.haml
+++ b/app/views/merge_requests/show/_commits.html.haml
@@ -1,18 +1,18 @@
- if @commits.present?
.ui-box
- %h5
+ %h5.title
%i.icon-list
Commits (#{@commits.count})
- .merge-request-commits
+ .commits
- if @commits.count > 8
- %ul.first_mr_commits.well-list
+ %ul.first-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.well-list
+ %a.show-all-commits Click here to show all
+ %ul.all-commits.hide.well-list
- @commits.each do |commit|
= render "commits/commit", commit: commit
diff --git a/app/views/merge_requests/show/_mr_accept.html.haml b/app/views/merge_requests/show/_mr_accept.html.haml
index f24228856ff..128ffe76782 100644
--- a/app/views/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/merge_requests/show/_mr_accept.html.haml
@@ -9,19 +9,24 @@
%span
= form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f|
%p
- You can accept this request automatically.
- If you still want to do it manually -
+ You can accept this request automatically.
+ If you still want to do it manually -
%strong= link_to "click here", "#", class: "how_to_merge_link vlink", title: "How To Merge"
for instructions
.accept_group
- = f.submit "Accept Merge Request", class: "btn small success accept_merge_request"
- - unless @project.root_ref? @merge_request.source_branch
+ = f.submit "Accept Merge Request", class: "btn success accept_merge_request"
+ - unless @project.root_ref? @merge_request.source_branch
.remove_branch_holder
- = label_tag :should_remove_source_branch, class: "checkbox" do
+ = label_tag :should_remove_source_branch, class: "checkbox" do
= check_box_tag :should_remove_source_branch
Remove source-branch
.clearfix
-
+
+
+ .automerge_widget.no_satellite{style: "display:none"}
+ .alert.alert-error
+ %span
+ %strong This repository does not have satellite. Ask administrator to fix this issue
.automerge_widget.cannot_be_merged{style: "display:none"}
.alert.alert-info
@@ -40,6 +45,6 @@
.alert.alert-info
%strong This merge request already can not be merged. Try to reload page.
- .merge_in_progress.hide
+ .merge-in-progress.hide
%span.cgray Merge is in progress. Please wait. Page will be automatically reloaded. &nbsp;
= image_tag "ajax_loader.gif"
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index cd33732d191..644d7fcc58e 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -1,5 +1,5 @@
-.main_box
- .top_box_content
+.ui-box.ui-box-show
+ .ui-box-head
%h4.box-title
- if @merge_request.merged
.error.status_info
@@ -9,7 +9,7 @@
.error.status_info Closed
= gfm escape_once(@merge_request.title)
- .middle_box_content
+ .ui-box-body
%div
%cite.cgray
Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by #{link_to_member(@project, @merge_request.author)}
@@ -22,7 +22,7 @@
- if @merge_request.closed
- .bottom_box_content
+ .ui-box-bottom
- if @merge_request.merged?
%span
Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index c4975c72ef2..fc7ae51f184 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -27,8 +27,8 @@
%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
+.ui-box.ui-box-show
+ .ui-box-head
%h4.box-title
- if @milestone.closed
.error.status_info Closed
@@ -37,52 +37,47 @@
= gfm escape_once(@milestone.title)
- .middle_box_content
- %h5
+ .ui-box-body
+ %p
Progress:
- %small
- #{@milestone.closed_items_count} closed
- &ndash;
- #{@milestone.open_items_count} open
+ #{@milestone.closed_items_count} closed
+ &ndash;
+ #{@milestone.open_items_count} open
%span.right= @milestone.expires_at
.progress.progress-info
.bar{style: "width: #{@milestone.percent_complete}%;"}
- if @milestone.description.present?
- .bottom_box_content
+ .ui-box-bottom
= preserve do
= markdown @milestone.description
.row
.span6
- %table.milestone-issue-filter
- %thead
- %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
+ .ui-box.milestone-issue-filter
+ .title
+ %ul.nav.nav-pills
+ %li.active= link_to('Open Issues', '#')
+ %li=link_to('All Issues', '#')
+ %ul.well-list
+ - @issues.each do |issue|
+ %li{data: {closed: issue.closed}}
= link_to [@project, issue] do
%span.badge.badge-info ##{issue.id}
&ndash;
= link_to_gfm truncate(issue.title, length: 60), [@project, issue]
.span6
- %table.milestone-merge-requests-filter
- %thead
- %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
+ .ui-box.milestone-merge-requests-filter
+ .title
+ %ul.nav.nav-pills
+ %li.active= link_to('Open Merge Requests', '#')
+ %li=link_to('All Merge Requests', '#')
+ %ul.well-list
+ - @merge_requests.each do |merge_request|
+ %li{data: {closed: merge_request.closed}}
= link_to [@project, merge_request] do
%span.badge.badge-info ##{merge_request.id}
&ndash;
diff --git a/app/views/notes/_note.html.haml b/app/views/notes/_note.html.haml
index 8881cf5a847..6f7eea9827f 100644
--- a/app/views/notes/_note.html.haml
+++ b/app/views/notes/_note.html.haml
@@ -28,6 +28,8 @@
= preserve do
= markdown(note.note)
- if note.attachment.url
+ - if note.attachment.image?
+ = image_tag note.attachment.url, class: 'thumbnail span4'
.attachment.right
= link_to note.attachment.url, target: "_blank" do
%i.icon-attachment
diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml
index c433e80c9e5..27168eef742 100644
--- a/app/views/notify/issue_status_changed_email.html.haml
+++ b/app/views/notify/issue_status_changed_email.html.haml
@@ -1,8 +1,8 @@
%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;"}
+ %td{width: "21"}
+ %td
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
= "Issue was #{@issue_status} by #{@updated_by.name}"
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index fba4b865487..3cb5351319e 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -1,13 +1,13 @@
%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;"}
+ %td{width: "21"}
+ %td
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
New Issue was created and assigned to you.
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{width: "21"}
%tr
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{width: "21"}
%td{align: "left", style: "padding: 20px 0 0;"}
%p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "}
= "Issue ##{@issue.id}"
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 9819767011e..990d4d2aa87 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -14,6 +14,6 @@
%p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
%p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- Asignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
+ Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
%td
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 764cd094b76..3857f2f0318 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,23 +1,27 @@
%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; "}
- = "New comment for Merge Request !#{@merge_request.id}"
- = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{width: "21"}
+ %td
+ %h2{style: "color:#646464; font-weight: normal;"}
+ - if @note.for_diff_line?
+ = link_to "New comment on diff", diffs_project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
+ - else
+ = link_to "New comment", project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
+ for Merge Request ##{@merge_request.id}
+ %cite "#{truncate(@merge_request.title, length: 20)}"
+ %td{width: "21"}
%tr
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
- %td{style: "padding: 15px 0 15px;", valign: "top"}
- %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ %td{width: "21"}
+ %td
+ %p
+ %strong #{@note.author_name}
left next message:
%br
%table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
%tr
%td{valign: "top"}
- %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ %div{ style: "background:#f5f5f5; padding:10px 20px;border:1px solid #ddd" }
= markdown(@note.note)
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{width: "21"}
diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml
index 31a5d23242c..bc2d6f7078b 100644
--- a/app/views/notify/reassigned_issue_email.html.haml
+++ b/app/views/notify/reassigned_issue_email.html.haml
@@ -2,7 +2,7 @@
%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;"}
+ %td
%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: 30), project_issue_url(@issue.project, @issue)
diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml
index 3c290948d6c..522e45e637a 100644
--- a/app/views/profiles/account.html.haml
+++ b/app/views/profiles/account.html.haml
@@ -69,7 +69,7 @@
%i.icon-ok
Saved
%span.update-failed.cred.hide
- %i.icon-ok
+ %i.icon-remove
Failed
%ul.cred
%li It will change web url for personal projects.
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 934c1fdf7c4..64f931ca887 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -64,7 +64,7 @@
%legend
Personal projects:
%small.right
- %span= current_user.my_own_projects.count
+ %span= current_user.personal_projects.count
of
%span= current_user.projects_limit
.padded
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 7044d1f20be..c8eacdc2a46 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -15,13 +15,13 @@
= f.label :path do
Repository
.controls
- = text_field_tag :ppath, @project.path_to_repo, class: "xxlarge", readonly: true
+ = text_field_tag :ppath, @repository.path_to_repo, class: "xxlarge", readonly: true
- - unless @project.heads.empty?
+ - unless @repository.heads.empty?
.clearfix
= f.label :default_branch, "Default Branch"
- .input= f.select(:default_branch, @project.heads.map(&:name), {}, style: "width:210px;")
+ .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;")
%fieldset.features
%legend Features:
diff --git a/app/views/projects/_new_form.html.haml b/app/views/projects/_new_form.html.haml
index 2ef29cb0c65..2391c750bc8 100644
--- a/app/views/projects/_new_form.html.haml
+++ b/app/views/projects/_new_form.html.haml
@@ -7,7 +7,7 @@
Project name is
.input
= f.text_field :name, placeholder: "Example Project", class: "xxlarge"
- = f.submit 'Create project', class: "btn primary project-submit"
+ = f.submit 'Create project', class: "btn success project-submit"
- if current_user.several_namespaces?
.clearfix
diff --git a/app/views/protected_branches/index.html.haml b/app/views/protected_branches/index.html.haml
index f408fd16c2c..c1ecceda435 100644
--- a/app/views/protected_branches/index.html.haml
+++ b/app/views/protected_branches/index.html.haml
@@ -1,51 +1,54 @@
-= render "repositories/branches_head"
+= render "commits/head"
+.row
+ .span3
+ = render "repositories/filter"
+ .span9
+ .alert
+ %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}.
+ %p This ability allows:
+ %ul
+ %li keep stable branches secured
+ %li forced code review before merge to protected branches
+ %p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"}
-.alert
- %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}.
- %p This ability allows:
- %ul
- %li keep stable branches secured
- %li forced code review before merge to protected branches
- %p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"}
+ - if can? current_user, :admin_project, @project
+ = form_for [@project, @protected_branch] do |f|
+ -if @protected_branch.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @protected_branch.errors.full_messages.each do |msg|
+ %li= msg
-- if can? current_user, :admin_project, @project
- = form_for [@project, @protected_branch] do |f|
- -if @protected_branch.errors.any?
- .alert-message.block-message.error
- %ul
- - @protected_branch.errors.full_messages.each do |msg|
- %li= msg
+ .entry.clearfix
+ = f.label :name, "Branch"
+ .span3
+ = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"})
+ &nbsp;
+ = f.submit 'Protect', class: "primary btn"
- .entry.clearfix
- = f.label :name, "Branch"
- .span3
- = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"})
- &nbsp;
- = f.submit 'Protect', class: "primary btn"
-
-- unless @branches.empty?
- %table
- %thead
- %tr
- %th Name
- %th Last commit
- %th
- %tbody
- - @branches.each do |branch|
- %tr
- %td
- = link_to project_commits_path(@project, branch.name) do
- %strong= branch.name
- - if branch.name == @project.root_ref
- %span.label default
- %td
- - if branch.commit
- = link_to project_commit_path(@project, branch.commit.id) do
- = truncate branch.commit.id.to_s, length: 10
- = time_ago_in_words(branch.commit.committed_date)
- ago
- - else
- (branch was removed from repository)
- %td
- - if can? current_user, :admin_project, @project
- = link_to 'Unprotect', [@project, branch], confirm: 'Are you sure?', method: :delete, class: "danger btn small"
+ - unless @branches.empty?
+ %table
+ %thead
+ %tr
+ %th Name
+ %th Last commit
+ %th
+ %tbody
+ - @branches.each do |branch|
+ %tr
+ %td
+ = link_to project_commits_path(@project, branch.name) do
+ %strong= branch.name
+ - if @project.root_ref?(branch.name)
+ %span.label default
+ %td
+ - if branch.commit
+ = link_to project_commit_path(@project, branch.commit.id) do
+ = truncate branch.commit.id.to_s, length: 10
+ = time_ago_in_words(branch.commit.committed_date)
+ ago
+ - else
+ (branch was removed from repository)
+ %td
+ - if can? current_user, :admin_project, @project
+ = link_to 'Unprotect', [@project, branch], confirm: 'Are you sure?', method: :delete, class: "danger btn small"
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
index 2728b100ff6..a6faa5fd633 100644
--- a/app/views/repositories/_branch.html.haml
+++ b/app/views/repositories/_branch.html.haml
@@ -8,7 +8,7 @@
- else
%i.icon-unlock
%strong= truncate(branch.name, length: 60)
- - if branch.name == @project.root_ref
+ - if branch.name == @repository.root_ref
%span.label default
%td
= link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
@@ -22,6 +22,6 @@
%td
- if can? current_user, :download_code, @project
= link_to archive_project_repository_path(@project, ref: branch.name) do
- %i.icon-download
+ %i.icon-download-alt
Download
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index 496328baca5..44380133718 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -5,7 +5,7 @@
= link_to project_commits_path(@project, commit.head.name) do
%strong
= commit.head.name
- - if commit.head.name == @project.root_ref
+ - if @project.root_ref?(commit.head.name)
%span.label default
%td
diff --git a/app/views/repositories/_branches_head.html.haml b/app/views/repositories/_filter.html.haml
index 8f3e1ba3f81..e718d48190a 100644
--- a/app/views/repositories/_branches_head.html.haml
+++ b/app/views/repositories/_filter.html.haml
@@ -1,10 +1,9 @@
-= render "commits/head"
-%ul.nav.nav-pills
+%ul.nav.nav-pills.nav-stacked
= nav_link(path: 'repositories#show') do
= link_to 'Recent', project_repository_path(@project)
= nav_link(path: 'protected_branches#index') do
= link_to project_protected_branches_path(@project) do
- %i.icon-lock
Protected
+ %i.icon-lock
= nav_link(path: 'repositories#branches') do
- = link_to 'All', branches_project_repository_path(@project)
+ = link_to 'All branches', branches_project_repository_path(@project)
diff --git a/app/views/repositories/branches.html.haml b/app/views/repositories/branches.html.haml
index 4c246c69d7c..14b5082e44e 100644
--- a/app/views/repositories/branches.html.haml
+++ b/app/views/repositories/branches.html.haml
@@ -1,12 +1,15 @@
-= render "repositories/branches_head"
-- unless @branches.empty?
- %table
- %thead
- %tr
- %th Name
- %th Last commit
- %th
-
- %tbody
- - @branches.each do |branch|
- = render "repositories/branch", branch: branch
+= render "commits/head"
+.row
+ .span3
+ = render "filter"
+ .span9
+ - unless @branches.empty?
+ %table
+ %thead
+ %tr
+ %th Name
+ %th Last commit
+ %th
+ %tbody
+ - @branches.each do |branch|
+ = render "repositories/branch", branch: branch
diff --git a/app/views/repositories/show.html.haml b/app/views/repositories/show.html.haml
index fd0abac8414..e58e16f8bf1 100644
--- a/app/views/repositories/show.html.haml
+++ b/app/views/repositories/show.html.haml
@@ -1,11 +1,14 @@
-= render "branches_head"
-
-%table
- %thead
- %tr
- %th Name
- %th Last commit
- %th
- - @activities.each do |update|
- = render "repositories/branch", branch: update.head
+= render "commits/head"
+.row
+ .span3
+ = render "filter"
+ .span9
+ %table
+ %thead
+ %tr
+ %th Name
+ %th Last commit
+ %th
+ - @activities.each do |update|
+ = render "repositories/branch", branch: update.head
diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml
index a93814a4777..bdf047f1e98 100644
--- a/app/views/repositories/stats.html.haml
+++ b/app/views/repositories/stats.html.haml
@@ -7,7 +7,7 @@
%b Total commits:
%span= @stats.commits_count
%p
- %b Total files in #{@project.root_ref}:
+ %b Total files in #{@repository.root_ref}:
%span= @stats.files_count
%p
%b Authors:
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index 193cb2e30f2..d4b8bbe10d4 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -26,8 +26,14 @@
%td
- if can? current_user, :download_code, @project
= link_to archive_project_repository_path(@project, ref: tag.name) do
- %i.icon-download
+ %i.icon-download-alt
Download
- else
- %h3 No tags
+ %h3.nothing_here_message
+ Repository has no tags yet.
+ %br
+ %small
+ Use git tag command to add a new one:
+ %br
+ %span.monospace git tag -a v1.4 -m 'version 1.4'
diff --git a/app/views/search/_result.html.haml b/app/views/search/_result.html.haml
index 8b137891791..79bed4f737c 100644
--- a/app/views/search/_result.html.haml
+++ b/app/views/search/_result.html.haml
@@ -1 +1,85 @@
+%br
+%h3.page_title
+ Search results
+ %span.cgray (#{@projects.count + @merge_requests.count + @issues.count + @wiki_pages.count})
+%hr
+.search_results
+ .row
+ .span6
+ %table
+ %thead
+ %tr
+ %th Projects
+ %tbody
+ - @projects.each do |project|
+ %tr
+ %td
+ = link_to project do
+ %strong.term= project.name_with_namespace
+ %small.cgray
+ last activity at
+ = project.last_activity_date.stamp("Aug 25, 2011")
+ - if @projects.blank?
+ %tr
+ %td
+ %h4.nothing_here_message No Projects
+ %br
+ %table
+ %thead
+ %tr
+ %th Merge Requests
+ %tbody
+ - @merge_requests.each do |merge_request|
+ %tr
+ %td
+ = link_to [merge_request.project, merge_request] do
+ %span.badge.badge-info ##{merge_request.id}
+ &ndash;
+ %strong.term= truncate merge_request.title, length: 50
+ %strong.right
+ %span.label= merge_request.project.name
+ - if @merge_requests.blank?
+ %tr
+ %td
+ %h4.nothing_here_message No Merge Requests
+ .span6
+ %table
+ %thead
+ %tr
+ %th Issues
+ %tbody
+ - @issues.each do |issue|
+ %tr
+ %td
+ = link_to [issue.project, issue] do
+ %span.badge.badge-info ##{issue.id}
+ &ndash;
+ %strong.term= truncate issue.title, length: 40
+ %strong.right
+ %span.label= issue.project.name
+ - if @issues.blank?
+ %tr
+ %td
+ %h4.nothing_here_message No Issues
+ .span6
+ %table
+ %thead
+ %tr
+ %th Wiki
+ %tbody
+ - @wiki_pages.each do |wiki_page|
+ %tr
+ %td
+ = link_to project_wiki_path(wiki_page.project, wiki_page) do
+ %strong.term= truncate wiki_page.title, length: 40
+ %strong.right
+ %span.label= wiki_page.project.name
+ - if @wiki_pages.blank?
+ %tr
+ %td
+ %h4.nothing_here_message No wiki pages
+:javascript
+ $(function() {
+ $(".search_results .term").highlight("#{escape_javascript(params[:search])}");
+ })
diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml
index 8448193deb9..aa0d6d700d9 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -6,87 +6,4 @@
= search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search"
= submit_tag 'Search', class: "btn primary wide"
- if params[:search].present?
- %br
- %h3
- Search results
- %small (#{@projects.count + @merge_requests.count + @issues.count + @wiki_pages.count})
- %hr
- .search_results
- .row
- .span6
- %table
- %thead
- %tr
- %th Projects
- %tbody
- - @projects.each do |project|
- %tr
- %td
- = link_to project do
- %strong.term= project.name_with_namespace
- %small.cgray
- last activity at
- = project.last_activity_date.stamp("Aug 25, 2011")
- - if @projects.blank?
- %tr
- %td
- %h4.nothing_here_message No Projects
- %br
- %table
- %thead
- %tr
- %th Merge Requests
- %tbody
- - @merge_requests.each do |merge_request|
- %tr
- %td
- = link_to [merge_request.project, merge_request] do
- %span.badge.badge-info ##{merge_request.id}
- &ndash;
- %strong.term= truncate merge_request.title, length: 50
- %strong.right
- %span.label= merge_request.project.name
- - if @merge_requests.blank?
- %tr
- %td
- %h4.nothing_here_message No Merge Requests
- .span6
- %table
- %thead
- %tr
- %th Issues
- %tbody
- - @issues.each do |issue|
- %tr
- %td
- = link_to [issue.project, issue] do
- %span.badge.badge-info ##{issue.id}
- &ndash;
- %strong.term= truncate issue.title, length: 40
- %strong.right
- %span.label= issue.project.name
- - if @issues.blank?
- %tr
- %td
- %h4.nothing_here_message No Issues
- .span6
- %table
- %thead
- %tr
- %th Wiki
- %tbody
- - @wiki_pages.each do |wiki_page|
- %tr
- %td
- = link_to project_wiki_path(wiki_page.project, wiki_page) do
- %strong.term= truncate wiki_page.title, length: 40
- %strong.right
- %span.label= wiki_page.project.name
- - if @wiki_pages.blank?
- %tr
- %td
- %h4.nothing_here_message No wiki pages
- :javascript
- $(function() {
- $(".search_results .term").highlight("#{params[:search]}");
- })
+ = render 'search/result'
diff --git a/app/views/team_members/_form.html.haml b/app/views/team_members/_form.html.haml
index e5d9a4a4b5e..a963e462a78 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.active.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).alphabetically, :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/_team.html.haml b/app/views/team_members/_team.html.haml
index 462e75af183..365d9b65942 100644
--- a/app/views/team_members/_team.html.haml
+++ b/app/views/team_members/_team.html.haml
@@ -1,6 +1,6 @@
- grouper_project_members(@project).each do |access, members|
.ui-box
- %h5
+ %h5.title
= Project.access_options.key(access).pluralize
%small= members.size
%ul.well-list
diff --git a/app/views/team_members/import.html.haml b/app/views/team_members/import.html.haml
index 34f7fb03288..de82f416248 100644
--- a/app/views/team_members/import.html.haml
+++ b/app/views/team_members/import.html.haml
@@ -9,7 +9,7 @@
%p.slead Choose project you want to use as team source:
.padded
= label_tag :source_project_id, "Project"
- .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.projects, :id, :name), prompt: "Select project", class: "chosen xxlarge", required: true)
+ .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "chosen xxlarge", required: true)
.actions
= submit_tag 'Import', class: "btn save-btn"
diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml
index af9a6e6b92d..4008e8bd23e 100644
--- a/app/views/team_members/show.html.haml
+++ b/app/views/team_members/show.html.haml
@@ -8,8 +8,7 @@
= image_tag gravatar_icon(user.email, 60), class: "borders"
%h3.page_title
= user.name
- %small
- = user.email
+ %small (@#{user.username})
%hr
.back_link
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index a632bb3b0d7..c2842959510 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -3,9 +3,13 @@
%span.arrow
= link_to project_tree_path(@project, @ref) do
= @project.name
- - tree.breadcrumbs(6) do |link|
+ - tree.breadcrumbs(6) do |title, path|
\/
- %li= link
+ %li
+ - if path
+ = link_to truncate(title, length: 40), project_tree_path(@project, path)
+ - else
+ = link_to title, '#'
.clear
%div.tree_progress
@@ -26,7 +30,7 @@
%tr.tree-item
%td.tree-item-file-name
= image_tag "file_empty.png", size: '16x16'
- = link_to "..", tree.up_dir_path
+ = link_to "..", project_tree_path(@project, tree.up_dir_path)
%td
%td
%td
diff --git a/app/views/tree/blob/_download.html.haml b/app/views/tree/blob/_download.html.haml
index c307622995b..864c209db76 100644
--- a/app/views/tree/blob/_download.html.haml
+++ b/app/views/tree/blob/_download.html.haml
@@ -2,7 +2,7 @@
%center
= link_to project_blob_path(@project, @id) do
%div.padded
- %br
- = image_tag "download.png", width: 64
- %h3
+ %h4
+ %i.icon-download-alt
+ %br
Download (#{number_to_human_size blob.size})
diff --git a/app/views/wikis/_form.html.haml b/app/views/wikis/_form.html.haml
index 83b16b138d3..9eb2a571fe5 100644
--- a/app/views/wikis/_form.html.haml
+++ b/app/views/wikis/_form.html.haml
@@ -6,12 +6,12 @@
- @wiki.errors.full_messages.each do |msg|
%li= msg
- .main_box
- .top_box_content
+ .ui-box.ui-box-show
+ .ui-box-head
= f.label :title
.input= f.text_field :title, class: 'span8'
= f.hidden_field :slug
- .middle_box_content
+ .ui-box-body
.input
%span.cgray
Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
@@ -19,7 +19,7 @@
%code [Link Title](page-slug)
\.
- .bottom_box_content
+ .ui-box-bottom
= f.label :content
.input= f.text_area :content, class: 'span8 js-gfm-input'
.actions
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 1414ed490c9..e74379a65dd 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,7 +1,9 @@
class PostReceive
- @queue = :post_receive
+ include Sidekiq::Worker
- def self.perform(repo_path, oldrev, newrev, ref, identifier)
+ sidekiq_options queue: :post_receive
+
+ def perform(repo_path, oldrev, newrev, ref, identifier)
repo_path.gsub!(Gitlab.config.gitolite.repos_path.to_s, "")
repo_path.gsub!(/.git$/, "")
repo_path.gsub!(/^\//, "")
@@ -11,7 +13,7 @@ class PostReceive
# Ignore push from non-gitlab users
user = if identifier.eql? Gitlab.config.gitolite.admin_key
- email = project.commit(newrev).author.email rescue nil
+ email = project.repository.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)
User.find_by_email(identifier)
diff --git a/app/workers/system_hook_worker.rb b/app/workers/system_hook_worker.rb
index ca154136b97..3ebc62b7e7a 100644
--- a/app/workers/system_hook_worker.rb
+++ b/app/workers/system_hook_worker.rb
@@ -1,7 +1,9 @@
class SystemHookWorker
- @queue = :system_hook
+ include Sidekiq::Worker
- def self.perform(hook_id, data)
+ sidekiq_options queue: :system_hook
+
+ def perform(hook_id, data)
SystemHook.find(hook_id).execute data
end
end