Commit 503d8542 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-02-27

parents 64270139 81852d1f
...@@ -200,17 +200,9 @@ ...@@ -200,17 +200,9 @@
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
font-size: 0; font-size: 0;
div {
display: inline;
}
.fa-spinner { .fa-spinner {
font-size: 12px; font-size: 12px;
} }
span {
font-size: 6px;
}
} }
.ci-status-link { .ci-status-link {
......
...@@ -19,10 +19,6 @@ class Groups::ApplicationController < ApplicationController ...@@ -19,10 +19,6 @@ class Groups::ApplicationController < ApplicationController
@projects ||= GroupProjectsFinder.new(group: group, current_user: current_user).execute @projects ||= GroupProjectsFinder.new(group: group, current_user: current_user).execute
end end
def group_merge_requests
@group_merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id).execute
end
def authorize_admin_group! def authorize_admin_group!
unless can?(current_user, :admin_group, group) unless can?(current_user, :admin_group, group)
return render_404 return render_404
......
...@@ -15,7 +15,6 @@ class GroupsController < Groups::ApplicationController ...@@ -15,7 +15,6 @@ class GroupsController < Groups::ApplicationController
before_action :authorize_create_group!, only: [:new] before_action :authorize_create_group!, only: [:new]
before_action :group_projects, only: [:projects, :activity, :issues, :merge_requests] before_action :group_projects, only: [:projects, :activity, :issues, :merge_requests]
before_action :group_merge_requests, only: [:merge_requests]
before_action :event_filter, only: [:activity] before_action :event_filter, only: [:activity]
before_action :user_actions, only: [:show, :subgroups] before_action :user_actions, only: [:show, :subgroups]
......
...@@ -21,6 +21,20 @@ module GroupsHelper ...@@ -21,6 +21,20 @@ module GroupsHelper
can?(current_user, :change_share_with_group_lock, group) can?(current_user, :change_share_with_group_lock, group)
end end
def group_issues_count(state:)
IssuesFinder
.new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
.execute
.count
end
def group_merge_requests_count(state:)
MergeRequestsFinder
.new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
.execute
.count
end
def group_icon(group, options = {}) def group_icon(group, options = {})
img_path = group_icon_url(group, options) img_path = group_icon_url(group, options)
image_tag img_path, options image_tag img_path, options
...@@ -85,10 +99,6 @@ module GroupsHelper ...@@ -85,10 +99,6 @@ module GroupsHelper
end end
end end
def group_issues(group)
IssuesFinder.new(current_user, group_id: group.id).execute
end
def remove_group_message(group) def remove_group_message(group)
_("You are going to remove %{group_name}. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?") % _("You are going to remove %{group_name}. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?") %
{ group_name: group.name } { group_name: group.name }
......
...@@ -6,7 +6,10 @@ module Ci ...@@ -6,7 +6,10 @@ module Ci
belongs_to :group belongs_to :group
validates :key, uniqueness: { scope: :group_id } validates :key, uniqueness: {
scope: :group_id,
message: "(%{value}) has already been taken"
}
scope :unprotected, -> { where(protected: false) } scope :unprotected, -> { where(protected: false) }
end end
......
...@@ -7,7 +7,10 @@ module Ci ...@@ -7,7 +7,10 @@ module Ci
belongs_to :project belongs_to :project
validates :key, uniqueness: { scope: [:project_id, :environment_scope] } validates :key, uniqueness: {
scope: [:project_id, :environment_scope],
message: "(%{value}) has already been taken"
}
scope :unprotected, -> { where(protected: false) } scope :unprotected, -> { where(protected: false) }
end end
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
# - Use `validates :xxx, uniqueness: { scope: :xxx_id }` in a child model # - Use `validates :xxx, uniqueness: { scope: :xxx_id }` in a child model
class VariableDuplicatesValidator < ActiveModel::EachValidator class VariableDuplicatesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
return if record.errors.include?(:"#{attribute}.key")
if options[:scope] if options[:scope]
scoped = value.group_by do |variable| scoped = value.group_by do |variable|
Array(options[:scope]).map { |attr| variable.send(attr) } # rubocop:disable GitlabSecurity/PublicSend Array(options[:scope]).map { |attr| variable.send(attr) } # rubocop:disable GitlabSecurity/PublicSend
......
- page_title "Issues" - page_title "Issues"
- group_issues_exists = group_issues(@group).exists?
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues") = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues")
...@@ -7,7 +6,9 @@ ...@@ -7,7 +6,9 @@
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'issues' = webpack_bundle_tag 'issues'
- if group_issues_exists - if group_issues_count(state: 'all').zero?
= render 'shared/empty_states/issues', project_select_button: true
- else
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls .nav-controls
...@@ -20,5 +21,3 @@ ...@@ -20,5 +21,3 @@
= render 'shared/issuable/search_bar', type: :issues = render 'shared/issuable/search_bar', type: :issues
= render 'shared/issues' = render 'shared/issues'
- else
= render 'shared/empty_states/issues', project_select_button: true
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
- if @group_merge_requests.empty? - if group_merge_requests_count(state: 'all').zero?
= render 'shared/empty_states/merge_requests', project_select_button: true = render 'shared/empty_states/merge_requests', project_select_button: true
- else - else
.top-area .top-area
......
- issues_count = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute.count - issues_count = group_issues_count(state: 'opened')
- merge_requests_count = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute.count - merge_requests_count = group_merge_requests_count(state: 'opened')
- issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index'] - issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index']
- if @group.feature_available?(:group_issue_boards) - if @group.feature_available?(:group_issue_boards)
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
.avatar-cell.hidden-xs .avatar-cell.hidden-xs
= author_avatar(commit, size: 36) = author_avatar(commit, size: 36)
.commit-detail .commit-detail.flex-list
.commit-content .commit-content
= link_to_markdown_field(commit, :title, link, class: "commit-row-message item-title") = link_to_markdown_field(commit, :title, link, class: "commit-row-message item-title")
%span.commit-row-message.visible-xs-inline %span.commit-row-message.visible-xs-inline
......
---
title: Allow Prometheus application to be installed from Cluster applications
merge_request: 17372
author:
type: fixed
---
title: Remove duplicated error message on duplicate variable validation
merge_request: 17135
author:
type: fixed
---
title: Fixes gpg popover layout
merge_request: 17323
author:
type: fixed
---
title: Ensure group issues and merge requests pages show results from subgroups when
there are no results from the current group
merge_request: 17312
author:
type: fixed
require 'spec_helper' require 'spec_helper'
feature 'Groups Merge Requests Empty States' do feature 'Group empty states' do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user } let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
...@@ -8,62 +8,100 @@ feature 'Groups Merge Requests Empty States' do ...@@ -8,62 +8,100 @@ feature 'Groups Merge Requests Empty States' do
sign_in(user) sign_in(user)
end end
context 'group has a project' do [:issue, :merge_request].each do |issuable|
let(:project) { create(:project, namespace: group) } issuable_name = issuable.to_s.humanize.downcase
project_relation = issuable == :issue ? :project : :source_project
before do context "for #{issuable_name}s" do
project.add_master(user) let(:path) { public_send(:"#{issuable}s_group_path", group) }
end
context 'the project has a merge request' do context 'group has a project' do
before do let(:project) { create(:project, namespace: group) }
create(:merge_request, source_project: project)
visit merge_requests_group_path(group) before do
end project.add_master(user)
end
it 'should not display an empty state' do context "the project has #{issuable_name}s" do
expect(page).not_to have_selector('.empty-state') before do
end create(issuable, project_relation => project)
end
context 'the project has no merge requests', :js do visit path
before do end
visit merge_requests_group_path(group)
end
it 'should display an empty state' do it 'does not display an empty state' do
expect(page).to have_selector('.empty-state') expect(page).not_to have_selector('.empty-state')
end end
end
context "the project has no #{issuable_name}s", :js do
before do
visit path
end
it 'displays an empty state' do
expect(page).to have_selector('.empty-state')
end
it "shows a new #{issuable_name} button" do
within '.empty-state' do
expect(page).to have_content("create #{issuable_name}")
end
end
it "the new #{issuable_name} button opens a project dropdown" do
within '.empty-state' do
find('.new-project-item-select-button').click
end
it 'should show a new merge request button' do expect(page).to have_selector('.ajax-project-dropdown')
within '.empty-state' do end
expect(page).to have_content('create merge request')
end end
end end
it 'the new merge request button opens a project dropdown' do context 'group without a project' do
within '.empty-state' do context 'group has a subgroup', :nested_groups do
find('.new-project-item-select-button').click let(:subgroup) { create(:group, parent: group) }
end let(:subgroup_project) { create(:project, namespace: subgroup) }
expect(page).to have_selector('.ajax-project-dropdown') context "the project has #{issuable_name}s" do
end before do
end create(issuable, project_relation => subgroup_project)
end
context 'group without a project' do visit path
before do end
visit merge_requests_group_path(group)
end
it 'should display an empty state' do it 'does not display an empty state' do
expect(page).to have_selector('.empty-state') expect(page).not_to have_selector('.empty-state')
end end
end
it 'should not show a new merge request button' do context "the project has no #{issuable_name}s" do
within '.empty-state' do before do
expect(page).not_to have_link('create merge request') visit path
end
it 'displays an empty state' do
expect(page).to have_selector('.empty-state')
end
end
end
context 'group has no subgroups' do
before do
visit path
end
it 'displays an empty state' do
expect(page).to have_selector('.empty-state')
end
it "shows a new #{issuable_name} button" do
within '.empty-state' do
expect(page).not_to have_link("create #{issuable_name}")
end
end
end
end end
end end
end end
......
...@@ -5,7 +5,7 @@ describe Ci::GroupVariable do ...@@ -5,7 +5,7 @@ describe Ci::GroupVariable do
it { is_expected.to include_module(HasVariable) } it { is_expected.to include_module(HasVariable) }
it { is_expected.to include_module(Presentable) } it { is_expected.to include_module(Presentable) }
it { is_expected.to validate_uniqueness_of(:key).scoped_to(:group_id) } it { is_expected.to validate_uniqueness_of(:key).scoped_to(:group_id).with_message(/\(\w+\) has already been taken/) }
describe '.unprotected' do describe '.unprotected' do
subject { described_class.unprotected } subject { described_class.unprotected }
......
...@@ -12,7 +12,7 @@ describe Ci::Variable do ...@@ -12,7 +12,7 @@ describe Ci::Variable do
it { is_expected.to include_module(HasEnvironmentScope) } it { is_expected.to include_module(HasEnvironmentScope) }
it { is_expected.to include_module(HasVariable) } it { is_expected.to include_module(HasVariable) }
it { is_expected.to include_module(Presentable) } it { is_expected.to include_module(Presentable) }
it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id, :environment_scope) } it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id, :environment_scope).with_message(/\(\w+\) has already been taken/) }
end end
describe '.unprotected' do describe '.unprotected' do
......
...@@ -261,6 +261,8 @@ shared_examples 'variable list' do ...@@ -261,6 +261,8 @@ shared_examples 'variable list' do
click_button('Save variables') click_button('Save variables')
wait_for_requests wait_for_requests
expect(all('.js-ci-variable-list-section .js-ci-variable-error-box ul li').count).to eq(1)
# We check the first row because it re-sorts to alphabetical order on refresh # We check the first row because it re-sorts to alphabetical order on refresh
page.within('.js-ci-variable-list-section') do page.within('.js-ci-variable-list-section') do
expect(find('.js-ci-variable-error-box')).to have_content(/Validation failed Variables have duplicate values \(.+\)/) expect(find('.js-ci-variable-error-box')).to have_content(/Validation failed Variables have duplicate values \(.+\)/)
......
...@@ -10,6 +10,9 @@ nodeExporter: ...@@ -10,6 +10,9 @@ nodeExporter:
pushgateway: pushgateway:
enabled: false enabled: false
rbac:
create: false
server: server:
image: image:
tag: v2.1.0 tag: v2.1.0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment