Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
dcf94a820d
commit
9970b06224
|
|
@ -0,0 +1,15 @@
|
|||
/title SHA256 Bug <!-- concise title here -->
|
||||
|
||||
### SHA256 Bug Summary
|
||||
|
||||
<!-- Summarize the bug -->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
<!-- Describe how one can reproduce the buggy behavior. Please use an ordered
|
||||
list -->
|
||||
|
||||
### Example project
|
||||
|
||||
<!-- If possible, provide a link to the project that is experiencing buggy
|
||||
behavior -->
|
||||
|
|
@ -39,6 +39,7 @@ export default {
|
|||
'groupName',
|
||||
'issueCount',
|
||||
'mergeRequestCount',
|
||||
'size',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -49,6 +50,9 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
widthClasses() {
|
||||
return this.size === 'small' ? 'gl-min-w-6' : 'gl-min-w-7';
|
||||
},
|
||||
hasUrl() {
|
||||
return this.editUrl || this.closeUrl || this.reopenUrl || this.promoteUrl;
|
||||
},
|
||||
|
|
@ -169,7 +173,9 @@ export default {
|
|||
no-caret
|
||||
:toggle-text="$options.i18n.actionsLabel"
|
||||
text-sr-only
|
||||
class="gl-relative gl-w-full gl-sm-w-auto gl-min-w-7"
|
||||
class="gl-relative gl-w-full sm:gl-w-auto"
|
||||
:class="widthClasses"
|
||||
:size="size"
|
||||
:data-testid="showTestIdIfNotDetailPage"
|
||||
@shown="showDropdown"
|
||||
@hidden="hideDropdown"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export default function InitMoreActionsDropdown() {
|
|||
groupName,
|
||||
issueCount,
|
||||
mergeRequestCount,
|
||||
size,
|
||||
} = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
|
|
@ -45,6 +46,7 @@ export default function InitMoreActionsDropdown() {
|
|||
groupName,
|
||||
issueCount: Number(issueCount),
|
||||
mergeRequestCount: Number(mergeRequestCount),
|
||||
size: size || 'medium',
|
||||
},
|
||||
render: (createElement) => createElement(MoreActionsDropdown),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
/* eslint-disable @gitlab/require-i18n-strings */
|
||||
|
||||
// This is temporary mock data that will be removed when completing https://gitlab.com/gitlab-org/gitlab/-/issues/454935
|
||||
|
||||
export const defaultOrganization = {
|
||||
id: 1,
|
||||
name: 'Default',
|
||||
web_url: '/-/organizations/default',
|
||||
avatar_url: null,
|
||||
};
|
||||
|
|
@ -3,7 +3,6 @@ import { GlDisclosureDropdown, GlAvatar, GlIcon, GlLoadingIcon, GlLink } from '@
|
|||
import getCurrentUserOrganizations from '~/organizations/shared/graphql/queries/organizations.query.graphql';
|
||||
import { AVATAR_SHAPE_OPTION_RECT } from '~/vue_shared/constants';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { defaultOrganization } from '~/organizations/mock_data';
|
||||
import { s__, __ } from '~/locale';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
|
||||
|
|
@ -67,9 +66,7 @@ export default {
|
|||
return this.$apollo.queries.organizations.loading;
|
||||
},
|
||||
currentOrganization() {
|
||||
// TODO - use `gon.current_organization` when backend supports it.
|
||||
// https://gitlab.com/gitlab-org/gitlab/-/issues/437095
|
||||
return defaultOrganization;
|
||||
return window.gon.current_organization;
|
||||
},
|
||||
nodes() {
|
||||
return this.organizations.nodes || [];
|
||||
|
|
@ -135,7 +132,7 @@ export default {
|
|||
<gl-disclosure-dropdown :items="items" class="gl-block" placement="bottom" @shown="onShown">
|
||||
<template #toggle>
|
||||
<button
|
||||
class="organization-switcher-button gl-flex gl-w-full gl-items-center gl-gap-3 gl-rounded-base gl-border-none gl-p-3 gl-leading-1"
|
||||
class="user-bar-button organization-switcher-button gl-flex gl-items-center gl-text-left gl-gap-3 gl-p-3 gl-rounded-base gl-border-none gl-leading-1 gl-w-full"
|
||||
data-testid="toggle-button"
|
||||
>
|
||||
<gl-avatar
|
||||
|
|
|
|||
|
|
@ -295,14 +295,15 @@ $command-palette-spacing: px-to-rem(14px);
|
|||
}
|
||||
|
||||
.organization-switcher-button {
|
||||
background-color: transparent;
|
||||
color: var(--super-sidebar-user-bar-button-color);
|
||||
&:not(:active),
|
||||
&:not(:hover),
|
||||
&:not(:focus) {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--super-sidebar-user-bar-button-hover-bg);
|
||||
color: var(--super-sidebar-user-bar-button-hover-color);
|
||||
.gl-avatar {
|
||||
color: var(--super-sidebar-user-bar-button-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
margin-bottom: $gl-padding-4;
|
||||
}
|
||||
|
||||
.milestone-progress,
|
||||
.milestone-release-links {
|
||||
.milestone-progress {
|
||||
a {
|
||||
color: var(--blue-600, $blue-600);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
.progress
|
||||
.progress-bar{ class: "bg-#{@variant}", style: "width: #{@value}%;" }
|
||||
.progress-bar{ class: "gl-rounded-base bg-#{@variant}", style: "width: #{@value}%;" }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ module TimeboxesHelper
|
|||
|
||||
def milestone_badge_variant(milestone)
|
||||
if milestone.closed?
|
||||
:danger
|
||||
:info
|
||||
elsif milestone.expired?
|
||||
:warning
|
||||
elsif milestone.upcoming?
|
||||
|
|
@ -91,7 +91,7 @@ module TimeboxesHelper
|
|||
def milestone_progress_bar(milestone)
|
||||
render Pajamas::ProgressComponent.new(
|
||||
value: milestone.percent_complete,
|
||||
variant: :success
|
||||
variant: :primary
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -170,6 +170,12 @@ module TimeboxesHelper
|
|||
[recent_releases, total_count, more_count]
|
||||
end
|
||||
|
||||
def milestone_releases_tooltip_list(releases, more_count = 0)
|
||||
list = releases.map(&:name).join(", ")
|
||||
list += format(_(", and %{number} more"), number: more_count) if more_count > 0
|
||||
list
|
||||
end
|
||||
|
||||
def milestone_tooltip_due_date(milestone)
|
||||
if milestone.due_date
|
||||
"#{milestone.due_date.to_fs(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
= render 'shared/milestones/milestone',
|
||||
issues_path: issues_dashboard_path(milestone_title: milestone.title),
|
||||
merge_requests_path: merge_requests_dashboard_path(milestone_title: milestone.title),
|
||||
milestone: milestone,
|
||||
dashboard: true
|
||||
milestone: milestone
|
||||
|
|
|
|||
|
|
@ -1,66 +1,71 @@
|
|||
- dashboard = local_assigns[:dashboard]
|
||||
- custom_dom_id = dom_id(milestone.try(:milestone) ? milestone.milestone : milestone)
|
||||
- milestone_type = milestone.group_milestone? ? s_('Milestones|Group Milestone') : s_('Milestones|Project Milestone')
|
||||
- can_admin_milestone = can?(current_user, :admin_milestone, milestone)
|
||||
- can_promote = @project && can_admin_group_milestones? && milestone.project
|
||||
|
||||
%li{ class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: custom_dom_id }
|
||||
.row
|
||||
.col-md-7.order-1{ class: can_admin_milestone ? 'col-11' : 'col-12' }
|
||||
.gl-mb-2
|
||||
%strong{ data: { testid: "milestone-link", qa_milestone_title: milestone.title } }
|
||||
= link_to truncate(milestone.title, length: 100), milestone_path(milestone)
|
||||
- if @group || dashboard
|
||||
= " - #{milestone_type}"
|
||||
%li{ class: "!gl-py-3 milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: custom_dom_id }
|
||||
.gl-flex.gl-gap-3.gl-px-4
|
||||
.gl-flex.gl-gap-4.gl-grow.gl-flex-wrap.sm:gl-flex-nowrap
|
||||
-# NAME AND PROJECT/GROUP
|
||||
.gl-flex.gl-flex-wrap.gl-grow.gl-gap-4.gl-gap-y-0.gl-items-center{ class: "xl:gl-basis-1/2 gl-w-full sm:gl-w-auto" }
|
||||
.gl-shrink.gl-font-bold{ data: { testid: "milestone-link", qa_milestone_title: milestone.title } }
|
||||
= link_to milestone.title, milestone_path(milestone)
|
||||
.gl-flex.gl-shrink-0.gl-items-center.gl-gap-2.gl-text-subtle.gl-text-sm
|
||||
- if milestone.project_milestone?
|
||||
= sprite_icon('project')
|
||||
%div
|
||||
= milestone.project.full_name
|
||||
|
||||
- if milestone.due_date || milestone.start_date
|
||||
.gl-text-subtle.gl-mb-2
|
||||
= milestone_date_range(milestone)
|
||||
- recent_releases, total_count, more_count = recent_releases_with_counts(milestone, current_user)
|
||||
- unless total_count == 0
|
||||
.gl-text-subtle.gl-mb-2.milestone-release-links
|
||||
= sprite_icon("rocket", size: 12)
|
||||
= n_('Release', 'Releases', total_count)
|
||||
- recent_releases.each do |release|
|
||||
= link_to release.name, project_releases_path(release.project, anchor: release.tag)
|
||||
- unless release == recent_releases.last
|
||||
•
|
||||
- if total_count > recent_releases.count
|
||||
•
|
||||
- more_text = n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }
|
||||
- if milestone.project_milestone?
|
||||
= link_to more_text, project_releases_path(milestone.project)
|
||||
- if milestone.group_milestone?
|
||||
= sprite_icon('group')
|
||||
%div
|
||||
= milestone.group.full_name
|
||||
|
||||
-# RELEASES, STATUS AND DATES
|
||||
.gl-flex.gl-shrink-0.gl-gap-3.gl-items-center.gl-justify-end.gl-text-sm.gl-whitespace-nowrap{ class: "xl:gl-basis-[17rem]" }
|
||||
-# RELEASES
|
||||
- recent_releases, total_count, more_count = recent_releases_with_counts(milestone, current_user)
|
||||
- unless total_count == 0
|
||||
.gl-text-subtle.gl-flex.gl-gap-2.gl-items-center
|
||||
= sprite_icon("rocket-launch", size: 12)
|
||||
- if total_count > 1
|
||||
.has-tooltip{ title: milestone_releases_tooltip_list(recent_releases, more_count) }
|
||||
= format(_('%{count} releases'), count: total_count)
|
||||
- else
|
||||
= more_text
|
||||
%div
|
||||
= render('shared/milestone_expired', milestone: milestone)
|
||||
- if milestone.group_milestone?
|
||||
= gl_badge_tag milestone.group.full_name, { variant: :info }, { class: 'gl-whitespace-normal gl-text-left' }
|
||||
- if milestone.project_milestone?
|
||||
= gl_badge_tag milestone.project.full_name, { variant: :muted }, { class: 'gl-whitespace-normal gl-text-left' }
|
||||
= recent_releases.first.name
|
||||
-# SEPARATOR FOR WHEN THERE ARE RELEASES AND DATES
|
||||
- if total_count > 0 && (milestone.due_date || milestone.start_date)
|
||||
%div ·
|
||||
-# STATUS AND DATES
|
||||
- if milestone.due_date || milestone.start_date
|
||||
.gl-text-subtle
|
||||
= milestone_date_range(milestone)
|
||||
%div
|
||||
= gl_badge_tag milestone_status_string(milestone), { variant: milestone_badge_variant(milestone) }
|
||||
|
||||
.order-3.order-md-2.mt-2.mt-md-0.milestone-progress{ class: can_admin_milestone ? 'col-md-4' : 'col-md-5' }
|
||||
= milestone_progress_bar(milestone)
|
||||
= link_to pluralize(milestone.total_issues_count, _('Issue')), issues_path
|
||||
- if milestone.merge_requests_enabled?
|
||||
·
|
||||
= link_to pluralize(milestone.total_merge_requests_count, _('Merge request')), merge_requests_path
|
||||
.float-lg-right.light
|
||||
= format(s_('Milestone|%{percentage}%{percent} complete'), percentage: milestone.percent_complete, percent: '%')
|
||||
-# PROGRESS
|
||||
.gl-flex.gl-shrink-0.gl-items-center.gl-gap-3.gl-justify-end.gl-text-subtle.gl-text-sm{ class: "xl:gl-basis-1/5" }
|
||||
.gl-text-right{ class: "gl-w-[6.5rem] gl-hidden md:gl-block" }
|
||||
= format('%{completed}/%{total} %{complete}', completed: milestone.closed_issues_count, total: milestone.total_issues_count, complete: _('complete'))
|
||||
.gl-w-11
|
||||
= milestone_progress_bar(milestone)
|
||||
.gl-whitespace-nowrap.gl-shrink-0.gl-w-8
|
||||
= format(s_('Milestone|%{percentage}%{percent}'), percentage: milestone.percent_complete, percent: '%')
|
||||
|
||||
-# MENU
|
||||
- if can_admin_milestone
|
||||
- show_delete = @project.present? || @group.present?
|
||||
.col-1.order-2.order-md-3
|
||||
.gl-flex.gl-justify-end
|
||||
.js-vue-milestone-actions{ data: { id: milestone.id,
|
||||
title: milestone.title,
|
||||
is_active: milestone.active?.to_s,
|
||||
show_delete: show_delete.to_s,
|
||||
milestone_url: Gitlab::UrlBuilder.build(milestone, only_path: true),
|
||||
edit_url: edit_milestone_path(milestone),
|
||||
close_url: milestone_path(milestone, milestone: { state_event: :close }),
|
||||
reopen_url: milestone_path(milestone, milestone: { state_event: :activate }),
|
||||
promote_url: can_promote ? promote_project_milestone_path(milestone.project, milestone) : '',
|
||||
group_name: can_promote ? @project.group.name : '',
|
||||
issue_count: milestone.issues.count,
|
||||
merge_request_count: milestone.merge_requests.count
|
||||
} }
|
||||
.gl-w-6.gl-flex.gl-items-center
|
||||
.js-vue-milestone-actions{ data: { id: milestone.id,
|
||||
title: milestone.title,
|
||||
is_active: milestone.active?.to_s,
|
||||
show_delete: show_delete.to_s,
|
||||
size: "small",
|
||||
milestone_url: Gitlab::UrlBuilder.build(milestone, only_path: true),
|
||||
edit_url: edit_milestone_path(milestone),
|
||||
close_url: milestone_path(milestone, milestone: { state_event: :close }),
|
||||
reopen_url: milestone_path(milestone, milestone: { state_event: :activate }),
|
||||
promote_url: can_promote ? promote_project_milestone_path(milestone.project, milestone) : '',
|
||||
group_name: can_promote ? @project.group.name : '',
|
||||
issue_count: milestone.issues.count,
|
||||
merge_request_count: milestone.merge_requests.count
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -45,7 +45,14 @@ class UpdateWeightWidgetDefinitions < Gitlab::Database::Migration[2.2]
|
|||
@work_item_widget_definitions ||= define_batchable_model('work_item_widget_definitions')
|
||||
end
|
||||
|
||||
def work_item_types
|
||||
@work_item_types ||= define_batchable_model('work_item_types')
|
||||
@work_item_types.reset_column_information
|
||||
|
||||
@work_item_types
|
||||
end
|
||||
|
||||
def epic_type
|
||||
@epic_type ||= define_batchable_model('work_item_types').find_by_base_type_and_namespace_id(EPIC_TYPE_ENUM, nil)
|
||||
@epic_type ||= work_item_types.find_by_base_type_and_namespace_id(EPIC_TYPE_ENUM, nil)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ class RemoveCrmContactsWidgetFromWorkItemTypes < Gitlab::Database::Migration[2.2
|
|||
end
|
||||
|
||||
def down
|
||||
WorkItemType.reset_column_information
|
||||
|
||||
widgets = []
|
||||
|
||||
WORK_ITEM_TYPES.each do |type_name|
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ class ChangeEpicsHierarchyRestrictions < Gitlab::Database::Migration[2.1]
|
|||
private
|
||||
|
||||
def upsert_epic_restrictions(stepping_down: false)
|
||||
MigrationWorkItemType.reset_column_information
|
||||
|
||||
issue_type = MigrationWorkItemType.find_by_name_and_namespace_id('Issue', nil)
|
||||
epic_type = MigrationWorkItemType.find_by_name_and_namespace_id('Epic', nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class EnableCrossHierarchyForHierarchyRestrictions < Gitlab::Database::Migration
|
|||
private
|
||||
|
||||
def upsert_enable_cross_hierarchy_restrictions(stepping_down: false)
|
||||
MigrationWorkItemType.reset_column_information
|
||||
|
||||
issue_type = MigrationWorkItemType.find_by_name_and_namespace_id('Issue', nil)
|
||||
task_type = MigrationWorkItemType.find_by_name_and_namespace_id('Task', nil)
|
||||
objective_type = MigrationWorkItemType.find_by_name_and_namespace_id('Objective', nil)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class UpdateHierarchyRestrictionSubepicsMaximumDepth < Gitlab::Database::Migrati
|
|||
private
|
||||
|
||||
def upsert_epic_restrictions(max_depth: OLD_DEPTH)
|
||||
MigrationWorkItemType.reset_column_information
|
||||
|
||||
epic_type = MigrationWorkItemType.find_by_name_and_namespace_id('Epic', nil)
|
||||
|
||||
unless epic_type
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddWorkItemTypesNameUniqueIndex < Gitlab::Database::Migration[2.2]
|
||||
INDEX_NAME = 'index_work_item_types_on_name_unique'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
milestone '17.4'
|
||||
|
||||
def up
|
||||
add_concurrent_index :work_item_types,
|
||||
'TRIM(BOTH FROM LOWER(name))',
|
||||
name: INDEX_NAME,
|
||||
unique: true
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :work_item_types, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropWorkItemTypesNamespaceId < Gitlab::Database::Migration[2.2]
|
||||
UNIQUE_INDEX_NAME = 'work_item_types_namespace_id_and_name_unique'
|
||||
UNIQUE_DEFAULT_NAMESPACE_INDEX_NAME = 'idx_work_item_types_on_namespace_id_and_name_null_namespace'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
milestone '17.4'
|
||||
|
||||
def up
|
||||
remove_column :work_item_types, :namespace_id
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :work_item_types, :namespace_id, :bigint
|
||||
|
||||
add_concurrent_index :work_item_types,
|
||||
'TRIM(BOTH FROM LOWER(name)), (namespace_id IS NULL)',
|
||||
unique: true,
|
||||
name: UNIQUE_DEFAULT_NAMESPACE_INDEX_NAME,
|
||||
where: 'namespace_id IS NULL'
|
||||
|
||||
add_concurrent_index :work_item_types,
|
||||
'namespace_id, TRIM(BOTH FROM LOWER(name))',
|
||||
unique: true,
|
||||
name: UNIQUE_INDEX_NAME
|
||||
|
||||
add_concurrent_foreign_key :work_item_types, :namespaces, column: :namespace_id, on_delete: :cascade
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
824b597b21d3e135f9716917621856ce02c6b55e20460fc86a7df0bcd6e0fb02
|
||||
|
|
@ -0,0 +1 @@
|
|||
cfb2bdacf66e68b63087161c5c948a33f16614fa7ef3b19d4d03a230e256a713
|
||||
|
|
@ -20282,7 +20282,6 @@ CREATE TABLE work_item_types (
|
|||
description text,
|
||||
description_html text,
|
||||
icon_name text,
|
||||
namespace_id bigint,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
CONSTRAINT check_104d2410f6 CHECK ((char_length(name) <= 255)),
|
||||
|
|
@ -26587,8 +26586,6 @@ CREATE INDEX idx_vulnerability_reads_for_traversal_ids_queries_srt_severity ON v
|
|||
|
||||
CREATE INDEX idx_vulnerability_reads_project_id_scanner_id_vulnerability_id ON vulnerability_reads USING btree (project_id, scanner_id, vulnerability_id);
|
||||
|
||||
CREATE UNIQUE INDEX idx_work_item_types_on_namespace_id_and_name_null_namespace ON work_item_types USING btree (btrim(lower(name)), ((namespace_id IS NULL))) WHERE (namespace_id IS NULL);
|
||||
|
||||
CREATE INDEX index_p_ci_builds_on_execution_config_id ON ONLY p_ci_builds USING btree (execution_config_id) WHERE (execution_config_id IS NOT NULL);
|
||||
|
||||
CREATE INDEX index_0928d9f200 ON ci_builds USING btree (execution_config_id) WHERE (execution_config_id IS NOT NULL);
|
||||
|
|
@ -30515,6 +30512,8 @@ CREATE INDEX index_work_item_related_link_restrictions_on_target_type_id ON work
|
|||
|
||||
CREATE INDEX index_work_item_types_on_base_type_and_id ON work_item_types USING btree (base_type, id);
|
||||
|
||||
CREATE UNIQUE INDEX index_work_item_types_on_name_unique ON work_item_types USING btree (TRIM(BOTH FROM lower(name)));
|
||||
|
||||
CREATE UNIQUE INDEX index_work_item_widget_definitions_on_default_witype_and_name ON work_item_widget_definitions USING btree (work_item_type_id, name) WHERE (namespace_id IS NULL);
|
||||
|
||||
CREATE UNIQUE INDEX index_work_item_widget_definitions_on_namespace_type_and_name ON work_item_widget_definitions USING btree (namespace_id, work_item_type_id, name);
|
||||
|
|
@ -30847,8 +30846,6 @@ CREATE INDEX wi_datessources_start_date_sourcing_milestone_id_index ON work_item
|
|||
|
||||
CREATE INDEX wi_datessources_start_date_sourcing_work_item_id_index ON work_item_dates_sources USING btree (start_date_sourcing_work_item_id);
|
||||
|
||||
CREATE UNIQUE INDEX work_item_types_namespace_id_and_name_unique ON work_item_types USING btree (namespace_id, btrim(lower(name)));
|
||||
|
||||
ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_00_pkey;
|
||||
|
||||
ALTER INDEX analytics_cycle_analytics_issue_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01_pkey;
|
||||
|
|
@ -34455,9 +34452,6 @@ ALTER TABLE ONLY boards_epic_lists
|
|||
ALTER TABLE ONLY approval_merge_request_rules_groups
|
||||
ADD CONSTRAINT fk_rails_2020a7124a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY work_item_types
|
||||
ADD CONSTRAINT fk_rails_20f694a960 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY user_statuses
|
||||
ADD CONSTRAINT fk_rails_2178592333 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ The compliance framework is configured in the [new group](#create-a-new-group).
|
|||
To configure the compliance framework:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find the `Tutorial group` group.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Compliance frameworks**.
|
||||
1. Select **Add framework**.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Select **New framework**.
|
||||
1. In the **Name** field, enter `Tutorial compliance framework`.
|
||||
1. In the **Description** field, enter `Compliance framework for tutorial`.
|
||||
1. In the **Compliance pipeline configuration (optional)** field, enter
|
||||
|
|
@ -92,10 +92,11 @@ To configure the compliance framework:
|
|||
For convenience, make the new compliance framework the default for all new projects in the group:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find the `Tutorial group` group.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Compliance frameworks**.
|
||||
1. In the row for `Tutorial compliance framework`, select **Options** (**{ellipsis_v}**).
|
||||
1. Select **Set default**.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Select `Tutorial compliance framework` then, select **Edit framework**.
|
||||
1. Select **Set as default**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Create a new project and apply the compliance framework
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def issue_work_item_type_id
|
||||
@issue_work_item_type_id ||= WorkItemType.find_by(namespace_id: nil, name: 'Issue').id
|
||||
@issue_work_item_type_id ||= WorkItemType.find_by(name: 'Issue').id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ module Gitlab
|
|||
|
||||
::WorkItems::Type.upsert_all(
|
||||
base_types,
|
||||
unique_by: :idx_work_item_types_on_namespace_id_and_name_null_namespace
|
||||
unique_by: :index_work_item_types_on_name_unique
|
||||
)
|
||||
|
||||
upsert_widgets
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ module Gitlab
|
|||
gon.time_display_format = current_user.time_display_format
|
||||
end
|
||||
|
||||
if current_organization && Feature.enabled?(:ui_for_organizations, current_user)
|
||||
gon.current_organization = current_organization.slice(:id, :name, :web_url, :avatar_url)
|
||||
end
|
||||
|
||||
# Initialize gon.features with any flags that should be
|
||||
# made globally available to the frontend
|
||||
push_frontend_feature_flag(:source_editor_toolbar)
|
||||
|
|
@ -141,6 +145,20 @@ module Gitlab
|
|||
gon.analytics_url = ENV['GITLAB_ANALYTICS_URL']
|
||||
gon.analytics_id = ENV['GITLAB_ANALYTICS_ID']
|
||||
end
|
||||
|
||||
# `::Current.organization` is only valid within the context of a request,
|
||||
# but it can be called from everywhere. So how do we avoid accidentally
|
||||
# calling it outside of the context of a request? We banned it with
|
||||
# Rubocop.
|
||||
#
|
||||
# This method is acceptable because it is only included by controllers.
|
||||
# This method intentionally looks like Devise's `current_user` method,
|
||||
# which has similar properties.
|
||||
# rubocop:disable Gitlab/AvoidCurrentOrganization -- This method follows the spirit of the rule
|
||||
def current_organization
|
||||
::Current.organization
|
||||
end
|
||||
# rubocop:enable Gitlab/AvoidCurrentOrganization
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -760,6 +760,9 @@ msgstr[1] ""
|
|||
msgid "%{count} related %{pluralized_subject}: %{links}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} releases"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} selected"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1687,6 +1690,9 @@ msgstr ""
|
|||
msgid ", "
|
||||
msgstr ""
|
||||
|
||||
msgid ", and %{number} more"
|
||||
msgstr ""
|
||||
|
||||
msgid ", or "
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -33794,9 +33800,6 @@ msgstr ""
|
|||
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestones|Group Milestone"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestones|Labels from issues in this milestone will appear here."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -33812,9 +33815,6 @@ msgstr ""
|
|||
msgid "Milestones|Organize issues and merge requests into a cohesive group, and set optional start and due dates. %{learn_more_link}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestones|Project Milestone"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -33839,7 +33839,7 @@ msgstr ""
|
|||
msgid "Milestones|Use milestones to track issues and merge requests over a fixed period of time"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestone|%{percentage}%{percent} complete"
|
||||
msgid "Milestone|%{percentage}%{percent}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Milestone|Copy milestone ID: %{id}"
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ RSpec.describe 'Dashboard > Milestones', :js, feature_category: :team_planning d
|
|||
expect(page).to have_current_path dashboard_milestones_path, ignore_query: true
|
||||
expect(page).to have_content(milestone.title)
|
||||
expect(page).to have_content(group.name)
|
||||
expect(first('.milestone')).to have_content('Merge requests')
|
||||
expect(first('.milestone').text).to match(%r{\d/\d complete})
|
||||
expect(first('.milestone').text).to match(%r{\d%})
|
||||
end
|
||||
|
||||
describe 'new milestones dropdown' do
|
||||
|
|
|
|||
|
|
@ -153,33 +153,15 @@ RSpec.describe 'Group milestones', feature_category: :team_planning do
|
|||
end
|
||||
|
||||
it 'renders milestones' do
|
||||
expect(page).to have_content('v1.0')
|
||||
expect(page).to have_content('v1.1')
|
||||
expect(page).to have_content('GL-113')
|
||||
expect(page).to have_link(
|
||||
expect(first('.milestone')).to have_link(
|
||||
'v1.0',
|
||||
href: project_milestone_path(project, active_project_milestone1)
|
||||
)
|
||||
expect(page).to have_link(
|
||||
'1 Issue',
|
||||
href: project_issues_path(project, milestone_title: 'v1.0')
|
||||
)
|
||||
expect(page).to have_link(
|
||||
'0 Merge requests',
|
||||
href: project_merge_requests_path(project, milestone_title: 'v1.0')
|
||||
)
|
||||
expect(page).to have_link(
|
||||
'GL-113',
|
||||
href: group_milestone_path(group, active_group_milestone)
|
||||
)
|
||||
expect(page).to have_link(
|
||||
'0 Issues',
|
||||
href: issues_group_path(group, milestone_title: 'GL-113')
|
||||
)
|
||||
expect(page).to have_link(
|
||||
'0 Merge requests',
|
||||
href: merge_requests_group_path(group, milestone_title: 'GL-113')
|
||||
)
|
||||
expect(first('.milestone')).to have_content('0/1 complete')
|
||||
expect(first('.milestone')).to have_content('0%')
|
||||
|
||||
expect(page).to have_content('v1.1')
|
||||
expect(page).to have_content('GL-113')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ RSpec.describe 'Milestones sorting', :js, feature_category: :team_planning do
|
|||
|
||||
# assert default sorting
|
||||
within '.milestones' do
|
||||
expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(['v2.0', 'v2.0', 'v3.0', 'v1.0', 'v1.0'])
|
||||
expect(page.all('[data-testid="milestone-link"]').map(&:text)).to eq(['v2.0', 'v2.0', 'v3.0', 'v1.0', 'v1.0'])
|
||||
end
|
||||
|
||||
click_button 'Due soon'
|
||||
|
|
@ -39,7 +39,7 @@ RSpec.describe 'Milestones sorting', :js, feature_category: :team_planning do
|
|||
|
||||
# assert descending sorting
|
||||
within '.milestones' do
|
||||
expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(['v1.0', 'v1.0', 'v3.0', 'v2.0', 'v2.0'])
|
||||
expect(page.all('[data-testid="milestone-link"]').map(&:text)).to eq(['v1.0', 'v1.0', 'v3.0', 'v2.0', 'v2.0'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ RSpec.describe "User views milestones", feature_category: :team_planning do
|
|||
it "shows milestone" do
|
||||
expect(page).to have_content(milestone.title)
|
||||
.and have_content(milestone.expires_at)
|
||||
.and have_content("Issues")
|
||||
.and have_content("Merge requests")
|
||||
expect(first('.milestone').text).to match(%r{\d/\d complete})
|
||||
expect(first('.milestone').text).to match(%r{\d%})
|
||||
end
|
||||
|
||||
context "with issues", :js do
|
||||
|
|
@ -41,8 +41,7 @@ RSpec.describe "User views milestones", feature_category: :team_planning do
|
|||
|
||||
context "with a single associated release" do
|
||||
it "shows the associated release" do
|
||||
expect(page).to have_content("Release #{first_release.name}")
|
||||
expect(page).to have_link(first_release.name, href: project_releases_path(project, anchor: first_release.tag))
|
||||
expect(page).to have_content(first_release.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -53,41 +52,8 @@ RSpec.describe "User views milestones", feature_category: :team_planning do
|
|||
let_it_be(:fifth_release) { create(:release, project: project, name: "The fifth release", milestones: [milestone], released_at: fourth_release.released_at + 1.day) }
|
||||
|
||||
it "shows the associated releases and the truncation text" do
|
||||
expect(page).to have_content("Releases #{fifth_release.name} • #{fourth_release.name} • #{third_release.name} • 2 more releases")
|
||||
|
||||
expect(page).to have_link(fifth_release.name, href: project_releases_path(project, anchor: fifth_release.tag))
|
||||
expect(page).to have_link(fourth_release.name, href: project_releases_path(project, anchor: fourth_release.tag))
|
||||
expect(page).to have_link(third_release.name, href: project_releases_path(project, anchor: third_release.tag))
|
||||
expect(page).to have_link("2 more releases", href: project_releases_path(project))
|
||||
expect(page).to have_content("5 releases")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe "User views milestones with no MR" do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :merge_requests_disabled) }
|
||||
let_it_be(:milestone) { create(:milestone, project: project) }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
sign_in(user)
|
||||
|
||||
visit(project_milestones_path(project))
|
||||
end
|
||||
|
||||
it "shows milestone" do
|
||||
expect(page).to have_content(milestone.title)
|
||||
.and have_content(milestone.expires_at)
|
||||
.and have_content("Issues")
|
||||
end
|
||||
|
||||
it "opens milestone" do
|
||||
click_link(milestone.title)
|
||||
|
||||
expect(page).to have_current_path(project_milestone_path(project, milestone), ignore_query: true)
|
||||
expect(page).to have_content(milestone.title)
|
||||
.and have_selector("#tab-issues")
|
||||
.and have_no_selector("#tab-merge-requests")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ RSpec.describe 'Milestones sorting', :js, feature_category: :team_planning do
|
|||
|
||||
# assert default sorting order
|
||||
within '.milestones' do
|
||||
expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(%w[a c b])
|
||||
expect(page.all('[data-testid="milestone-link"]').map(&:text)).to eq(%w[a c b])
|
||||
end
|
||||
|
||||
# assert milestones listed for given sort order
|
||||
|
|
@ -51,7 +51,7 @@ RSpec.describe 'Milestones sorting', :js, feature_category: :team_planning do
|
|||
expect(page).to have_button(sort_by)
|
||||
|
||||
within '.milestones' do
|
||||
expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(expected_milestones)
|
||||
expect(page.all('[data-testid="milestone-link"]').map(&:text)).to eq(expected_milestones)
|
||||
end
|
||||
|
||||
selected_sort_order = sort_by
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ describe('moreActionsDropdown', () => {
|
|||
issueCount: 1,
|
||||
mergeRequestCount: 2,
|
||||
isDetailPage: false,
|
||||
size: 'medium',
|
||||
};
|
||||
|
||||
const createComponent = ({ provideData = {}, propsData = {} } = {}) => {
|
||||
|
|
|
|||
|
|
@ -21,3 +21,10 @@ export const pageInfoEmpty = {
|
|||
startCursor: null,
|
||||
__typename: 'PageInfo',
|
||||
};
|
||||
|
||||
export const defaultOrganization = {
|
||||
id: 1,
|
||||
name: 'Default',
|
||||
web_url: '/-/organizations/default',
|
||||
avatar_url: null,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ import Vue from 'vue';
|
|||
import organizationsGraphQlResponse from 'test_fixtures/graphql/organizations/organizations.query.graphql.json';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import OrganizationSwitcher from '~/super_sidebar/components/organization_switcher.vue';
|
||||
import { defaultOrganization as currentOrganization } from '~/organizations/mock_data';
|
||||
import { pageInfoEmpty } from 'jest/organizations/mock_data';
|
||||
import {
|
||||
pageInfoEmpty,
|
||||
defaultOrganization as currentOrganization,
|
||||
} from 'jest/organizations/mock_data';
|
||||
import organizationsQuery from '~/organizations/shared/graphql/queries/organizations.query.graphql';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
|
|
@ -55,6 +57,10 @@ describe('OrganizationSwitcher', () => {
|
|||
wrapper.findAllByTestId('disclosure-dropdown-item').at(index);
|
||||
const showDropdown = () => wrapper.findComponent(GlDisclosureDropdown).vm.$emit('shown');
|
||||
|
||||
beforeEach(() => {
|
||||
window.gon.current_organization = currentOrganization;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockApollo = null;
|
||||
window.gon = {};
|
||||
|
|
|
|||
|
|
@ -65,6 +65,20 @@ RSpec.describe TimeboxesHelper, feature_category: :team_planning do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#milestone_releases_tooltip_list' do
|
||||
let_it_be(:project) { milestone_upcoming.project }
|
||||
|
||||
it 'returns comma separated list of the names of supplied releases and adds the more count when defined' do
|
||||
test_releases = create_list(:release, 3, project: project, milestones: [milestone_upcoming], released_at: '2022-01-01T18:00:00Z')
|
||||
|
||||
releases_list_text = test_releases.map(&:name).join(', ')
|
||||
|
||||
expect(helper.milestone_releases_tooltip_list(test_releases)).to eq(releases_list_text)
|
||||
|
||||
expect(helper.milestone_releases_tooltip_list(test_releases, 7)).to eq("#{releases_list_text}, and 7 more")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#milestone_status_string' do
|
||||
where(:milestone, :status) do
|
||||
lazy { milestone_expired } | 'Expired'
|
||||
|
|
@ -84,8 +98,8 @@ RSpec.describe TimeboxesHelper, feature_category: :team_planning do
|
|||
describe '#milestone_badge_variant' do
|
||||
where(:milestone, :variant) do
|
||||
lazy { milestone_expired } | :warning
|
||||
lazy { milestone_closed } | :danger
|
||||
lazy { milestone_closed_and_expired } | :danger
|
||||
lazy { milestone_closed } | :info
|
||||
lazy { milestone_closed_and_expired } | :info
|
||||
lazy { milestone_upcoming } | :neutral
|
||||
lazy { milestone_open } | :success
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::LooseIndexScanBa
|
|||
let(:projects) { table(:projects) }
|
||||
let(:issues) { table(:issues) }
|
||||
let(:issue_base_type_enum_value) { 0 }
|
||||
let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) }
|
||||
let(:issue_type) { table(:work_item_types).find_by!(base_type: issue_base_type_enum_value) }
|
||||
|
||||
let!(:namespace1) { namespaces.create!(name: 'ns1', path: 'ns1') }
|
||||
let!(:namespace2) { namespaces.create!(name: 'ns2', path: 'ns2') }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::GonHelper, feature_category: :shared do
|
||||
let_it_be(:organization) { create(:organization) }
|
||||
let(:helper) do
|
||||
Class.new do
|
||||
include Gitlab::GonHelper
|
||||
|
|
@ -77,6 +78,43 @@ RSpec.describe Gitlab::GonHelper, feature_category: :shared do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ui_for_organizations feature flag is enabled' do
|
||||
context 'when current_organization is set' do
|
||||
before do
|
||||
allow(::Current).to receive(:organization).and_return(organization)
|
||||
end
|
||||
|
||||
it 'exposes current_organization' do
|
||||
expect(gon).to receive(:current_organization=).with(
|
||||
organization.slice(:id, :name, :web_url, :avatar_url)
|
||||
)
|
||||
|
||||
helper.add_gon_variables
|
||||
end
|
||||
end
|
||||
|
||||
context 'when current_organization is not set' do
|
||||
it 'does not expose current_organization' do
|
||||
expect(gon).not_to receive(:current_organization=)
|
||||
|
||||
helper.add_gon_variables
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ui_for_organizations feature flag is disabled' do
|
||||
before do
|
||||
allow(::Current).to receive(:organization).and_return(organization)
|
||||
stub_feature_flags(ui_for_organizations: false)
|
||||
end
|
||||
|
||||
it 'does not expose current_organization' do
|
||||
expect(gon).not_to receive(:current_organization=)
|
||||
|
||||
helper.add_gon_variables
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#push_frontend_ability' do
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ RSpec.describe SwapTimelogsNoteIdToBigintForSelfHosts, feature_category: :databa
|
|||
connection.execute('ALTER TABLE timelogs DROP COLUMN IF EXISTS note_id_convert_to_bigint')
|
||||
end
|
||||
|
||||
it 'swaps the columns' do
|
||||
it 'swaps the columns', :aggregate_failures do
|
||||
disable_migrations_output do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ RSpec.describe WorkItems::Type, feature_category: :team_planning do
|
|||
end
|
||||
|
||||
describe '.default_by_type' do
|
||||
let(:default_issue_type) { described_class.find_by(namespace_id: nil, base_type: :issue) }
|
||||
let(:default_issue_type) { described_class.find_by(base_type: :issue) }
|
||||
let(:base_type) { :issue }
|
||||
|
||||
subject { described_class.default_by_type(base_type) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue