diff --git a/.ruby-version b/.ruby-version index cd57a8b95d6..ccbccc3dc62 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.5 +2.2.0 diff --git a/CHANGELOG b/CHANGELOG index b87d8a2cada..b7e85f2e5e9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,21 +5,23 @@ v 7.7.0 - - - Mention notification level - - - - + - Markdown preview in wiki (Yuriy Glukhov) + - Raise group avatar filesize limit to 200kb - OAuth applications feature - - - - + - Show user SSH keys in admin area + - Developer can push to protected branches option - Set project path instead of project name in create form - - - - New side navigation - Updates to the messages returned by API (sponsored by O'Reilly Media) + - New UI layout with side navigation + - - - - Add alert message in case of outdated browser (IE < 10) - - Added API support for sorting projects + - Update gitlab_git to version 7.0.0.rc13 v 7.6.0 - Fork repository to groups @@ -45,8 +47,15 @@ v 7.6.0 - Possibility to create Milestones or Labels when Issues are disabled - Fix bug with showing gpg signature in tag +v 7.5.3 + - Bump gitlab_git to 7.0.0.rc12 (includes Rugged 0.21.2) + v 7.5.2 - Don't log Sidekiq arguments by default + - Fix restore of wiki repositories from backups + +v 7.5.1 + - Add missing timestamps to 'members' table v 7.5.0 - API: Add support for Hipchat (Kevin Houdebert) diff --git a/Gemfile b/Gemfile index 29f3df0ea9e..46ba460506b 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ gem "browser" # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '7.0.0.rc12' +gem "gitlab_git", '7.0.0.rc13' # Ruby/Rack Git Smart-HTTP Server Handler gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack' @@ -95,7 +95,7 @@ gem "github-markup" gem 'redcarpet', '~> 3.1.2' gem 'RedCloth' gem 'rdoc', '~>3.6' -gem 'org-ruby', '= 0.9.9' +gem 'org-ruby', '= 0.9.12' gem 'creole', '~>0.3.6' gem 'wikicloth', '=0.8.1' gem 'asciidoctor', '= 0.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 554223b83c9..4d4be5674dc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,7 +124,7 @@ GEM equalizer (0.0.8) erubis (2.7.0) escape_utils (0.2.4) - eventmachine (1.0.3) + eventmachine (1.0.4) excon (0.32.1) execjs (2.0.2) expression_parser (0.9.0) @@ -183,7 +183,7 @@ GEM mime-types (~> 1.19) gitlab_emoji (0.0.1.1) emoji (~> 1.0.1) - gitlab_git (7.0.0.rc12) + gitlab_git (7.0.0.rc13) activesupport (~> 4.0) charlock_holmes (~> 0.6) gitlab-linguist (~> 3.0) @@ -280,7 +280,7 @@ GEM kaminari (0.15.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - kgio (2.8.1) + kgio (2.9.2) launchy (2.4.2) addressable (~> 2.3) letter_opener (1.1.2) @@ -343,7 +343,7 @@ GEM omniauth-twitter (1.0.1) multi_json (~> 1.3) omniauth-oauth (~> 1.0) - org-ruby (0.9.9) + org-ruby (0.9.12) rubypants (~> 0.2) orm_adapter (0.5.0) pg (0.15.1) @@ -409,7 +409,7 @@ GEM activesupport (= 4.1.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - raindrops (0.12.0) + raindrops (0.13.0) rake (10.3.2) raphael-rails (2.1.2) rb-fsevent (0.9.3) @@ -643,7 +643,7 @@ DEPENDENCIES gitlab-grack (~> 2.0.0.pre) gitlab-linguist (~> 3.0.0) gitlab_emoji (~> 0.0.1.1) - gitlab_git (= 7.0.0.rc12) + gitlab_git (= 7.0.0.rc13) gitlab_meta (= 7.0) gitlab_omniauth-ldap (= 1.2.0) gollum-lib (~> 3.0.0) @@ -677,7 +677,7 @@ DEPENDENCIES omniauth-kerberos omniauth-shibboleth omniauth-twitter - org-ruby (= 0.9.9) + org-ruby (= 0.9.12) pg poltergeist (~> 1.5.1) pry diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index 24f7a9ad686..da708c96b09 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -292,11 +292,17 @@ table { .dashboard-intro-icon { float: left; + text-align: center; font-size: 32px; color: #AAA; - padding: 5px 0; - width: 50px; - min-height: 100px; + width: 60px; +} + +.dashboard-intro-text { + display: inline-block; + margin-left: -60px; + padding-left: 60px; + width: 100%; } .broadcast-message { diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss index e8b23090b0f..1a832569953 100644 --- a/app/assets/stylesheets/generic/forms.scss +++ b/app/assets/stylesheets/generic/forms.scss @@ -31,7 +31,12 @@ fieldset legend { margin-bottom: 18px; background-color: whitesmoke; border-top: 1px solid #e5e5e5; - padding-left: 17%; +} + +@media (min-width: $screen-sm-min) { + .form-actions { + padding-left: 17%; + } } label { @@ -88,7 +93,8 @@ label { @include box-shadow(none); } -.issuable-description { +.issuable-description, +.wiki-content { margin-top: 35px; } diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss index 4168e235cae..5a87cc6c612 100644 --- a/app/assets/stylesheets/generic/markdown_area.scss +++ b/app/assets/stylesheets/generic/markdown_area.scss @@ -65,6 +65,7 @@ .edit_note, .issuable-description, .milestone-description, +.wiki-content, .merge-request-form { .nav-tabs { margin-bottom: 0; diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 93ad17f57c0..3c3a0d92c6e 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -145,8 +145,12 @@ * Last push widget */ .event-last-push { + overflow: auto; .event-last-push-text { - @include str-truncated(75%); + @include str-truncated(100%); + float:left; + margin-right: -150px; + padding-right: 150px; line-height: 24px; } } diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index 920702ff3c4..8445b77c1a8 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -11,10 +11,27 @@ } } - .accept-group { - label { - margin: 5px; + .accept-merge-holder { + margin-top: 5px; + + .accept-action { + display: inline-block; + + .accept_merge_request { + padding: 10px 20px; + } + } + + .accept-control { + display: inline-block; margin-left: 20px; + padding: 10px 0; + line-height: 20px; + font-weight: bold; + + .checkbox { + margin: 0; + } } } } @@ -170,7 +187,3 @@ .merge-request-show-labels .label { padding: 6px 10px; } - -.mr-commits .commit { - padding: 10px 15px; -} diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index f362f449e70..95801f8b8fb 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -11,7 +11,7 @@ class Projects::MilestonesController < Projects::ApplicationController respond_to :html def index - @milestones = case params[:f] + @milestones = case params[:state] when 'all'; @project.milestones.order("state, due_date DESC") when 'closed'; @project.milestones.closed.order("due_date DESC") else @project.milestones.active.order("due_date ASC") diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 3e6f3b41ff5..4dae96644c8 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -4,6 +4,8 @@ module DashboardHelper sort: params[:sort], scope: params[:scope], group: params[:group], + tag: params[:tag], + visibility_level: params[:visibility_level], } options = exist_opts.merge(options) diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 975cdeda1bc..03fd461a462 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -33,18 +33,6 @@ module GroupsHelper title end - def group_filter_path(entity, options={}) - exist_opts = { - status: params[:status] - } - - options = exist_opts.merge(options) - - path = request.path - path << "?#{options.to_param}" - path - end - def group_settings_page? if current_controller?('groups') current_action?('edit') || current_action?('projects') diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb new file mode 100644 index 00000000000..6847123d2d4 --- /dev/null +++ b/app/helpers/milestones_helper.rb @@ -0,0 +1,9 @@ +module MilestonesHelper + def milestones_filter_path(opts = {}) + if @project + project_milestones_path(@project, opts) + elsif @group + group_milestones_path(@group, opts) + end + end +end diff --git a/app/models/event.rb b/app/models/event.rb index 65b4c2edfee..2a6c690ab91 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -174,7 +174,7 @@ class Event < ActiveRecord::Base def valid_push? data[:ref] && ref_name.present? - rescue => ex + rescue false end diff --git a/app/models/group.rb b/app/models/group.rb index b8ed3b8ac73..733afa2fc07 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -21,7 +21,7 @@ class Group < Namespace has_many :users, through: :group_members validate :avatar_type, if: ->(user) { user.avatar_changed? } - validates :avatar, file_size: { maximum: 100.kilobytes.to_i } + validates :avatar, file_size: { maximum: 200.kilobytes.to_i } mount_uploader :avatar, AttachmentUploader diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 2cc427d35c2..de0ee0e2c5a 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -189,7 +189,9 @@ class MergeRequest < ActiveRecord::Base end def automerge!(current_user, commit_message = nil) - MergeRequests::AutoMergeService.new.execute(self, current_user, commit_message) + MergeRequests::AutoMergeService. + new(target_project, current_user). + execute(self, commit_message) end def open? diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index a848d74044c..6ef4b210c56 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -35,7 +35,7 @@ class HipchatService < Service { type: 'text', name: 'token', placeholder: '' }, { type: 'text', name: 'room', placeholder: '' }, { type: 'text', name: 'server', - placeholder: 'Leave blank for default. https://chat.hipchat.com' } + placeholder: 'Leave blank for default. https://hipchat.example.com' } ] end @@ -47,7 +47,7 @@ class HipchatService < Service def gate options = { api_version: 'v2' } - options[:server_url] = server unless server.nil? + options[:server_url] = server unless server.blank? @gate ||= HipChat::Client.new(token, options) end diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb index 20b88d1510c..b5d90a74e15 100644 --- a/app/services/merge_requests/auto_merge_service.rb +++ b/app/services/merge_requests/auto_merge_service.rb @@ -5,15 +5,16 @@ module MergeRequests # mark merge request as merged and execute all hooks and notifications # Called when you do merge via GitLab UI class AutoMergeService < BaseMergeService - def execute(merge_request, current_user, commit_message) + def execute(merge_request, commit_message) merge_request.lock_mr if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message) merge_request.merge - notification.merge_mr(merge_request, current_user) + notification_service.merge_mr(merge_request, current_user) create_merge_event(merge_request, current_user) - execute_project_hooks(merge_request) + create_note(merge_request) + execute_hooks(merge_request) true else diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb index 700a21ca011..9579573adf9 100644 --- a/app/services/merge_requests/base_merge_service.rb +++ b/app/services/merge_requests/base_merge_service.rb @@ -1,21 +1,10 @@ module MergeRequests - class BaseMergeService + class BaseMergeService < MergeRequests::BaseService private - def notification - NotificationService.new - end - def create_merge_event(merge_request, current_user) EventCreateService.new.merge_mr(merge_request, current_user) end - - def execute_project_hooks(merge_request) - if merge_request.project - hook_data = merge_request.to_hook_data(current_user) - merge_request.project.execute_hooks(hook_data, :merge_request_hooks) - end - end end end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 1475973e543..859c3f56b2b 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -13,7 +13,7 @@ module MergeRequests merge_request.target_branch ||= merge_request.target_project.default_branch unless merge_request.target_branch && merge_request.source_branch - return build_failed(merge_request, "You must select source and target branches") + return build_failed(merge_request, nil) end # Generate suggested MR title based on source branch name @@ -59,7 +59,7 @@ module MergeRequests end def build_failed(merge_request, message) - merge_request.errors.add(:base, message) + merge_request.errors.add(:base, message) unless message.nil? merge_request.compare_commits = [] merge_request.can_be_created = false merge_request diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 680766140bd..5de7247d617 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -6,12 +6,13 @@ module MergeRequests # Called when you do merge via command line and push code # to target branch class MergeService < BaseMergeService - def execute(merge_request, current_user, commit_message) + def execute(merge_request, commit_message) merge_request.merge - notification.merge_mr(merge_request, current_user) + notification_service.merge_mr(merge_request, current_user) create_merge_event(merge_request, current_user) - execute_project_hooks(merge_request) + create_note(merge_request) + execute_hooks(merge_request) true rescue diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index baf0936cc3d..a6705de61f2 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -32,7 +32,9 @@ module MergeRequests merge_requests.uniq.select(&:source_project).each do |merge_request| - MergeRequests::MergeService.new.execute(merge_request, @current_user, nil) + MergeRequests::MergeService. + new(merge_request.target_project, @current_user). + execute(merge_request, nil) end end diff --git a/app/views/dashboard/_projects_filter.html.haml b/app/views/dashboard/_projects_filter.html.haml index b65e882e693..0e990ccfab4 100644 --- a/app/views/dashboard/_projects_filter.html.haml +++ b/app/views/dashboard/_projects_filter.html.haml @@ -1,55 +1,100 @@ -%fieldset - %ul.nav.nav-pills.nav-stacked - = nav_tab :scope, nil do - = link_to projects_dashboard_filter_path(scope: nil) do - All - %span.pull-right - = current_user.authorized_projects.count - = nav_tab :scope, 'personal' do - = link_to projects_dashboard_filter_path(scope: 'personal') do - Personal - %span.pull-right - = current_user.personal_projects.count - = nav_tab :scope, 'joined' do - = link_to projects_dashboard_filter_path(scope: 'joined') do - Joined - %span.pull-right - = current_user.authorized_projects.joined(current_user).count - = nav_tab :scope, 'owned' do - = link_to projects_dashboard_filter_path(scope: 'owned') do - Owned - %span.pull-right - = current_user.owned_projects.count +.dash-projects-filters.append-bottom-20 + .pull-left.append-right-20 + %ul.nav.nav-pills.nav-compact + = nav_tab :scope, nil do + = link_to projects_dashboard_filter_path(scope: nil) do + All + = nav_tab :scope, 'personal' do + = link_to projects_dashboard_filter_path(scope: 'personal') do + Personal + = nav_tab :scope, 'joined' do + = link_to projects_dashboard_filter_path(scope: 'joined') do + Joined + = nav_tab :scope, 'owned' do + = link_to projects_dashboard_filter_path(scope: 'owned') do + Owned -%fieldset - %legend Visibility - %ul.nav.nav-pills.nav-stacked.nav-small.visibility-filter - - Gitlab::VisibilityLevel.values.each do |level| - %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(visibility_level: level) do - = visibility_level_icon(level) - = visibility_level_label(level) + .dropdown.inline.append-right-10 + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %i.fa.fa-globe + %span.light Visibility: + - if params[:visibility_level].present? + = visibility_level_label(params[:visibility_level].to_i) + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to projects_dashboard_filter_path(visibility_level: nil) do + Any + - Gitlab::VisibilityLevel.values.each do |level| + %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(visibility_level: level) do + = visibility_level_icon(level) + = visibility_level_label(level) -- if @groups.present? - %fieldset - %legend Groups - %ul.nav.nav-pills.nav-stacked.nav-small - - @groups.each do |group| - %li{ class: (group.name == params[:group]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(group: group.name) do - %i.fa.fa-folder-o - = group.name - %small.pull-right - = group.projects.count + - if @groups.present? + .dropdown.inline.append-right-10 + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %i.fa.fa-group + %span.light Group: + - if params[:group].present? + = Group.find_by(name: params[:group]).name + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to projects_dashboard_filter_path(group: nil) do + Any + - @groups.each do |group| + %li{ class: (group.name == params[:group]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(group: group.name) do + = group.name + %small.pull-right + = group.projects.count -- if @tags.present? - %fieldset - %legend Tags - %ul.nav.nav-pills.nav-stacked.nav-small - - @tags.each do |tag| - %li{ class: (tag.name == params[:tag]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(scope: params[:scope], tag: tag.name) do - %i.fa.fa-tag - = tag.name + - if @tags.present? + .dropdown.inline.append-right-10 + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %i.fa.fa-tags + %span.light Tags: + - if params[:tag].present? + = params[:tag] + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to projects_dashboard_filter_path(tag: nil) do + Any + + - @tags.each do |tag| + %li{ class: (tag.name == params[:tag]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(tag: tag.name) do + %i.fa.fa-tag + = tag.name + + .pull-right + .dropdown.inline + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} + %span.light sort: + - if @sort.present? + = @sort.humanize + - else + Name + %b.caret + %ul.dropdown-menu + %li + = link_to projects_dashboard_filter_path(sort: nil) do + Name + = link_to projects_dashboard_filter_path(sort: 'newest') do + = sort_title_recently_created + = link_to projects_dashboard_filter_path(sort: 'oldest') do + = sort_title_oldest_created + = link_to projects_dashboard_filter_path(sort: 'recently_updated') do + = sort_title_recently_updated + = link_to projects_dashboard_filter_path(sort: 'last_updated') do + = sort_title_oldest_updated diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml index 5d133cd8285..f78ce69ef9e 100644 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/_zero_authorized_projects.html.haml @@ -4,7 +4,7 @@ %div .dashboard-intro-icon %i.fa.fa-bookmark-o - %div + .dashboard-intro-text %p.slead You don't have access to any projects right now. %br @@ -24,7 +24,7 @@ %div .dashboard-intro-icon %i.fa.fa-users - %div + .dashboard-intro-text %p.slead You can create a group for several dependent projects. %br @@ -38,7 +38,7 @@ %div .dashboard-intro-icon %i.fa.fa-globe - %div + .dashboard-intro-text %p.slead There are %strong= @publicish_project_count diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder index 66381310221..72e9e361dc3 100644 --- a/app/views/dashboard/issues.atom.builder +++ b/app/views/dashboard/issues.atom.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "#{current_user.name} issues" xml.link href: issues_dashboard_url(:atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml" xml.link href: issues_dashboard_url(private_token: current_user.private_token), rel: "alternate", type: "text/html" diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml index b880acf1245..944441669e7 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -1,76 +1,54 @@ %h3.page-title My Projects -.pull-right - .dropdown.inline - %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} - %span.light sort: - - if @sort.present? - = @sort.humanize - - else - Name - %b.caret - %ul.dropdown-menu - %li - = link_to projects_dashboard_filter_path(sort: nil) do - Name - = link_to projects_dashboard_filter_path(sort: 'newest') do - = sort_title_recently_created - = link_to projects_dashboard_filter_path(sort: 'oldest') do - = sort_title_oldest_created - = link_to projects_dashboard_filter_path(sort: 'recently_updated') do - = sort_title_recently_updated - = link_to projects_dashboard_filter_path(sort: 'last_updated') do - = sort_title_oldest_updated %p.light All projects you have access to are listed here. Public projects are not included here unless you are a member %hr -.row - .col-md-3.hidden-sm.hidden-xs.side-filters - = render "projects_filter" - .col-md-9 - %ul.bordered-list.my-projects.top-list - - @projects.each do |project| - %li.my-project-row - %h4.project-title - .project-access-icon - = visibility_level_icon(project.visibility_level) - = link_to project_path(project), class: dom_class(project) do - = project.name_with_namespace +.side-filters + = render "projects_filter" +.dash-projects + %ul.bordered-list.my-projects.top-list + - @projects.each do |project| + %li.my-project-row + %h4.project-title + .project-access-icon + = visibility_level_icon(project.visibility_level) + = link_to project_path(project), class: dom_class(project) do + = project.name_with_namespace - - if project.forked_from_project -   - %small - %i.fa.fa-code-fork - Forked from: - = link_to project.forked_from_project.name_with_namespace, project_path(project.forked_from_project) + - if project.forked_from_project +   + %small + %i.fa.fa-code-fork + Forked from: + = link_to project.forked_from_project.name_with_namespace, project_path(project.forked_from_project) - - if current_user.can_leave_project?(project) - .pull-right - = link_to leave_project_team_members_path(project), data: { confirm: "Leave project?"}, method: :delete, remote: true, class: "btn-tiny btn remove-row", title: 'Leave project' do - %i.fa.fa-sign-out - Leave - - .project-info + - if current_user.can_leave_project?(project) .pull-right - - if project.archived? - %span.label - %i.fa.fa-archive - Archived - - project.tags.each do |tag| - %span.label.label-info - %i.fa.fa-tag - = tag.name - - if project.description.present? - %p= truncate project.description, length: 100 - .last-activity - %span.light Last activity: - %span.date= project_last_activity(project) + = link_to leave_project_team_members_path(project), data: { confirm: "Leave project?"}, method: :delete, remote: true, class: "btn-tiny btn remove-row", title: 'Leave project' do + %i.fa.fa-sign-out + Leave + + .project-info + .pull-right + - if project.archived? + %span.label + %i.fa.fa-archive + Archived + - project.tags.each do |tag| + %span.label.label-info + %i.fa.fa-tag + = tag.name + - if project.description.present? + %p= truncate project.description, length: 100 + .last-activity + %span.light Last activity: + %span.date= project_last_activity(project) - - if @projects.blank? - %li - .nothing-here-block There are no projects here. - .bottom - = paginate @projects, theme: "gitlab" + - if @projects.blank? + %li + .nothing-here-block There are no projects here. + .bottom + = paginate @projects, theme: "gitlab" diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/show.atom.builder index 70ac66f8016..da631ecb33e 100644 --- a/app/views/dashboard/show.atom.builder +++ b/app/views/dashboard/show.atom.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "Dashboard feed#{" - #{current_user.name}" if current_user.name.present?}" xml.link href: dashboard_url(:atom), rel: "self", type: "application/atom+xml" xml.link href: dashboard_url, rel: "alternate", type: "text/html" diff --git a/app/views/groups/_filter.html.haml b/app/views/groups/_filter.html.haml deleted file mode 100644 index 393be3f1d12..00000000000 --- a/app/views/groups/_filter.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= form_tag group_filter_path(entity), method: 'get' do - %fieldset - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if (params[:status] == 'active' || !params[:status]))} - = link_to group_filter_path(entity, status: 'active') do - Active - %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 diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index 2727525f070..7f0b2832cac 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -9,42 +9,38 @@ %hr -.row - .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.fa.fa-list.fa-2x - .col-md-3.responsive-side - = render 'groups/filter', entity: 'milestone' - .col-md-9 - .panel.panel-default - %ul.well-list - - if @group_milestones.blank? - %li - .nothing-here-block No milestones to show - - else - - @group_milestones.each do |milestone| - %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - .pull-right - - if can?(current_user, :manage_group, @group) - - if milestone.closed? - = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped btn-reopen" - - else - = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-close" - %h4 - = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) += render 'shared/milestones_filter' +.milestones + .panel.panel-default + %ul.well-list + - if @group_milestones.blank? + %li + .nothing-here-block No milestones to show + - else + - @group_milestones.each do |milestone| + %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } + .pull-right + - if can?(current_user, :manage_group, @group) + - if milestone.closed? + = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped btn-reopen" + - else + = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-close" + %h4 + = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) + %div %div - %div - = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do - = pluralize milestone.issue_count, 'Issue' -   - = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do - = pluralize milestone.merge_requests_count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete - .progress.progress-info - .progress-bar{style: "width: #{milestone.percent_complete}%;"} - %div - %br - - milestone.projects.each do |project| - %span.label.label-default - = project.name - = paginate @group_milestones, theme: "gitlab" + = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do + = pluralize milestone.issue_count, 'Issue' +   + = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do + = pluralize milestone.merge_requests_count, 'Merge Request' +   + %span.light #{milestone.percent_complete}% complete + .progress.progress-info + .progress-bar{style: "width: #{milestone.percent_complete}%;"} + %div + %br + - milestone.projects.each do |project| + %span.label.label-default + = project.name + = paginate @group_milestones, theme: "gitlab" diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder index e765ea8338d..c78bd1bd263 100644 --- a/app/views/groups/show.atom.builder +++ b/app/views/groups/show.atom.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "Group feed - #{@group.name}" xml.link href: group_path(@group, :atom), rel: "self", type: "application/atom+xml" xml.link href: group_path(@group), rel: "alternate", type: "text/html" diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml index b02f52a5aff..9e2e214b3e8 100644 --- a/app/views/projects/_issuable_form.html.haml +++ b/app/views/projects/_issuable_form.html.haml @@ -52,10 +52,11 @@ - else %span.light No open milestones available.   - = link_to 'Create new milestone', new_project_milestone_path(issuable.project), target: :blank + - if can? current_user, :admin_milestone, issuable.project + = link_to 'Create new milestone', new_project_milestone_path(issuable.project), target: :blank .form-group = f.label :label_ids, class: 'control-label' do - %i.icon-tag + %i.fa.fa-tag Labels .col-sm-10 - if issuable.project.labels.any? @@ -64,9 +65,15 @@ - else %span.light No labels yet.   - = link_to 'Create new label', new_project_label_path(issuable.project), target: :blank + - if can? current_user, :admin_label, issuable.project + = link_to 'Create new label', new_project_label_path(issuable.project), target: :blank .form-actions + - if !issuable.project.empty_repo? && contribution_guide_url(issuable.project) && !issuable.persisted? + %p + Please review the + %strong #{link_to 'guidelines for contribution', contribution_guide_url(issuable.project)} + to this repository. - if issuable.new_record? = f.submit "Submit new #{issuable.class.model_name.human.downcase}", class: 'btn btn-create' - else diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index d57659065a8..f279e3c37cd 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -7,5 +7,5 @@ %p= pluralize(commits.count, 'commit') .col-md-10 %ul.bordered-list - = render commits, project: @project + = render commits, project: project %hr.lists-separator diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 56956625e0b..b80639763c8 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -13,7 +13,7 @@ = commits_breadcrumbs %div{id: dom_id(@project)} - #commits-list= render "commits" + #commits-list= render "commits", project: @project .clear = spinner diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 23e7691b32e..0c5f2ad1f3a 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -4,7 +4,7 @@ .diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }} .diff-header{id: "file-path-#{hexdigest(diff_file.new_path || diff_file.old_path)}"} - if diff_file.deleted_file - %span= diff_file.old_path + %span="#{diff_file.old_path} deleted" .diff-btn-group - if @commit.parent_ids.present? diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml index 64a28d8da49..2a7b44955cd 100644 --- a/app/views/projects/issues/_form.html.haml +++ b/app/views/projects/issues/_form.html.haml @@ -1,12 +1,6 @@ %div.issue-form-holder %h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}" %hr - - if @repository.exists? && !@repository.empty? && @repository.contribution_guide && !@issue.persisted? - - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) - .row - .col-sm-10.col-sm-offset-2 - .alert.alert-info - = "Please review the #{link_to "guidelines for contribution", contribution_guide_url} to this repository.".html_safe = form_for [@project, @issue], html: { class: 'form-horizontal issue-form gfm-form' } do |f| = render 'projects/issuable_form', f: f, issuable: @issue diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 76813e688b5..ac374532ffd 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -9,74 +9,103 @@ %span.pull-right = link_to 'Change branches', new_project_merge_request_path(@project) -= form_for [@project, @merge_request], html: { class: "merge-request-form gfm-form" } do |f| - .panel.panel-default - - .panel-body - .form-group - .light - = f.label :title do - Title * - = f.text_field :title, class: "form-control input-lg js-gfm-input", maxlength: 255, rows: 5, required: true - .form-group - .light - = f.label :description, "Description" += form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal gfm-form" } do |f| + .merge-request-form-info + .form-group + = f.label :title, class: 'control-label' do + %strong Title * + .col-sm-10 + = f.text_field :title, maxlength: 255, autofocus: true, class: 'form-control pad js-gfm-input', required: true + .form-group.issuable-description + = f.label :description, 'Description', class: 'control-label' + .col-sm-10 = render layout: 'projects/md_preview' do - = render 'projects/zen', f: f, attr: :description, - classes: 'description form-control' - .clearfix.hint - .pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}. - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. - .error-alert - .form-group - .issue-assignee - = f.label :assignee_id do - %i.fa.fa-user - Assign to - %div - = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id, project_id: @merge_request.target_project_id) -   - = link_to 'Assign to me', '#', class: 'btn assign-to-me-link' - .form-group - .issue-milestone - = f.label :milestone_id do - %i.fa.fa-clock-o - Milestone - %div= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'}) - .form-group - = f.label :label_ids do - %i.fa.fa-tag - Labels - %div - = f.collection_select :label_ids, @merge_request.target_project.labels.all, :id, :name, { selected: @merge_request.label_ids }, multiple: true, class: 'select2' + = render 'projects/zen', f: f, attr: :description, classes: 'description form-control' - .panel-footer + .col-sm-12-hint + .pull-left + Parsed with + #{link_to 'Gitlab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}. + .pull-right + Attach images (JPG, PNG, GIF) by dragging & dropping + or #{link_to 'selecting them', '#', class: 'markdown-selector'}. + + .clearfix + .error-alert + %hr + .form-group + .issue-assignee + = f.label :assignee_id, class: 'control-label' do + %i.fa.fa-user + Assign to + .col-sm-10 + = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id, project_id: @merge_request.target_project_id) +   + = link_to 'Assign to me', '#', class: 'btn assign-to-me-link' + .form-group + .issue-milestone + = f.label :milestone_id, class: 'control-label' do + %i.fa.fa-clock-o + Milestone + .col-sm-10 + - if milestone_options(@merge_request).present? + = f.select(:milestone_id, milestone_options(@merge_request), {include_blank: 'Select milestone'}, {class: 'select2'}) + - else + %span.light No open milestones available. +   + - if can? current_user, :admin_milestone, @merge_request.target_project + = link_to 'Create new milestone', new_project_milestone_path(@merge_request.target_project), target: :blank + .form-group + = f.label :label_ids, class: 'control-label' do + %i.fa.fa-tag + Labels + .col-sm-10 + - if @merge_request.target_project.labels.any? + = f.collection_select :label_ids, @merge_request.target_project.labels.all, :id, :name, {selected: @merge_request.label_ids}, multiple: true, class: 'select2' + - else + %span.light No labels yet. +   + - if can? current_user, :admin_label, @merge_request.target_project + = link_to 'Create new label', new_project_label_path(@merge_request.target_project), target: :blank + + .form-actions - if contribution_guide_url(@target_project) %p Please review the - %strong #{link_to "guidelines for contribution", contribution_guide_url(@target_project)} + %strong #{link_to 'guidelines for contribution', contribution_guide_url(@target_project)} to this repository. = f.hidden_field :source_project_id + = f.hidden_field :source_branch = f.hidden_field :target_project_id = f.hidden_field :target_branch - = f.hidden_field :source_branch - = f.submit 'Submit merge request', class: "btn btn-create" + = f.submit 'Submit merge request', class: 'btn btn-create' -.mr-compare - = render "projects/commits/commit_list" - - %h4 Changes - - if @diffs.present? - = render "projects/diffs/diffs", diffs: @diffs, project: @project - - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - .bs-callout.bs-callout-danger - %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. - %p To preserve performance the line changes are not shown. - - else - .bs-callout.bs-callout-danger - %h4 This comparison includes huge diff. - %p To preserve performance the line changes are not shown. +.mr-compare.merge-request + %ul.nav.nav-tabs.merge-request-tabs + %li.commits-tab{data: {action: 'commits'}} + = link_to url_for(params) do + %i.fa.fa-history + Commits + %span.badge= @commits.size + %li.diffs-tab{data: {action: 'diffs'}} + = link_to url_for(params) do + %i.fa.fa-list-alt + Changes + %span.badge= @diffs.size + .commits.tab-content + = render "projects/commits/commits", project: @project + .diffs.tab-content + - if @diffs.present? + = render "projects/diffs/diffs", diffs: @diffs, project: @project + - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE + .bs-callout.bs-callout-danger + %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. + %p To preserve performance the line changes are not shown. + - else + .bs-callout.bs-callout-danger + %h4 This comparison includes a huge diff. + %p To preserve performance the line changes are not shown. :javascript $('.assign-to-me-link').on('click', function(e){ @@ -85,3 +114,9 @@ }); window.project_image_path_upload = "#{upload_image_project_path @project}"; + +:javascript + var merge_request + merge_request = new MergeRequest({ + action: 'commits' + }); diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 74ef819a7aa..f8d2673335a 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -42,7 +42,7 @@ %span.badge= @merge_request.mr_and_commit_notes.count %li.commits-tab{data: {action: 'commits'}} = link_to project_merge_request_path(@project, @merge_request), title: 'Commits' do - %i.fa.fa-database + %i.fa.fa-history Commits %span.badge= @commits.size %li.diffs-tab{data: {action: 'diffs'}} diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml index a6587403871..3b7f283daf0 100644 --- a/app/views/projects/merge_requests/show/_commits.html.haml +++ b/app/views/projects/merge_requests/show/_commits.html.haml @@ -1,30 +1 @@ -- if @commits.present? - .panel.panel-default - .panel-heading - %i.fa.fa-list - Commits (#{@commits.count}) - .commits.mr-commits - - if @commits.count > 8 - %ul.first-commits.well-list - - @commits.first(8).each do |commit| - = render "projects/commits/commit", commit: commit, project: @merge_request.source_project - %li.bottom - 8 of #{@commits.count} commits displayed. - %strong - %a.show-all-commits Click here to show all - - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - %ul.all-commits.hide.well-list - - @commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE).each do |commit| - = render "projects/commits/inline_commit", commit: commit, project: @merge_request.source_project - %li - other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues. - - else - %ul.all-commits.hide.well-list - - @commits.each do |commit| - = render "projects/commits/inline_commit", commit: commit, project: @merge_request.source_project - - - else - %ul.well-list - - @commits.each do |commit| - = render "projects/commits/commit", commit: commit, project: @merge_request.source_project - += render "projects/commits/commits", project: @merge_request.source_project diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 4939ae03994..dd5f29e5389 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -13,25 +13,22 @@ .automerge_widget.can_be_merged.hide .clearfix = form_for [:automerge, @project, @merge_request], remote: true, method: :post do |f| - %h4 - You can accept this request automatically. - .accept-merge-holder.clearfix - .accept-group - .pull-left - = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" - - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? - .remove_branch_holder.pull-left - = label_tag :should_remove_source_branch, class: "checkbox" do - = check_box_tag :should_remove_source_branch - Remove source-branch - .js-toggle-container - %label - %i.fa.fa-edit - = link_to "modify merge commit message", "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" - .js-toggle-content.hide - = render 'shared/commit_message_container', params: params, - text: @merge_request.merge_commit_message, - rows: 14, hint: true + .accept-merge-holder.clearfix.js-toggle-container + .accept-action + = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" + - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? + .accept-control + = label_tag :should_remove_source_branch, class: "checkbox" do + = check_box_tag :should_remove_source_branch + Remove source-branch + .accept-control + = link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do + %i.fa.fa-edit + Modify commit message + .js-toggle-content.hide.prepend-top-20 + = render 'shared/commit_message_container', params: params, + text: @merge_request.merge_commit_message, + rows: 14, hint: true %hr .light diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index 0db0b114d63..04a1b9243d5 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -7,27 +7,15 @@ %i.fa.fa-plus New Milestone - .row - .fixed.sidebar-expand-button.hidden-lg.hidden-md.hidden-xs - %i.fa.fa-list.fa-2x - .col-md-3.responsive-side - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if (params[:f] == "active" || !params[:f]))} - = link_to project_milestones_path(@project, f: "active") do - Active - %li{class: ("active" if params[:f] == "closed")} - = link_to project_milestones_path(@project, f: "closed") do - Closed - %li{class: ("active" if params[:f] == "all")} - = link_to project_milestones_path(@project, f: "all") do - All - .col-md-9 - .panel.panel-default - %ul.well-list - = render @milestones += render 'shared/milestones_filter' - - if @milestones.blank? - %li - .nothing-here-block No milestones to show +.milestones + .panel.panel-default + %ul.well-list + = render @milestones - = paginate @milestones, theme: "gitlab" + - if @milestones.blank? + %li + .nothing-here-block No milestones to show + + = paginate @milestones, theme: "gitlab" diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index f37c086716d..111484c8316 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -19,13 +19,15 @@ %code [Link Title](page-slug) \. - .form-group + .form-group.wiki-content = f.label :content, class: 'control-label' .col-sm-10 - = render 'projects/zen', f: f, attr: :content, classes: 'description form-control' - .col-sm-12.hint - .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'} - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + = render layout: 'projects/md_preview' do + = render 'projects/zen', f: f, attr: :content, classes: 'description form-control' + .col-sm-12.hint + .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'} + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. + .clearfix .error-alert .form-group diff --git a/app/views/shared/_milestones_filter.html.haml b/app/views/shared/_milestones_filter.html.haml new file mode 100644 index 00000000000..8c2fd166922 --- /dev/null +++ b/app/views/shared/_milestones_filter.html.haml @@ -0,0 +1,16 @@ +.fixed.sidebar-expand-button.hidden-lg.hidden-md + %i.fa.fa-list.fa-2x +.responsive-side.milestones-filters.append-bottom-10 + %ul.nav.nav-pills.nav-compact + %li{class: ("active" if params[:state].blank? || params[:state] == 'opened')} + = link_to milestones_filter_path(state: 'opened') do + %i.fa.fa-exclamation-circle + Open + %li{class: ("active" if params[:state] == 'closed')} + = link_to milestones_filter_path(state: 'closed') do + %i.fa.fa-check-circle + Closed + %li{class: ("active" if params[:state] == 'all')} + = link_to milestones_filter_path(state: 'all') do + %i.fa.fa-compass + All diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder index b7216a88765..8fe30b23635 100644 --- a/app/views/users/show.atom.builder +++ b/app/views/users/show.atom.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlnsmedia" => "http://search.yahoo.com/mrss/" do +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "Activity feed for #{@user.name}" xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml" xml.link href: user_url(@user), rel: "alternate", type: "text/html" diff --git a/doc/operations/README.md b/doc/operations/README.md index 31b1b583b0c..f1456c6c8e2 100644 --- a/doc/operations/README.md +++ b/doc/operations/README.md @@ -1,3 +1,4 @@ # GitLab operations - [Sidekiq MemoryKiller](sidekiq_memory_killer.md) +- [Cleaning up Redis sessions](cleaning_up_redis_sessions.md) diff --git a/doc/operations/cleaning_up_redis_sessions.md b/doc/operations/cleaning_up_redis_sessions.md new file mode 100644 index 00000000000..93521e976d5 --- /dev/null +++ b/doc/operations/cleaning_up_redis_sessions.md @@ -0,0 +1,52 @@ +# Cleaning up stale Redis sessions + +Since version 6.2, GitLab stores web user sessions as key-value pairs in Redis. +Prior to GitLab 7.3, user sessions did not automatically expire from Redis. If +you have been running a large GitLab server (thousands of users) since before +GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis +database after you upgrade to GitLab 7.3. You can also perform a cleanup while +still running GitLab 7.2 or older, but in that case new stale sessions will +start building up again after you clean up. + +In GitLab versions prior to 7.3.0, the session keys in Redis are 16-byte +hexadecimal values such as '976aa289e2189b17d7ef525a6702ace9'. Starting with +GitLab 7.3.0, the keys are +prefixed with 'session:gitlab:', so they would look like +'session:gitlab:976aa289e2189b17d7ef525a6702ace9'. Below we describe how to +remove the keys in the old format. + +First we define a shell function with the proper Redis connection details. + +``` +rcli() { + # This example works for Omnibus installations of GitLab 7.3 or newer. For an + # installation from source you will have to change the socket path and the + # path to redis-cli. + sudo /opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket "$@" +} + +# test the new shell function; the response should be PONG +rcli ping +``` + +Now we do a search to see if there are any session keys in the old format for +us to clean up. + +``` +# returns the number of old-format session keys in Redis +rcli keys '*' | grep '^[a-f0-9]\{32\}$' | wc -l +``` + +If the number is larger than zero, you can proceed to expire the keys from +Redis. If the number is zero there is nothing to clean up. + +``` +# Tell Redis to expire each matched key after 600 seconds. +rcli keys '*' | grep '^[a-f0-9]\{32\}$' | awk '{ print "expire", $0, 600 }' | rcli +# This will print '(integer) 1' for each key that gets expired. +``` + +Over the next 15 minutes (10 minutes expiry time plus 5 minutes Redis +background save interval) your Redis database will be compacted. If you are +still using GitLab 7.2, users who are not clicking around in GitLab during the +10 minute expiry window will be signed out of GitLab. diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index d70cbb28074..c9928e11b2e 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -49,4 +49,4 @@ If a user is a GitLab administrator they receive all permissions. | Manage group members | | | | | ✓ | | Remove group | | | | | ✓ | -Any user can remove himself from a group, unless he is the last Owner of the group. +Any user can remove themselves from a group, unless they are the last Owner of the group. diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index b7d70881d56..6ea64f70092 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -50,6 +50,16 @@ Feature: Project Source Browse Files And I click button "Edit" Then I can edit code + Scenario: If the file is binary the edit link is hidden + Given I visit a binary file in the repo + Then I cannot see the edit button + + Scenario: If I don't have edit permission the edit link is disabled + Given public project "Community" + And I visit project "Community" source page + And I click on ".gitignore" file in repo + Then The edit button is disabled + @javascript Scenario: I can edit and commit file Given I click on ".gitignore" file in repo diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index bd84abae06e..84f1ebc003b 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -113,7 +113,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps click_link 'Commits' end - within '.mr-commits' do + within '.commits' do click_link Commit.truncate_sha(sample_commit.id) end end @@ -156,7 +156,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'merge request is mergeable' do - page.should have_content 'You can accept this request automatically' + page.should have_button 'Accept Merge Request' end step 'I modify merge commit message' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index ddd501d4f88..805e6ff0eac 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -48,6 +48,14 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps click_link 'Edit' end + step 'I cannot see the edit button' do + page.should_not have_link 'edit' + end + + step 'The edit button is disabled' do + page.should have_css '.disabled', text: 'Edit' + end + step 'I can edit code' do set_new_content evaluate_script('editor.getValue()').should == new_gitignore_content diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index b60d290ae9c..e657fceb704 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -183,6 +183,11 @@ module SharedPaths visit project_tree_path(@project, root_ref) end + step 'I visit a binary file in the repo' do + visit project_blob_path(@project, File.join( + root_ref, 'files/images/logo-black.png')) + end + step "I visit my project's commits page" do visit project_commits_path(@project, root_ref, {limit: 5}) end @@ -385,6 +390,11 @@ module SharedPaths visit project_path(project) end + step 'I visit project "Community" source page' do + project = Project.find_by(name: 'Community') + visit project_tree_path(project, root_ref) + end + step 'I visit project "Internal" page' do project = Project.find_by(name: "Internal") visit project_path(project) diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index 746b6fc1ac9..de4f94fff2f 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -24,11 +24,12 @@ describe "User Feed", feature: true do end it "should have issue opened event" do - body.should have_content("#{user.name} opened issue ##{issue.iid}") + expect(body).to have_content("#{safe_name} opened issue ##{issue.iid}") end it "should have issue comment event" do - body.should have_content("#{user.name} commented on issue ##{issue.iid}") + expect(body). + to have_content("#{safe_name} commented on issue ##{issue.iid}") end end end @@ -40,4 +41,8 @@ describe "User Feed", feature: true do def note_event(note, user) EventCreateService.new.leave_note(note, user) end + + def safe_name + html_escape(user.name) + end end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index 9f294152053..35c7aac94df 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -47,10 +47,10 @@ describe MergeRequests::RefreshService do reload_mrs end - it { @merge_request.notes.should be_empty } + it { @merge_request.notes.last.note.should include('changed to merged') } it { @merge_request.should be_merged } it { @fork_merge_request.should be_merged } - it { @fork_merge_request.notes.should be_empty } + it { @fork_merge_request.notes.last.note.should include('changed to merged') } end context 'push to fork repo source branch' do @@ -61,7 +61,7 @@ describe MergeRequests::RefreshService do it { @merge_request.notes.should be_empty } it { @merge_request.should be_open } - it { @fork_merge_request.notes.should_not be_empty } + it { @fork_merge_request.notes.last.note.should include('new commit') } it { @fork_merge_request.should be_open } end @@ -84,7 +84,7 @@ describe MergeRequests::RefreshService do reload_mrs end - it { @merge_request.notes.should be_empty } + it { @merge_request.notes.last.note.should include('changed to merged') } it { @merge_request.should be_merged } it { @fork_merge_request.should be_open } it { @fork_merge_request.notes.should be_empty }