diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-25 12:09:40 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-25 12:09:40 +0300 |
commit | e6bcd6e73801e31e15ef0c9c1e6ad790626cdfaf (patch) | |
tree | f2ae9a09c10a8275c4df9c72a6a301aaf0d838e1 /app | |
parent | 654281e682c684c9d62778a71ab067b3679b4ee9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
24 files changed, 121 insertions, 91 deletions
diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.vue b/app/assets/javascripts/environments/folder/environments_folder_view.vue index 16d25615779..061c9ffe8d4 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_view.vue +++ b/app/assets/javascripts/environments/folder/environments_folder_view.vue @@ -1,4 +1,5 @@ <script> +import { GlBadge, GlTab, GlTabs } from '@gitlab/ui'; import environmentsMixin from '../mixins/environments_mixin'; import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin'; import StopEnvironmentModal from '../components/stop_environment_modal.vue'; @@ -6,8 +7,11 @@ import DeleteEnvironmentModal from '../components/delete_environment_modal.vue'; export default { components: { - StopEnvironmentModal, DeleteEnvironmentModal, + GlBadge, + GlTab, + GlTabs, + StopEnvironmentModal, }, mixins: [environmentsMixin, CIPaginationMixin], @@ -73,9 +77,21 @@ export default { <b>{{ folderName }}</b> </h4> - <div class="top-area"> - <tabs v-if="!isLoading" :tabs="tabs" scope="environments" @onChangeTab="onChangeTab" /> - </div> + <gl-tabs v-if="!isLoading" scope="environments" content-class="gl-display-none"> + <gl-tab + v-for="(tab, i) in tabs" + :key="`${tab.name}-${i}`" + :active="tab.isActive" + :title-item-class="tab.isActive ? 'gl-outline-none' : ''" + :title-link-attributes="{ 'data-testid': `environments-tab-${tab.scope}` }" + @click="onChangeTab(tab.scope)" + > + <template #title> + <span>{{ tab.name }}</span> + <gl-badge size="sm" class="gl-tab-counter-badge">{{ tab.count }}</gl-badge> + </template> + </gl-tab> + </gl-tabs> <container :is-loading="isLoading" diff --git a/app/assets/javascripts/jira_import/index.js b/app/assets/javascripts/jira_import/index.js index 695a237bf50..003f3c7107e 100644 --- a/app/assets/javascripts/jira_import/index.js +++ b/app/assets/javascripts/jira_import/index.js @@ -6,7 +6,7 @@ import App from './components/jira_import_app.vue'; Vue.use(VueApollo); -const defaultClient = createDefaultClient(); +const defaultClient = createDefaultClient({}, { assumeImmutableResults: true }); const apolloProvider = new VueApollo({ defaultClient, diff --git a/app/assets/javascripts/jira_import/queries/initiate_jira_import.mutation.graphql b/app/assets/javascripts/jira_import/queries/initiate_jira_import.mutation.graphql index 8fda8287988..807374bf06c 100644 --- a/app/assets/javascripts/jira_import/queries/initiate_jira_import.mutation.graphql +++ b/app/assets/javascripts/jira_import/queries/initiate_jira_import.mutation.graphql @@ -2,7 +2,6 @@ mutation($input: JiraImportStartInput!) { jiraImportStart(input: $input) { - clientMutationId jiraImport { ...JiraImport } diff --git a/app/assets/javascripts/jira_import/utils/cache_update.js b/app/assets/javascripts/jira_import/utils/cache_update.js index 6aaf2010866..01b851ca527 100644 --- a/app/assets/javascripts/jira_import/utils/cache_update.js +++ b/app/assets/javascripts/jira_import/utils/cache_update.js @@ -1,3 +1,4 @@ +import produce from 'immer'; import getJiraImportDetailsQuery from '../queries/get_jira_import_details.query.graphql'; import { IMPORT_STATE } from './jira_import_utils'; @@ -13,22 +14,16 @@ export const addInProgressImportToStore = (store, jiraImportStart, fullPath) => }, }; - const cacheData = store.readQuery({ + const sourceData = store.readQuery({ ...queryDetails, }); store.writeQuery({ ...queryDetails, - data: { - project: { - ...cacheData.project, - jiraImportStatus: IMPORT_STATE.SCHEDULED, - jiraImports: { - ...cacheData.project.jiraImports, - nodes: cacheData.project.jiraImports.nodes.concat(jiraImportStart.jiraImport), - }, - }, - }, + data: produce(sourceData, draftData => { + draftData.project.jiraImportStatus = IMPORT_STATE.SCHEDULED; // eslint-disable-line no-param-reassign + draftData.project.jiraImports.nodes.push(jiraImportStart.jiraImport); + }), }); }; diff --git a/app/assets/javascripts/pipelines/constants.js b/app/assets/javascripts/pipelines/constants.js index 701d36b71f2..d3acd1ef3d0 100644 --- a/app/assets/javascripts/pipelines/constants.js +++ b/app/assets/javascripts/pipelines/constants.js @@ -13,6 +13,8 @@ export const TestStatus = { FAILED: 'failed', SKIPPED: 'skipped', SUCCESS: 'success', + ERROR: 'error', + UNKNOWN: 'unknown', }; export const FETCH_AUTHOR_ERROR_MESSAGE = __('There was a problem fetching project users.'); diff --git a/app/assets/javascripts/pipelines/stores/test_reports/utils.js b/app/assets/javascripts/pipelines/stores/test_reports/utils.js index 8f1ac305cda..42406e5a67a 100644 --- a/app/assets/javascripts/pipelines/stores/test_reports/utils.js +++ b/app/assets/javascripts/pipelines/stores/test_reports/utils.js @@ -1,13 +1,19 @@ import { __, sprintf } from '../../../locale'; +import { TestStatus } from '../../constants'; export function iconForTestStatus(status) { switch (status) { - case 'success': + case TestStatus.SUCCESS: return 'status_success_borderless'; - case 'failed': + case TestStatus.FAILED: return 'status_failed_borderless'; - default: + case TestStatus.ERROR: + return 'status_warning_borderless'; + case TestStatus.SKIPPED: return 'status_skipped_borderless'; + case TestStatus.UNKNOWN: + default: + return 'status_notfound_borderless'; } } diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index cf21c23cb17..52319d9658b 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -203,18 +203,6 @@ margin-right: 0; } } - - &:hover, - &:focus { - text-decoration: none; - outline: 0; - opacity: 1; - color: $white; - - &.header-user-dropdown-toggle .header-user-avatar { - border-color: $white; - } - } } .header-new-dropdown-toggle { diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss index ec0755b1614..5623d38d66e 100644 --- a/app/assets/stylesheets/framework/icons.scss +++ b/app/assets/stylesheets/framework/icons.scss @@ -9,6 +9,7 @@ } } +.ci-status-icon-error, .ci-status-icon-failed { svg { fill: $red-500; diff --git a/app/controllers/concerns/show_inherited_labels_checker.rb b/app/controllers/concerns/show_inherited_labels_checker.rb new file mode 100644 index 00000000000..acbea37a62e --- /dev/null +++ b/app/controllers/concerns/show_inherited_labels_checker.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module ShowInheritedLabelsChecker + extend ActiveSupport::Concern + + private + + def show_inherited_labels?(include_ancestor_groups) + Feature.enabled?(:show_inherited_labels, @project || @group) || include_ancestor_groups # rubocop:disable Gitlab/ModuleWithInstanceVariables + end +end diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index df0b71d2cf0..97d9f8fcecd 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -2,6 +2,7 @@ class Groups::LabelsController < Groups::ApplicationController include ToggleSubscriptionAction + include ShowInheritedLabelsChecker before_action :label, only: [:edit, :update, :destroy] before_action :authorize_admin_labels!, only: [:new, :create, :edit, :update, :destroy] @@ -12,8 +13,9 @@ class Groups::LabelsController < Groups::ApplicationController def index respond_to do |format| format.html do - @labels = GroupLabelsFinder - .new(current_user, @group, params.merge(sort: sort)).execute + # at group level we do not want to list project labels, + # we only want `only_group_labels = false` when pulling labels for label filter dropdowns, fetched through json + @labels = available_labels(params.merge(only_group_labels: true)).page(params[:page]) end format.json do render json: LabelSerializer.new.represent_appearance(available_labels) @@ -74,7 +76,7 @@ class Groups::LabelsController < Groups::ApplicationController end def label - @label ||= @group.labels.find(params[:id]) + @label ||= available_labels(params.merge(only_group_labels: true)).find(params[:id]) end alias_method :subscribable_resource, :label @@ -102,15 +104,17 @@ class Groups::LabelsController < Groups::ApplicationController session[:previous_labels_path] = URI(request.referer || '').path end - def available_labels + def available_labels(options = params) @available_labels ||= LabelsFinder.new( current_user, group_id: @group.id, - only_group_labels: params[:only_group_labels], - include_ancestor_groups: params[:include_ancestor_groups], - include_descendant_groups: params[:include_descendant_groups], - search: params[:search]).execute + only_group_labels: options[:only_group_labels], + include_ancestor_groups: show_inherited_labels?(params[:include_ancestor_groups]), + sort: sort, + subscribed: options[:subscribed], + include_descendant_groups: options[:include_descendant_groups], + search: options[:search]).execute end def sort diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb index 9c47e6d4b0b..fdca6da95c5 100644 --- a/app/controllers/import/manifest_controller.rb +++ b/app/controllers/import/manifest_controller.rb @@ -26,8 +26,7 @@ class Import::ManifestController < Import::BaseController manifest = Gitlab::ManifestImport::Manifest.new(params[:manifest].tempfile) if manifest.valid? - session[:manifest_import_repositories] = manifest.projects - session[:manifest_import_group_id] = group.id + manifest_import_metadata.save(manifest.projects, group.id) redirect_to status_import_manifest_path else @@ -96,12 +95,16 @@ class Import::ManifestController < Import::BaseController # rubocop: disable CodeReuse/ActiveRecord def group - @group ||= Group.find_by(id: session[:manifest_import_group_id]) + @group ||= Group.find_by(id: manifest_import_metadata.group_id) end # rubocop: enable CodeReuse/ActiveRecord + def manifest_import_metadata + @manifest_import_status ||= Gitlab::ManifestImport::Metadata.new(current_user, fallback: session) + end + def repositories - @repositories ||= session[:manifest_import_repositories] + @repositories ||= manifest_import_metadata.repositories end def find_jobs diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index b7aeab8f5ff..ca2fad35451 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -2,6 +2,7 @@ class Projects::LabelsController < Projects::ApplicationController include ToggleSubscriptionAction + include ShowInheritedLabelsChecker before_action :check_issuables_available! before_action :label, only: [:edit, :update, :destroy, :promote] @@ -161,7 +162,7 @@ class Projects::LabelsController < Projects::ApplicationController @available_labels ||= LabelsFinder.new(current_user, project_id: @project.id, - include_ancestor_groups: params[:include_ancestor_groups], + include_ancestor_groups: show_inherited_labels?(params[:include_ancestor_groups]), search: params[:search], subscribed: params[:subscribed], sort: sort).execute diff --git a/app/finders/group_labels_finder.rb b/app/finders/group_labels_finder.rb deleted file mode 100644 index a668a0f0fae..00000000000 --- a/app/finders/group_labels_finder.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class GroupLabelsFinder - attr_reader :current_user, :group, :params - - def initialize(current_user, group, params = {}) - @current_user = current_user - @group = group - @params = params - end - - def execute - group.labels - .optionally_subscribed_by(subscriber_id) - .optionally_search(params[:search]) - .order_by(params[:sort]) - .page(params[:page]) - end - - private - - def subscriber_id - current_user&.id if subscribed? - end - - def subscribed? - params[:subscribed] == 'true' - end -end diff --git a/app/graphql/types/issue_sort_enum.rb b/app/graphql/types/issue_sort_enum.rb index e458d6e02c5..08762264b1b 100644 --- a/app/graphql/types/issue_sort_enum.rb +++ b/app/graphql/types/issue_sort_enum.rb @@ -8,6 +8,8 @@ module Types value 'DUE_DATE_ASC', 'Due date by ascending order', value: :due_date_asc value 'DUE_DATE_DESC', 'Due date by descending order', value: :due_date_desc value 'RELATIVE_POSITION_ASC', 'Relative position by ascending order', value: :relative_position_asc + value 'SEVERITY_ASC', 'Severity from less critical to more critical', value: :severity_asc + value 'SEVERITY_DESC', 'Severity from more critical to less critical', value: :severity_desc end end diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index d6253f74ce5..487508f448f 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -36,8 +36,7 @@ module Types end field :author, Types::UserType, null: false, - description: 'User that created the issue', - resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find } + description: 'User that created the issue' field :assignees, Types::UserType.connection_type, null: true, description: 'Assignees of the issue' @@ -45,16 +44,14 @@ module Types field :labels, Types::LabelType.connection_type, null: true, description: 'Labels of the issue' field :milestone, Types::MilestoneType, null: true, - description: 'Milestone of the issue', - resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, obj.milestone_id).find } + description: 'Milestone of the issue' field :due_date, Types::TimeType, null: true, description: 'Due date of the issue' field :confidential, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates the issue is confidential' field :discussion_locked, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates discussion is locked on the issue', - resolve: -> (obj, _args, _ctx) { !!obj.discussion_locked } + description: 'Indicates discussion is locked on the issue' field :upvotes, GraphQL::INT_TYPE, null: false, description: 'Number of upvotes the issue has received' @@ -108,6 +105,18 @@ module Types field :severity, Types::IssuableSeverityEnum, null: true, description: 'Severity level of the incident' + + def author + Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find + end + + def milestone + Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, object.milestone_id).find + end + + def discussion_locked + !!object.discussion_locked + end end end diff --git a/app/graphql/types/project_member_type.rb b/app/graphql/types/project_member_type.rb index f08781238d0..01731531ae2 100644 --- a/app/graphql/types/project_member_type.rb +++ b/app/graphql/types/project_member_type.rb @@ -12,7 +12,10 @@ module Types authorize :read_project field :project, Types::ProjectType, null: true, - description: 'Project that User is a member of', - resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, obj.source_id).find } + description: 'Project that User is a member of' + + def project + Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.source_id).find + end end end diff --git a/app/graphql/types/snippet_type.rb b/app/graphql/types/snippet_type.rb index f29b513c26c..495c25c1776 100644 --- a/app/graphql/types/snippet_type.rb +++ b/app/graphql/types/snippet_type.rb @@ -24,16 +24,14 @@ module Types field :project, Types::ProjectType, description: 'The project the snippet is associated with', null: true, - authorize: :read_project, - resolve: -> (snippet, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, snippet.project_id).find } + authorize: :read_project # Author can be nil in some scenarios. For example, # when the admin setting restricted visibility # level is set to public field :author, Types::UserType, description: 'The owner of the snippet', - null: true, - resolve: -> (snippet, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, snippet.author_id).find } + null: true field :file_name, GraphQL::STRING_TYPE, description: 'File Name of the snippet', @@ -86,5 +84,13 @@ module Types null: true markdown_field :description_html, null: true, method: :description + + def author + Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find + end + + def project + Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find + end end end diff --git a/app/graphql/types/sort_enum.rb b/app/graphql/types/sort_enum.rb index 3245cb33e0d..f9fa8829c7d 100644 --- a/app/graphql/types/sort_enum.rb +++ b/app/graphql/types/sort_enum.rb @@ -5,9 +5,16 @@ module Types graphql_name 'Sort' description 'Common sort values' + # Deprecated, as we prefer uppercase enums + # https://gitlab.com/groups/gitlab-org/-/epics/1838 value 'updated_desc', 'Updated at descending order' value 'updated_asc', 'Updated at ascending order' value 'created_desc', 'Created at descending order' value 'created_asc', 'Created at ascending order' + + value 'UPDATED_DESC', 'Updated at descending order', value: :updated_desc + value 'UPDATED_ASC', 'Updated at ascending order', value: :updated_asc + value 'CREATED_DESC', 'Created at descending order', value: :created_desc + value 'CREATED_ASC', 'Created at ascending order', value: :created_asc end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 0dea6217276..fc1bf4e38d7 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module SearchHelper - SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets, :state].freeze + SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets, :state, :confidential].freeze def search_autocomplete_opts(term) return unless current_user diff --git a/app/models/issue.rb b/app/models/issue.rb index 5a5de371301..a9b821e7d21 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -101,6 +101,8 @@ class Issue < ApplicationRecord scope :order_relative_position_asc, -> { reorder(::Gitlab::Database.nulls_last_order('relative_position', 'ASC')) } scope :order_closed_date_desc, -> { reorder(closed_at: :desc) } scope :order_created_at_desc, -> { reorder(created_at: :desc) } + scope :order_severity_asc, -> { includes(:issuable_severity).order('issuable_severities.severity ASC NULLS FIRST') } + scope :order_severity_desc, -> { includes(:issuable_severity).order('issuable_severities.severity DESC NULLS LAST') } scope :preload_associated_models, -> { preload(:assignees, :labels, project: :namespace) } scope :with_web_entity_associations, -> { preload(:author, :project) } @@ -232,6 +234,8 @@ class Issue < ApplicationRecord when 'due_date', 'due_date_asc' then order_due_date_asc.with_order_id_desc when 'due_date_desc' then order_due_date_desc.with_order_id_desc when 'relative_position', 'relative_position_asc' then order_relative_position_asc.with_order_id_desc + when 'severity_asc' then order_severity_asc.with_order_id_desc + when 'severity_desc' then order_severity_desc.with_order_id_desc else super end diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index fab02697cf0..e4907bf0761 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -14,7 +14,7 @@ module Search Gitlab::SearchResults.new(current_user, params[:search], projects, - filters: { state: params[:state] }) + filters: { state: params[:state], confidential: params[:confidential] }) end def projects diff --git a/app/services/search/group_service.rb b/app/services/search/group_service.rb index 68778aa2768..24409a04e74 100644 --- a/app/services/search/group_service.rb +++ b/app/services/search/group_service.rb @@ -16,7 +16,7 @@ module Search params[:search], projects, group: group, - filters: { state: params[:state] } + filters: { state: params[:state], confidential: params[:confidential] } ) end diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb index 5eba909c23b..9c18f8e947c 100644 --- a/app/services/search/project_service.rb +++ b/app/services/search/project_service.rb @@ -13,7 +13,8 @@ module Search params[:search], project: project, repository_ref: params[:repository_ref], - filters: { state: params[:state] }) + filters: { confidential: params[:confidential], state: params[:state] } + ) end def scope diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index 2fc46f033dd..e3f02bf85f0 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -104,7 +104,6 @@ module Users def build_user_params(skip_authorization:) if current_user&.admin? user_params = params.slice(*admin_create_params) - user_params[:created_by_id] = current_user&.id if params[:reset_password] user_params.merge!(force_random_password: true, password_expires_at: nil) @@ -125,6 +124,8 @@ module Users end end + user_params[:created_by_id] = current_user&.id + if user_default_internal_regex_enabled? && !user_params.key?(:external) user_params[:external] = user_external? end |