Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-05-03 21:13:03 +00:00
parent a5f5c99d4a
commit e4a70049b6
95 changed files with 219 additions and 136 deletions

View File

@ -116,7 +116,6 @@ Gitlab/AvoidGitlabInstanceChecks:
- 'ee/lib/gitlab/llm/tanuki_bot.rb'
- 'ee/lib/gitlab/manual_quarterly_co_term_banner.rb'
- 'ee/lib/gitlab/sitemaps/generator.rb'
- 'ee/lib/sidebars/groups/menus/trial_widget_menu.rb'
- 'ee/lib/sidebars/user_settings/menus/profile_billing_menu.rb'
- 'ee/lib/tasks/gitlab/elastic.rake'
- 'ee/spec/factories/gitlab_subscriptions.rb'

View File

@ -219,21 +219,6 @@ Layout/ArgumentAlignment:
- 'ee/app/graphql/mutations/security_policy/assign_security_policy_project.rb'
- 'ee/app/graphql/mutations/security_policy/commit_scan_execution_policy.rb'
- 'ee/app/graphql/mutations/security_policy/create_security_policy_project.rb'
- 'ee/app/graphql/mutations/security_policy/unassign_security_policy_project.rb'
- 'ee/app/graphql/mutations/users/abuse/namespace_bans/destroy.rb'
- 'ee/app/graphql/mutations/vulnerabilities/confirm.rb'
- 'ee/app/graphql/mutations/vulnerabilities/create_external_issue_link.rb'
- 'ee/app/graphql/mutations/vulnerabilities/destroy_external_issue_link.rb'
- 'ee/app/graphql/mutations/vulnerabilities/dismiss.rb'
- 'ee/app/graphql/mutations/vulnerabilities/resolve.rb'
- 'ee/app/graphql/mutations/vulnerabilities/revert_to_detected.rb'
- 'ee/app/graphql/resolvers/alert_management/payload_alert_field_resolver.rb'
- 'ee/app/graphql/resolvers/analytics/contribution_analytics/contributions_resolver.rb'
- 'ee/app/graphql/resolvers/analytics/devops_adoption/enabled_namespaces_resolver.rb'
- 'ee/app/graphql/resolvers/analytics/devops_adoption/snapshots_resolver.rb'
- 'ee/app/graphql/resolvers/app_sec/dast/profile_resolver.rb'
- 'ee/app/graphql/resolvers/board_groupings/epics_resolver.rb'
- 'ee/app/graphql/resolvers/boards/board_list_epics_resolver.rb'
- 'ee/app/graphql/resolvers/incident_management/escalation_policies_resolver.rb'
- 'ee/app/graphql/resolvers/incident_management/issuable_resource_links_resolver.rb'
- 'ee/app/graphql/resolvers/incident_management/oncall_rotations_resolver.rb'

View File

@ -84,7 +84,7 @@ export default {
{
key: 'buttons',
label: '',
tdClass: `${DEFAULT_TD_CLASSES} gl-white-space-nowrap`,
tdClass: `${DEFAULT_TD_CLASSES} gl-whitespace-nowrap`,
},
],
methods: {

View File

@ -64,8 +64,8 @@ export default {
{
key: 'actions',
label: __('Actions'),
tdClass: 'gl-lg-w-1px gl-white-space-nowrap',
thClass: 'gl-lg-w-1px gl-white-space-nowrap',
tdClass: 'gl-lg-w-1px gl-whitespace-nowrap',
thClass: 'gl-lg-w-1px gl-whitespace-nowrap',
},
],
modal: {

View File

@ -414,7 +414,7 @@ export default {
v-if="item.iteration"
data-testid="issue-iteration"
:iteration="item.iteration"
class="gl-align-bottom gl-white-space-nowrap"
class="gl-align-bottom gl-whitespace-nowrap"
/>
<issue-due-date
v-if="item.dueDate"

View File

@ -202,7 +202,7 @@ export default {
v-if="!isSwimlanesOn"
ref="list"
v-bind="draggableOptions"
class="boards-list gl-w-full gl-py-5 gl-pl-0 gl-pr-5 xl:gl-pl-3 xl:gl-pr-6 gl-white-space-nowrap gl-overflow-x-auto"
class="boards-list gl-w-full gl-py-5 gl-pl-0 gl-pr-5 xl:gl-pl-3 xl:gl-pr-6 gl-whitespace-nowrap gl-overflow-x-auto"
@end="updateListPosition"
>
<board-column

View File

@ -178,7 +178,7 @@ export default {
<div class="js-pipeline-graph">
<div
ref="mainPipelineContainer"
class="pipeline-graph gl-display-flex gl-position-relative gl-white-space-nowrap gl-rounded-lg"
class="pipeline-graph gl-display-flex gl-position-relative gl-whitespace-nowrap gl-rounded-lg"
:class="{
'pipeline-graph-container gl-bg-gray-10 gl-pipeline-min-h gl-align-items-flex-start gl-pt-3 gl-pb-8 gl-mt-3 gl-overflow-auto': !isLinkedPipeline,
'gl-bg-gray-50 gl-sm-ml-5': isLinkedPipeline,

View File

@ -41,7 +41,7 @@ export default {
>
<p
v-if="duration"
class="gl-display-inline-flex gl-align-items-center gl-text-secondary gl-m-0 gl-white-space-nowrap"
class="gl-display-inline-flex gl-align-items-center gl-text-secondary gl-m-0 gl-whitespace-nowrap"
data-testid="duration"
>
<gl-icon name="timer" class="gl-mr-2" :size="12" />
@ -50,7 +50,7 @@ export default {
<p
v-if="finishedTime"
class="gl-display-inline-flex gl-align-items-center gl-text-secondary gl-m-0 gl-white-space-nowrap"
class="gl-display-inline-flex gl-align-items-center gl-text-secondary gl-m-0 gl-whitespace-nowrap"
data-testid="finished-at"
>
<gl-icon name="calendar" class="gl-mr-2" :size="12" data-testid="calendar-icon" />

View File

@ -67,7 +67,7 @@ export default {
{
key: 'actions',
label: __('Actions'),
tdClass: 'gl-text-right gl-white-space-nowrap',
tdClass: 'gl-text-right gl-whitespace-nowrap',
thClass: `gl-text-right gl-w-1/20`,
},
],

View File

@ -229,7 +229,7 @@ export default {
:aria-label="linkCanonicalSrc"
:title="linkCanonicalSrc"
target="_blank"
class="gl-px-3 gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis"
class="gl-px-3 gl-overflow-hidden gl-whitespace-nowrap gl-text-overflow-ellipsis"
>
{{ linkCanonicalSrc }}
</gl-link>

View File

@ -247,7 +247,7 @@ export default {
:aria-label="mediaCanonicalSrc"
:title="mediaCanonicalSrc"
target="_blank"
class="gl-px-3 gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis"
class="gl-px-3 gl-overflow-hidden gl-whitespace-nowrap gl-text-overflow-ellipsis"
>
{{ mediaCanonicalSrc }}
</gl-link>

View File

@ -176,7 +176,7 @@ export default {
:tippy-options="$options.tippyOptions"
>
<gl-button-group class="gl-display-flex gl-align-items-center">
<span class="gl-py-2 gl-px-3 gl-text-secondary gl-white-space-nowrap">
<span class="gl-py-2 gl-px-3 gl-text-secondary gl-whitespace-nowrap">
{{ __('Display as:') }}
</span>
<gl-collapsible-listbox

View File

@ -198,7 +198,7 @@ export default {
</div>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-pl-3 gl-gap-2 gl-white-space-nowrap"
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-pl-3 gl-gap-2 gl-whitespace-nowrap"
>
<gl-sprintf :message="__('From line %{line1} to %{line2}')">
<template #line1>

View File

@ -149,7 +149,7 @@ export default {
>
<template #default="{ timeAgo }">
<gl-icon name="calendar" class="gl-mr-2" />
<span class="gl-mr-2 gl-white-space-nowrap">
<span class="gl-mr-2 gl-whitespace-nowrap">
<gl-sprintf :message="timeagoText">
<template #timeago>{{ timeAgo }}</template>
<template #username>

View File

@ -70,7 +70,7 @@ export default {
:avatar-size="24"
badge-tooltip-prop="name"
:badge-sr-only-text="authorCollapsedTooltip"
class="gl-white-space-nowrap gl-mr-3"
class="gl-whitespace-nowrap gl-mr-3"
>
<template #avatar="{ avatar }">
<gl-avatar-link v-gl-tooltip :href="avatar.webUrl" :title="avatar.name">

View File

@ -228,7 +228,7 @@ export default {
>
<template #default="{ timeAgo }">
<gl-icon name="calendar" class="gl-mr-2" />
<span class="gl-mr-2 gl-white-space-nowrap">
<span class="gl-mr-2 gl-whitespace-nowrap">
<gl-sprintf :message="timeStamp">
<template #timeago>{{ timeAgo }}</template>
</gl-sprintf>

View File

@ -43,21 +43,21 @@ export const ENVIRONMENT_DETAILS_TABLE_FIELDS = [
key: 'created',
label: __('Created'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle gl-white-space-nowrap',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
},
{
key: 'deployed',
label: __('Deployed'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle gl-white-space-nowrap',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
},
{
key: 'actions',
label: __('Actions'),
columnClass: 'gl-w-3/20',
tdClass: '!gl-align-middle gl-white-space-nowrap',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
},
];

View File

@ -13,7 +13,7 @@ export default {
{
key: 'relation',
label: __('Type'),
tdClass: 'gl-white-space-nowrap',
tdClass: 'gl-whitespace-nowrap',
},
{
key: 'source_title',

View File

@ -10,7 +10,7 @@ export default {
{
key: 'type',
label: __('Type'),
tdClass: 'gl-white-space-nowrap',
tdClass: 'gl-whitespace-nowrap',
},
{
key: 'title',
@ -20,7 +20,7 @@ export default {
{
key: 'provider_url',
label: __('URL'),
tdClass: 'gl-white-space-nowrap',
tdClass: 'gl-whitespace-nowrap',
},
{
key: 'details',

View File

@ -79,7 +79,7 @@ export default {
</script>
<template>
<div class="gl-white-space-nowrap gl-display-inline-flex gl-align-items-center gl-gap-3">
<div class="gl-whitespace-nowrap gl-display-inline-flex gl-align-items-center gl-gap-3">
<template v-if="isProjectCreationAllowed">
<gl-button-group v-if="showImportActions">
<gl-button

View File

@ -132,7 +132,7 @@ export default {
<template>
<div>
<p class="gl-text-gray-900 gl-white-space-nowrap gl-mt-3">
<p class="gl-text-gray-900 gl-whitespace-nowrap gl-mt-3">
{{ s__('ImportProjects|Select the repositories you want to import') }}
</p>
<template v-if="hasIncompatibleRepos">

View File

@ -211,7 +211,7 @@ export default {
<td data-testid="import-status-indicator">
<import-status :project-id="importedProjectId" :status="importStatus" :stats="stats" />
</td>
<td data-testid="actions" class="gl-white-space-nowrap">
<td data-testid="actions" class="gl-whitespace-nowrap">
<gl-tooltip :target="() => $refs.cancelButton.$el">
<div class="gl-text-left">
<p class="gl-mb-5 gl-font-weight-bold">{{ s__('ImportProjects|Cancel import') }}</p>

View File

@ -112,7 +112,7 @@ export default {
:closed="isIssueClosed"
tooltip-placement="top"
class="gl-mr-4"
css-class="gl-display-flex gl-white-space-nowrap"
css-class="gl-display-flex gl-whitespace-nowrap"
/>
<issue-weight
v-if="issue.weight"

View File

@ -198,7 +198,7 @@ export const TABS = [
},
{
namespace: MEMBER_TYPES.invite,
title: __('Invited'),
title: s__('Members|Pending invitations'),
requiredPermissions: ['canManageMembers'],
queryParamValue: TAB_QUERY_PARAM_VALUES.invite,
},

View File

@ -173,7 +173,7 @@ export default {
<a
v-safe-html:[$options.safeHtmlConfig]="titleHtml"
href="#top"
class="gl-display-none gl-lg-display-block gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0 gl-ml-1 gl-mr-2 gl-text-black-normal"
class="gl-display-none gl-lg-display-block gl-font-weight-bold gl-overflow-hidden gl-whitespace-nowrap gl-text-overflow-ellipsis gl-my-0 gl-ml-1 gl-mr-2 gl-text-black-normal"
></a>
<div class="gl-display-flex gl-align-items-center">
<gl-sprintf :message="__('%{source} %{copyButton} into %{target}')">

View File

@ -151,7 +151,7 @@ export default {
<div
v-gl-tooltip="{ title: tag.name }"
data-testid="name"
class="gl-text-overflow-ellipsis gl-overflow-hidden gl-white-space-nowrap"
class="gl-text-overflow-ellipsis gl-overflow-hidden gl-whitespace-nowrap"
:class="mobileClasses"
>
{{ tag.name }}

View File

@ -49,7 +49,7 @@ export default {
<div class="gl-display-flex gl-align-items-center">
<div
data-testid="name"
class="gl-text-overflow-ellipsis gl-overflow-hidden gl-white-space-nowrap"
class="gl-text-overflow-ellipsis gl-overflow-hidden gl-whitespace-nowrap"
>
{{ tag.name }}
</div>

View File

@ -48,7 +48,7 @@ export default {
<template>
<div
:class="{
'issue-token gl-display-inline-flex gl-align-items-stretch gl-max-w-full gl-line-height-24 gl-white-space-nowrap': isCondensed,
'issue-token gl-display-inline-flex gl-align-items-stretch gl-max-w-full gl-line-height-24 gl-whitespace-nowrap': isCondensed,
'flex-row issuable-info-container': !isCondensed,
}"
>

View File

@ -210,7 +210,7 @@ export default {
<div class="gl-display-flex gl-flex-direction-column">
<span
v-safe-html="highlightedItemName(item)"
class="gl-font-weight-bold gl-white-space-nowrap"
class="gl-font-weight-bold gl-whitespace-nowrap"
data-testid="item-title"
></span>
<span class="gl-font-sm gl-text-gray-700" data-testid="item-namespace">

View File

@ -70,7 +70,7 @@ export default {
class="gl-display-flex gl-align-items-center gl-justify-content-space-between hide-collapsed"
>
<span
class="gl-overflow-hidden gl-text-overflow-ellipsis gl-white-space-nowrap"
class="gl-overflow-hidden gl-text-overflow-ellipsis gl-whitespace-nowrap"
:title="value"
>
<gl-sprintf :message="$options.i18n.templateText">

View File

@ -25,7 +25,7 @@ export default {
<span
class="show-hover-layover-hint gl-opacity-0 gl-justify-content-end gl-align-items-center gl-display-none gl-sm-display-flex"
>
<span class="gl-text-gray-700 gl-white-space-nowrap" data-testid="overlay-message">
<span class="gl-text-gray-700 gl-whitespace-nowrap" data-testid="overlay-message">
<gl-sprintf :message="textMessage">
<template #kbd="{ content }">
<kbd class="gl-font-base gl-pb-3 vertical-align-normalization gl-align-middle">

View File

@ -206,7 +206,7 @@ export default {
</p>
</div>
<p
class="gl-m-0 gl-font-size-h-display gl-font-weight-bold gl-white-space-nowrap"
class="gl-m-0 gl-font-size-h-display gl-font-weight-bold gl-whitespace-nowrap"
data-testid="total-usage"
>
{{ totalUsage }}

View File

@ -64,7 +64,7 @@ export default {
<div>
<div class="gl-display-flex gl-mt-7">
<div class="gl-flex-basis-0 gl-mr-7">
<h4 class="gl-min-width-fit-content gl-white-space-nowrap">
<h4 class="gl-min-width-fit-content gl-whitespace-nowrap">
{{ $options.translations.formLabel }}
</h4>
<gl-sprintf :message="$options.translations.formSubtitle" class="gl-text-gray-500">

View File

@ -108,7 +108,7 @@ export default {
@click="$emit('ciStatusBadgeClick')"
>
<span class="ci-icon-gl-icon-wrapper"><gl-icon :name="icon" /></span
><span v-if="showStatusText" class="gl-mx-2 gl-white-space-nowrap" data-testid="ci-icon-text">{{
><span v-if="showStatusText" class="gl-mx-2 gl-whitespace-nowrap" data-testid="ci-icon-text">{{
status.text
}}</span>
</gl-badge>

View File

@ -127,7 +127,7 @@ export default {
:class="item.name ? 'gl-text-truncate' : 'gl-italic gl-gray-400'"
>{{ item.text }}</span
>
<span class="gl-ml-auto gl-white-space-nowrap" aria-hidden="true">
<span class="gl-ml-auto gl-whitespace-nowrap" aria-hidden="true">
<span class="gl-text-green-600">+{{ item.added }}</span>
<span class="gl-text-red-500">-{{ item.removed }}</span>
</span>

View File

@ -1,5 +1,5 @@
export const tdClass =
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-whitespace-nowrap';
export const bodyTrClass =
'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-cursor-pointer gl-hover-bg-gray-50 gl-hover-border-b-solid';

View File

@ -380,7 +380,7 @@ export default {
</div>
<div
v-if="project.updatedAt"
class="gl-font-sm gl-white-space-nowrap gl-text-secondary gl-mt-3 gl-md-mt-0"
class="gl-font-sm gl-whitespace-nowrap gl-text-secondary gl-mt-3 gl-md-mt-0"
>
<span>{{ $options.i18n.updated }}</span>
<time-ago-tooltip :time="project.updatedAt" />

View File

@ -92,7 +92,7 @@ export default {
>
<div class="issue-sticky-header-text gl-display-flex gl-align-items-baseline gl-mx-auto">
<gl-badge
class="gl-white-space-nowrap gl-mr-3 gl-align-self-center"
class="gl-whitespace-nowrap gl-mr-3 gl-align-self-center"
:variant="badgeVariant"
>
<gl-icon v-if="statusIcon" class="gl-sm-display-none" :name="statusIcon" />
@ -102,12 +102,12 @@ export default {
</gl-badge>
<confidentiality-badge
v-if="issuable.confidential"
class="gl-white-space-nowrap gl-mr-3 gl-align-self-center"
class="gl-whitespace-nowrap gl-mr-3 gl-align-self-center"
:issuable-type="issuable.type"
:workspace-type="workspaceType"
/>
<p
class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0"
class="gl-font-weight-bold gl-overflow-hidden gl-whitespace-nowrap gl-text-overflow-ellipsis gl-my-0"
:title="issuable.title"
>
{{ issuable.title }}

View File

@ -188,7 +188,7 @@ export default {
:avatar-size="16"
badge-tooltip-prop="name"
:badge-sr-only-text="assigneesCollapsedTooltip"
class="gl-white-space-nowrap gl-mr-3"
class="gl-whitespace-nowrap gl-mr-3"
>
<template #avatar="{ avatar }">
<gl-avatar-link v-gl-tooltip :href="avatar.webUrl" :title="avatar.name">

View File

@ -282,7 +282,7 @@ export default {
<template v-else-if="hasParent">
<gl-link
data-testid="work-item-parent-link"
class="gl-link gl-text-gray-900 gl-display-inline-block gl-max-w-full gl-white-space-nowrap gl-text-overflow-ellipsis gl-overflow-hidden"
class="gl-link gl-text-gray-900 gl-display-inline-block gl-max-w-full gl-whitespace-nowrap gl-text-overflow-ellipsis gl-overflow-hidden"
:href="parent.webUrl"
>{{ listboxText }}</gl-link
>

View File

@ -142,7 +142,7 @@ class ProjectsFinder < UnionFinder
public_visibility_levels = Gitlab::VisibilityLevel.levels_for_user(current_user)
!public_visibility_levels.include?(params[:visibility_level].to_i)
public_visibility_levels.exclude?(params[:visibility_level].to_i)
end
def owned_projects?

View File

@ -123,7 +123,7 @@ module ApplicationSettingsHelper
def oauth_providers_checkboxes(form)
button_based_providers.map do |source|
checked = !@application_setting.disabled_oauth_sign_in_sources.include?(source.to_s)
checked = @application_setting.disabled_oauth_sign_in_sources.exclude?(source.to_s)
name = Gitlab::Auth::OAuth::Provider.label_for(source)
form.gitlab_ui_checkbox_component(

View File

@ -80,7 +80,7 @@ module Ci
gl_badge_tag(variant: variant, size: :md, href: path, class: badge_classes, title: title, data: data) do
if show_status_text
content_tag(:span, ci_icon_for_status(status), { class: icon_wrapper_class }) + content_tag(:span, status.label, { class: 'gl-mx-2 gl-white-space-nowrap', data: { testid: 'ci-icon-text' } })
content_tag(:span, ci_icon_for_status(status), { class: icon_wrapper_class }) + content_tag(:span, status.label, { class: 'gl-mx-2 gl-whitespace-nowrap', data: { testid: 'ci-icon-text' } })
else
content_tag(:span, ci_icon_for_status(status), { class: icon_wrapper_class })
end

View File

@ -799,7 +799,7 @@ module ProjectsHelper
def project_allowed_visibility_levels(project)
Gitlab::VisibilityLevel.values.select do |level|
project.visibility_level_allowed?(level) && !restricted_levels.include?(level)
project.visibility_level_allowed?(level) && restricted_levels.exclude?(level)
end
end

View File

@ -96,7 +96,7 @@ module TreeHelper
part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty?
next if parts.count > max_links && !parts.last(2).include?(part)
next if parts.count > max_links && parts.last(2).exclude?(part)
yield(part, part_path)
end

View File

@ -105,7 +105,7 @@ module Integrations
failed_jobs = builds.select do |build|
# Select jobs which doesn't have a successful retry
build[:status] == 'failed' && !succeeded_job_names.include?(build[:name])
build[:status] == 'failed' && succeeded_job_names.exclude?(build[:name])
end
failed_jobs.uniq { |job| job[:name] }.reverse

View File

@ -31,7 +31,7 @@ module Integrations
invalid_attributes = attributes.keys - ATTRIBUTES
if invalid_attributes.present?
raise ArgumentError, "Invalid attributes #{invalid_attributes.inspect}"
elsif !TYPES.include?(self[:type])
elsif TYPES.exclude?(self[:type])
raise ArgumentError, "Invalid type #{self[:type].inspect}"
end
end

View File

@ -347,7 +347,7 @@ class Label < ApplicationRecord
def label_format_reference(format = :id)
raise StandardError, 'Unknown format' unless [:id, :name].include?(format)
if format == :name && !name.include?('"')
if format == :name && name.exclude?('"')
%("#{name}")
else
id

View File

@ -816,7 +816,7 @@ class MergeRequest < ApplicationRecord
def merge_participants
participants = [author]
if auto_merge_enabled? && !participants.include?(merge_user)
if auto_merge_enabled? && participants.exclude?(merge_user)
participants << merge_user
end

View File

@ -278,7 +278,7 @@ class Milestone < ApplicationRecord
raise ArgumentError, _('Cannot refer to a group milestone by an internal id!')
end
if format == :name && !name.include?('"')
if format == :name && name.exclude?('"')
%("#{name}")
else
iid

View File

@ -288,7 +288,7 @@ class TodoService
).distinct_user_ids
end
if users_multiple_todos.present? && !Todo::ACTIONS_MULTIPLE_ALLOWED.include?(attributes.fetch(:action))
if users_multiple_todos.present? && Todo::ACTIONS_MULTIPLE_ALLOWED.exclude?(attributes.fetch(:action))
excluded_user_ids += pending_todos(
users_multiple_todos,
attributes.slice(:project_id, :target_id, :target_type, :commit_id, :discussion, :action)

View File

@ -181,7 +181,7 @@
.gl-display-flex.gl-py-3
.gl-mr-auto.gl-overflow-hidden.gl-text-overflow-ellipsis
= link_to project.full_name, admin_project_path(project)
%span.gl-white-space-nowrap.gl-text-right
%span.gl-whitespace-nowrap.gl-text-right
#{time_ago_with_tooltip(project.created_at)}
.col-md-4.gl-mb-6
= render Pajamas::CardComponent.new do |c|
@ -192,7 +192,7 @@
.gl-mr-auto.gl-overflow-hidden.gl-text-overflow-ellipsis
= link_to [:admin, user] do
= user.name
%span.gl-white-space-nowrap.gl-text-right
%span.gl-whitespace-nowrap.gl-text-right
#{time_ago_with_tooltip(user.created_at)}
.col-md-4.gl-mb-6
= render Pajamas::CardComponent.new do |c|
@ -203,5 +203,5 @@
.gl-mr-auto.gl-overflow-hidden.gl-text-overflow-ellipsis
= link_to [:admin, group] do
= group.full_name
%span.gl-white-space-nowrap.gl-text-right
%span.gl-whitespace-nowrap.gl-text-right
#{time_ago_with_tooltip(group.created_at)}

View File

@ -49,7 +49,7 @@
= render_if_exists "dashboard/todos/review_summary", local_assigns: { todo: todo }
.todo-timestamp.gl-white-space-nowrap.gl-sm-ml-3.gl-mt-2.gl-mb-2.gl-sm-my-0.gl-px-2.gl-sm-px-0
.todo-timestamp.gl-whitespace-nowrap.gl-sm-ml-3.gl-mt-2.gl-mb-2.gl-sm-my-0.gl-px-2.gl-sm-px-0
%span.todo-timestamp.gl-font-sm.gl-text-secondary
= todo_due_date(todo)
#{time_ago_with_tooltip(todo.created_at)}

View File

@ -3,5 +3,5 @@
- if current_user
- unless has_label
%span.gl-float-left.gl-white-space-nowrap= _("Visibility:")
%span.gl-float-left.gl-whitespace-nowrap= _("Visibility:")
= gl_redirect_listbox_tag(projects_filter_items, selected, class: 'gl-ml-3', data: { placement: 'right' })

View File

@ -9,7 +9,7 @@
.tree-ref-holder.gl-mb-3.gl-sm-mb-0.gl-max-w-26
#js-blob-ref-switcher{ data: { project_id: @project.id, ref: @ref, ref_type: @ref_type, namespace: "/-/find_file" } }
%ul.breadcrumb.repo-breadcrumb.gl-flex-nowrap
%li.breadcrumb-item.gl-white-space-nowrap
%li.breadcrumb-item.gl-whitespace-nowrap
= link_to project_tree_path(@project, @ref, ref_type: @ref_type) do
= @project.path
%li.file-finder.breadcrumb-item

View File

@ -14,7 +14,7 @@
- if label.description.present?
.gl-my-1
= markdown_field(label, :description)
%ul.label-links.gl-m-0.gl-p-0.gl-white-space-nowrap
%ul.label-links.gl-m-0.gl-p-0.gl-whitespace-nowrap
- if label.lock_on_merge
%li.inline.gl-mr-3.gl-mt-1
.label-badge.gl-bg-orange-50= _('Lock on merge')

View File

@ -8,4 +8,4 @@
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil, data: { meta: '' }
= dropdown_tag(users_dropdown_label(issuable.assignees), options: assignees_dropdown_options(issuable.to_ability_name))
= link_to _('Assign to me'), '#', class: "assign-to-me-link gl-white-space-nowrap gl-md-pl-3 #{'hide' if issuable.assignees.include?(current_user)}", data: { testid: 'assign-to-me-link' }
= link_to _('Assign to me'), '#', class: "assign-to-me-link gl-whitespace-nowrap gl-md-pl-3 #{'hide' if issuable.assignees.include?(current_user)}", data: { testid: 'assign-to-me-link' }

View File

@ -4,11 +4,11 @@
%div
.issuable-form-select-holder
= f.gitlab_ui_datepicker :start_date, data: { testid: "start-date-field" }, placeholder: _('Select start date'), autocomplete: 'off'
%a.gl-white-space-nowrap.gl-pl-4.js-clear-start-date{ href: "#" }= _('Clear start date')
%a.gl-whitespace-nowrap.gl-pl-4.js-clear-start-date{ href: "#" }= _('Clear start date')
.gl-form-group
%div
= f.label :due_date, _('Due Date')
%div
.issuable-form-select-holder
= f.gitlab_ui_datepicker :due_date, data: { testid: "due-date-field" }, placeholder: _('Select due date'), autocomplete: 'off'
%a.gl-white-space-nowrap.gl-pl-4.js-clear-due-date{ href: "#" }= _('Clear due date')
%a.gl-whitespace-nowrap.gl-pl-4.js-clear-due-date{ href: "#" }= _('Clear due date')

View File

@ -5,7 +5,7 @@
- c.with_header do
.gl-flex-grow-2
= title
.gl-ml-3.gl-flex-shrink-0.gl-font-weight-bold.gl-white-space-nowrap{ class: milestone_counter_class(primary) }
.gl-ml-3.gl-flex-shrink-0.gl-font-weight-bold.gl-whitespace-nowrap{ class: milestone_counter_class(primary) }
- if show_counter
%span
= sprite_icon('issues', css_class: 'gl-vertical-align-text-bottom')

View File

@ -163,7 +163,7 @@
.block.reference
= clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport', class: 'sidebar-collapsed-icon js-dont-change-state')
.gl-display-flex.gl-align-items-center.gl-justify-content-space-between.gl-mb-2.hide-collapsed
%span.gl-overflow-hidden.gl-text-overflow-ellipsis.gl-white-space-nowrap
%span.gl-overflow-hidden.gl-text-overflow-ellipsis.gl-whitespace-nowrap
= s_('MilestoneSidebar|Reference:')
%span{ title: milestone_ref }
= milestone_ref

View File

@ -114,7 +114,7 @@
= sprite_icon('issues', size: 14, css_class: 'gl-mr-2')
= badge_count(project.open_issues_count)
= render_if_exists 'shared/projects/actions', project: project
.updated-note.gl-font-sm.gl-white-space-nowrap.gl-justify-content-end
.updated-note.gl-font-sm.gl-whitespace-nowrap.gl-justify-content-end
%span
= _('Updated')
= updated_tooltip

View File

@ -85,7 +85,7 @@
= render 'ci/status/icon', status: last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
= render_if_exists 'shared/projects/badges', project: project
.updated-note.gl-font-sm.gl-white-space-nowrap.gl-justify-content-start
.updated-note.gl-font-sm.gl-whitespace-nowrap.gl-justify-content-start
%span
= _('Updated')
= updated_tooltip

View File

@ -34,4 +34,4 @@
= snippet_file_count(snippet)
%span.has-tooltip{ title: visibility_level_label(snippet.visibility_level), data: { testid: 'snippet-visibility-content', qa_snippet_visibility: visibility_level_label(snippet.visibility_level) } }
= visibility_level_icon(snippet.visibility_level)
.gl-white-space-nowrap.gl-font-sm.gl-text-secondary= _('updated %{timeAgo}').html_safe % { timeAgo: time_ago_with_tooltip(snippet.updated_at, placement: 'bottom') }
.gl-whitespace-nowrap.gl-font-sm.gl-text-secondary= _('updated %{timeAgo}').html_safe % { timeAgo: time_ago_with_tooltip(snippet.updated_at, placement: 'bottom') }

View File

@ -577,7 +577,7 @@ module Gitlab
LOOSE_APP_ASSETS = lambda do |logical_path, filename|
filename.start_with?(*asset_roots) &&
!['.js', '.css', '.md', '.vue', '.graphql', ''].include?(File.extname(logical_path))
['.js', '.css', '.md', '.vue', '.graphql', ''].exclude?(File.extname(logical_path))
end
app.config.assets.precompile << LOOSE_APP_ASSETS

View File

@ -25,6 +25,7 @@
- build_artifacts
- capacity_planning
- cell
- ci_scaling
- cloud_connector
- cloud_native_installation
- code_quality

View File

@ -1059,7 +1059,7 @@ Gitlab.ee do
Settings.kerberos['https'] = Settings.gitlab.https if Settings.kerberos['https'].nil?
Settings.kerberos['port'] ||= Settings.kerberos.https ? 8443 : 8088
if Settings.kerberos['enabled'] && !Settings.omniauth.providers.map(&:name).include?('kerberos')
if Settings.kerberos['enabled'] && Settings.omniauth.providers.map(&:name).exclude?('kerberos')
Settings.omniauth.providers << GitlabSettings::Options.build({ 'name' => 'kerberos' })
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class RemoveCreateEmptyEmbeddingsRecordsWorker < Gitlab::Database::Migration[2.2]
milestone '17.0'
disable_ddl_transaction!
def up
# This is to clean up the cron schedule for Llm::Embedding::GitlabDocumentation::CreateEmptyEmbeddingsRecordsWorker
# which was removed in
# https://gitlab.com/gitlab-org/gitlab/-/issues/438337
# TODO: make shard-aware. See https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/3430
Gitlab::SidekiqSharding::Validator.allow_unrouted_sidekiq_calls do
removed_job = Sidekiq::Cron::Job.find('llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker')
removed_job.destroy if removed_job
end
end
def down
# This is to remove the cron schedule for a deleted job, so there is no
# meaningful way to reverse it.
end
end

View File

@ -0,0 +1 @@
bc9dbe0d22d8988934d2b8af1c89295bb190e6995278b8864f327ba3fba84ae5

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation for the Code Intelligence feature."
---
# Code intelligence development guidelines

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation for extending the merge request report widget with additional features."
---
# Merge request widget extensions

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation explaining the design and workflow of merge request approval rules."
---
# Approval rules development guidelines

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation for the backend design and flow of merge request diffs."
---
# Merge request diffs development guide

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation explaining how the different parts of the Vue-based frontend diffs are generated."
---
# Merge request diffs frontend overview

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer documentation for how diffs are generated and rendered in GitLab."
---
# Working with diffs

View File

@ -1,7 +1,8 @@
---
stage: Create
group: Code Review
info: "See the Technical Writers assigned to Development Guidelines: https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-development-guidelines"
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer information explaining terminology and features used in merge requests."
---
# Merge request concepts

View File

@ -1,7 +1,8 @@
---
stage: Create
group: Code Review
info: Detailing the process to add a new mergeability check
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
description: "Developer information explaining the process to add a new mergeability check"
---
# Mergeability framework

View File

@ -38,17 +38,9 @@ Like default roles, custom roles are [inherited](../../user/project/members/inde
- A custom role can enable additional abilities for a `base_access_level` but it cannot disable a permission. As a result, custom roles are "additive only". The rationale for this choice is [in this comment](https://gitlab.com/gitlab-org/gitlab/-/issues/352891#note_1059561579).
- Custom role abilities are supported at project level and group level.
## How to implement a new ability for custom roles
## Refactoring abilities
Usually 2-3 merge requests should be created for a new ability. The rough guidance is following:
1. Pick a feature you want to add abilities to custom roles.
1. Refactor & consolidate abilities for the feature (1-2 merge requests depending on the feature complexity)
1. Implement a new ability (1 merge request)
### Refactoring abilities
#### Finding existing abilities checks
### Finding existing abilities checks
Abilities are often [checked in multiple locations](../permissions/authorizations.md#where-should-permissions-be-checked) for a single endpoint or web request. Therefore, it can be difficult to find the list of authorization checks that are run for a given endpoint.
@ -75,7 +67,7 @@ POLICY CHECK DEBUG -> policy: GlobalPolicy, ability: create_group, called_from:
Use this setting to learn more about authorization checks while
refactoring. You should not keep this setting enabled for any specs on the default branch.
#### Understanding logic for individual abilities
### Understanding logic for individual abilities
References to an ability may appear in a `DeclarativePolicy` class many times
and depend on conditions and rules which reference other abilities. As a result,
@ -147,7 +139,7 @@ policy.debug(:read_group)
@prevented=true>
```
#### Abilities consolidation
### Abilities consolidation
Every feature added to custom roles should have minimal abilities. For most features, having `read_*` and `admin_*` should be enough. You should consolidate all:
@ -173,9 +165,12 @@ the parent group will allow the custom role to access the group security dashboa
for each project in that group. Enabling the same permission on a specific project will allow access to that projects'
security dashboard.
### Implement a new ability
## How to add support for an ability to custom roles
#### Step 1. Generate a configuration file
If adding an existing ability, consider [refactoring & consolidating abilities for the feature](#refactoring-abilities)
before in a separate merge request, before completing the below.
### Step 1. Generate a configuration file
- Run `./ee/bin/custom-ability <ABILITY_NAME>` to generate a configuration file for the new ability.
- This will generate a YAML file in `ee/config/custom_abilities` which follows the following schema:
@ -191,13 +186,13 @@ security dashboard.
| `group_ability` | yes | Boolean value to indicate whether this ability is checked on group level. |
| `project_ability` | yes | Boolean value to whether this ability is checked on project level. |
| `requirements` | no | The list of custom permissions this ability is dependent on. For instance `admin_vulnerability` is dependent on `read_vulnerability`. If none, then enter `[]` |
| `available_from_access_level` | no | The access level from which this ability is available, if applicable. See the section on [understanding logic for individual abilities](#understanding-logic-for-individual-abilities) for help on determining the base access level for an ability. |
| `available_from_access_level` | no | The access level of the predefined role from which this ability is available, if applicable. See the section on [understanding logic for individual abilities](#understanding-logic-for-individual-abilities) for help on determining the base access level for an ability. This is for information only and has no impact on how custom roles operate. |
#### Step 2: Create a spec file and update validation schema
### Step 2: Create a spec file and update validation schema
- Run `bundle exec rails generate gitlab:custom_roles:code --ability <ABILITY_NAME>` which will update the permissions validation schema file and create an empty spec file.
#### Step 3: Update policies
### Step 3: Update policies
- If the ability is checked on a group level, add rule(s) to GroupPolicy to enable the ability.
- For example: if the ability we would like to add is `read_dependency`, then an update to `ee/app/policies/ee/group_policy.rb` would look like as follows:
@ -237,7 +232,7 @@ end
- Not all abilities need to be enabled on both levels, for instance `admin_terraform_state` allows users to manage a project's terraform state. It only needs to be enabled on the project level and not the group level, and thus only needs to be configured in `ee/app/policies/ee/project_policy.rb`.
#### Step 4: Verify
### Step 4: Verify
- Ensure SaaS mode is enabled with `GITLAB_SIMULATE_SAAS=1`.
- Go to any Group that you are an owner of, then go to `Settings -> Roles and Permissions`.
@ -245,7 +240,7 @@ end
- Go to the Group's `Manage -> Members` page and assign a member to this newly created custom role.
- Next, log-in as that member and ensure that you are able to access the page that the custom ability is intended for.
#### Step 5: Add specs
### Step 5: Add specs
- Add the ability as a trait in the `MemberRoles` factory, `ee/spec/factories/member_roles.rb`.
- Add tests to `ee/spec/requests/custom_roles/<ABILITY_NAME>/request_spec.rb` to ensure that once the user has been assigned the custom ability, they can successfully access the controllers, REST API endpoints and GraphQL API endpoints.
@ -311,7 +306,7 @@ end
end
```
#### Step 6: Update documentation
### Step 6: Update documentation
- Update the list of custom abilities by running `bundle exec rake gitlab:custom_roles:compile_docs`
- Update the GraphQL documentation by running `bundle exec rake gitlab:graphql:compile_docs`

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Use AI-assisted features for relevant information about a merge request."
---
# GitLab Duo in merge requests

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "When you fork a merge request, you can set whether or not members of the upstream repository can contribute to your fork."
---
# Collaborate on merge requests across forks

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "The most common merge request flows in GitLab use forks, protected branches, or both."
---
# Merge request workflows

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Understand how to read the changes proposed in a merge request."
---
# Changes in merge requests

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Understand how to read the display of commits in a merge request."
---
# Merge request commits

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "How to create a merge request for a confidential issue without leaking information publicly."
---
# Merge requests for confidential issues

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Set a merge request dependency to control the merge order of merge requests with related or dependent content."
---
# Merge request dependencies

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Prevent an incomplete merge request from merging until it's ready by setting it as a draft."
---
# Draft merge requests

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Troubleshooting help for merge requests."
---
# Merge request troubleshooting

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Use diff versions to compare pushes contained in a single merge request."
---
# Merge request diff versions

View File

@ -2,6 +2,7 @@
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: "Merge requests show the results of CI/CD pipelines and mergeability tests in a reports area."
---
# Merge request widgets

View File

@ -31851,6 +31851,9 @@ msgstr ""
msgid "Members|Membership"
msgstr ""
msgid "Members|Pending invitations"
msgstr ""
msgid "Members|Private group information is only accessible to its members."
msgstr ""

View File

@ -11,9 +11,9 @@ RSpec.describe 'Groups > Members > Tabs', :js, feature_category: :groups_and_pro
end
end
shared_examples 'active "Invited" tab' do
it 'displays "Invited" tab' do
expect(page).to have_selector('.nav-link.active', text: 'Invited')
shared_examples 'active "Pending invitations" tab' do
it 'displays "Pending invitations" tab' do
expect(page).to have_selector('.nav-link.active', text: 'Pending invitations')
end
end
@ -34,10 +34,10 @@ RSpec.describe 'Groups > Members > Tabs', :js, feature_category: :groups_and_pro
end
where(:tab, :count) do
'Members' | 3
'Invited' | 2
'Groups' | 2
'Access requests' | 2
'Members' | 3
'Pending invitations' | 2
'Groups' | 2
'Access requests' | 2
end
with_them do
@ -56,11 +56,11 @@ RSpec.describe 'Groups > Members > Tabs', :js, feature_category: :groups_and_pro
it_behaves_like 'active "Members" tab'
end
context 'when searching "Invited"' do
context 'when searching "Pending invitations"' do
before do
visit group_group_members_path(group)
click_link 'Invited'
click_link 'Pending invitations'
within_testid('members-filtered-search-bar') do
find_field('Search invited').click
@ -69,7 +69,7 @@ RSpec.describe 'Groups > Members > Tabs', :js, feature_category: :groups_and_pro
end
end
it_behaves_like 'active "Invited" tab'
it_behaves_like 'active "Pending invitations" tab'
context 'and then searching "Members"' do
before do
@ -86,18 +86,18 @@ RSpec.describe 'Groups > Members > Tabs', :js, feature_category: :groups_and_pro
end
end
context 'when using "Invited" pagination' do
context 'when using "Pending invitations" pagination' do
before do
visit group_group_members_path(group)
click_link 'Invited'
click_link 'Pending invitations'
page.within '.pagination' do
click_link '2'
end
end
it_behaves_like 'active "Invited" tab'
it_behaves_like 'active "Pending invitations" tab'
context 'and then using "Members" pagination' do
before do

View File

@ -76,7 +76,7 @@ RSpec.describe 'Projects members', :js, feature_category: :groups_and_projects d
end
it 'shows the project invitee' do
click_link 'Invited'
click_link 'Pending invitations'
expect(members_table).to have_content('test1@abc.com')
expect(members_table).not_to have_content('test2@abc.com')

View File

@ -27,10 +27,10 @@ RSpec.describe 'Projects > Members > Tabs', :js, feature_category: :groups_and_p
context 'tabs' do
where(:tab, :count) do
'Members' | 3
'Invited' | 2
'Groups' | 2
'Access requests' | 2
'Members' | 3
'Pending invitations' | 2
'Groups' | 2
'Access requests' | 2
end
with_them do

View File

@ -122,7 +122,7 @@ describe('MembersTabs', () => {
expect(tabs[0].text()).toBe('Members 10');
expect(tabs[1].text()).toBe('Groups 10');
expect(tabs[2].text()).toBe('Invited 10');
expect(tabs[2].text()).toBe('Pending invitations 10');
expect(tabs[3].text()).toBe('Access requests 10');
expect(findActiveTab().text()).toContain('Members');
});
@ -149,7 +149,7 @@ describe('MembersTabs', () => {
expect(findTabByText('Members')).not.toBeUndefined();
expect(findTabByText('Groups')).toBeUndefined();
expect(findTabByText('Invited')).toBeUndefined();
expect(findTabByText('Pending invitations')).toBeUndefined();
expect(findTabByText('Access requests')).toBeUndefined();
});
@ -179,14 +179,14 @@ describe('MembersTabs', () => {
});
describe('when `canManageMembers` is `false`', () => {
it('shows all tabs except `Invited` and `Access requests`', async () => {
it('shows all tabs except `Pending invitations` and `Access requests`', async () => {
await createComponent({
provide: { canManageMembers: false, canManageAccessRequests: false },
});
expect(findTabByText('Members')).not.toBeUndefined();
expect(findTabByText('Groups')).not.toBeUndefined();
expect(findTabByText('Invited')).toBeUndefined();
expect(findTabByText('Pending invitations')).toBeUndefined();
expect(findTabByText('Access requests')).toBeUndefined();
});
});

View File

@ -0,0 +1,58 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe RemoveCreateEmptyEmbeddingsRecordsWorker, :migration, feature_category: :scalability do
let(:hash_name) { 'cron_job:llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker' }
let(:zset_name) { 'cron_job:llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker:enqueued' }
let(:job_message) do
{ "retry" => 3,
"queue" => "default",
"version" => 0,
"queue_namespace" => "cronjob",
"class" => "Llm::Embedding::GitlabDocumentation::CreateEmptyEmbeddingsRecordsWorker",
"args" => [] }
end
let(:cron_args) do
[
"symbolize_args", "0", "date_as_argument", "false",
"name", "llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker",
"queue_name_prefix", "",
"cron", "0 5 * * 1,2,3,4,5",
"last_enqueue_time", "2024-04-30,05:00:01,+0000",
"status", "enabled",
"klass", "Llm::Embedding::GitlabDocumentation::CreateEmptyEmbeddingsRecordsWorker",
"message", Sidekiq.dump_json(job_message)
]
end
context 'when cron job exists' do
before do
Gitlab::Redis::Queues.with do |redis|
redis.hset(hash_name, *cron_args)
redis.zadd(zset_name, 1714626000, "2024-05-02T05:00:00Z")
end
end
after do
Gitlab::Redis::Queues.with(&:flushdb)
end
it "deletes the cron job and enqueued jobs" do
migrate!
Gitlab::Redis::Queues.with do |redis|
expect(redis.exists(hash_name)).to eq(0)
expect(redis.exists(zset_name)).to eq(0)
end
end
end
context 'when cron job does not exist' do
it "no-ops" do
expect { migrate! }.not_to raise_error
end
end
end

View File

@ -44,7 +44,7 @@ RSpec.shared_examples 'inviting members' do |snowplow_invite_label|
invite_member('test@example.com', role: 'Reporter')
click_link 'Invited'
click_link 'Pending invitations'
page.within find_invited_member_row('test@example.com') do
expect(page).to have_button('Reporter')
@ -68,7 +68,7 @@ RSpec.shared_examples 'inviting members' do |snowplow_invite_label|
expect(page).to have_button('Reporter')
end
click_link 'Invited'
click_link 'Pending invitations'
page.within find_invited_member_row('test@example.com') do
expect(page).to have_button('Reporter')
@ -107,7 +107,7 @@ RSpec.shared_examples 'inviting members' do |snowplow_invite_label|
page.refresh
click_link 'Invited'
click_link 'Pending invitations'
page.within find_invited_member_row(email) do
expect(page).to have_button('Reporter')