Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-04-30 15:11:09 +00:00
parent 1bf756371d
commit 35305bfc83
61 changed files with 333 additions and 204 deletions

View File

@ -1,4 +1,3 @@
import Vue from 'vue';
import * as types from './mutation_types';
export default {
@ -12,19 +11,18 @@ export default {
state.groupMilestonesAvailable = groupMilestonesAvailable;
},
[types.SET_SELECTED_MILESTONES](state, selectedMilestones) {
Vue.set(state, 'selectedMilestones', selectedMilestones);
state.selectedMilestones = selectedMilestones;
},
[types.CLEAR_SELECTED_MILESTONES](state) {
Vue.set(state, 'selectedMilestones', []);
state.selectedMilestones = [];
},
[types.ADD_SELECTED_MILESTONE](state, selectedMilestone) {
state.selectedMilestones.push(selectedMilestone);
},
[types.REMOVE_SELECTED_MILESTONE](state, selectedMilestone) {
const filteredMilestones = state.selectedMilestones.filter(
state.selectedMilestones = state.selectedMilestones.filter(
(milestone) => milestone !== selectedMilestone,
);
Vue.set(state, 'selectedMilestones', filteredMilestones);
},
[types.SET_SEARCH_QUERY](state, searchQuery) {
state.searchQuery = searchQuery;

View File

@ -68,7 +68,7 @@ export default {
></div>
<noteable-warning
v-if="hasWarning"
class="gl-pt-4 gl-pb-5 gl-mb-n3 gl-rounded-lg gl-rounded-bottom-left-none gl-rounded-bottom-right-none"
class="gl-pt-4 gl-pb-5 -gl-mb-3 gl-rounded-lg gl-rounded-bottom-left-none gl-rounded-bottom-right-none"
:is-locked="isLocked"
:is-confidential="isConfidential"
:noteable-type="noteableType"
@ -80,14 +80,14 @@ export default {
v-if="showAttachmentWarning"
:class="{
'gl-py-3': !showEmailParticipantsWarning,
'gl-pt-4 gl-pb-3 gl-mt-n3': showEmailParticipantsWarning,
'gl-pt-4 gl-pb-3 -gl-mt-3': showEmailParticipantsWarning,
}"
/>
<email-participants-warning
v-if="showEmailParticipantsWarning"
class="gl-border-t-1 gl-rounded-lg gl-rounded-top-left-none! gl-rounded-top-right-none!"
:class="{
'gl-pt-4 gl-pb-3 gl-mt-n3': !showAttachmentWarning,
'gl-pt-4 gl-pb-3 -gl-mt-3': !showAttachmentWarning,
'gl-py-3 gl-mt-1': showAttachmentWarning,
}"
:emails="emailParticipants"

View File

@ -29,7 +29,7 @@ export default {
data-testid="discussion-filter-container"
>
<div
class="gl-float-left gl--flex-center gl-rounded-full gl-mt-n1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
class="gl-float-left gl--flex-center gl-rounded-full -gl-mt-1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
>
<gl-icon name="comment" />
</div>

View File

@ -399,7 +399,7 @@ export default {
</template>
<template v-if="showBatchCommentsActions">
<div class="gl-display-flex gl-flex-wrap gl-mb-n3">
<div class="gl-display-flex gl-flex-wrap -gl-mb-3">
<gl-button
:disabled="isDisabled"
category="primary"

View File

@ -294,7 +294,7 @@ export default {
:issuable-type="issuableType"
:is-editing="edit"
:issuable-author="issuableAuthor"
class="gl-w-full dropdown-menu-user gl-mt-n3"
class="gl-w-full dropdown-menu-user -gl-mt-3"
@toggle="collapseWidget"
@error="showError"
@input="setDirtyState"

View File

@ -96,7 +96,7 @@ export default {
<div class="color-input-container gl-display-flex">
<gl-form-input
v-model.trim="selectedColor"
class="gl-rounded-top-right-none gl-rounded-bottom-right-none gl-mr-n1 gl-mb-2 gl-w-8"
class="gl-rounded-top-right-none gl-rounded-bottom-right-none -gl-mr-1 gl-mb-2 gl-w-8"
type="color"
:value="selectedColor"
:placeholder="__('Open color picker')"

View File

@ -36,7 +36,7 @@ export default {
<gl-button
category="tertiary"
size="small"
class="gl-float-right js-sidebar-dropdown-toggle gl-mr-n2"
class="gl-float-right js-sidebar-dropdown-toggle -gl-mr-2"
@click="toggleDropdownContents"
>
{{ __('Edit') }}

View File

@ -82,7 +82,7 @@ export default {
<gl-form-group class="gl-mb-0!">
<gl-form-input
v-model.trim="selectedColor"
class="gl-mr-n1 gl-mb-2 gl-w-8"
class="-gl-mr-1 gl-mb-2 gl-w-8"
type="color"
:value="selectedColor"
:placeholder="__('Select color')"

View File

@ -180,7 +180,7 @@ export default {
v-gl-tooltip.viewport.html
category="tertiary"
size="small"
class="gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2 shortcut-sidebar-dropdown-toggle"
class="gl-text-gray-900! gl-ml-auto hide-collapsed -gl-mr-2 shortcut-sidebar-dropdown-toggle"
:title="editTooltipText"
:aria-label="editAriaLabelText"
:aria-keyshortcuts="editKeyshortcutsText"

View File

@ -11,6 +11,7 @@ import {
TOP_NAV_INVITE_MEMBERS_COMPONENT,
TRIGGER_ELEMENT_DISCLOSURE_DROPDOWN,
} from '~/invite_members/constants';
import { WORK_ITEM_TYPE_ENUM_EPIC, CREATE_NEW_WORK_ITEM_MODAL } from '~/work_items/constants';
import { DROPDOWN_Y_OFFSET, IMPERSONATING_OFFSET } from '../constants';
// Left offset required for the dropdown to be aligned with the super sidebar
@ -23,6 +24,7 @@ export default {
GlDisclosureDropdownGroup,
GlDisclosureDropdownItem,
InviteMembersTrigger,
CreateWorkItemModal: () => import('~/work_items/components/create_work_item_modal.vue'),
},
directives: {
GlTooltip: GlTooltipDirective,
@ -54,9 +56,13 @@ export default {
isInvitedMembers(groupItem) {
return groupItem.component === TOP_NAV_INVITE_MEMBERS_COMPONENT;
},
isCreateWorkItem(groupItem) {
return groupItem.component === CREATE_NEW_WORK_ITEM_MODAL;
},
},
toggleId: 'create-menu-toggle',
TRIGGER_ELEMENT_DISCLOSURE_DROPDOWN,
WORK_ITEM_TYPE_ENUM_EPIC,
};
</script>
@ -87,6 +93,12 @@ export default {
trigger-source="top_nav"
:trigger-element="$options.TRIGGER_ELEMENT_DISCLOSURE_DROPDOWN"
/>
<create-work-item-modal
v-else-if="isCreateWorkItem(groupItem)"
:key="`${groupItem.text}-modal-trigger`"
as-dropdown-item
:work-item-type="$options.WORK_ITEM_TYPE_ENUM_EPIC"
/>
<gl-disclosure-dropdown-item v-else :key="groupItem.text" :item="groupItem" />
</template>
</gl-disclosure-dropdown-group>

View File

@ -71,3 +71,5 @@ export const FIFTEEN_MINUTES_IN_MS = 900000;
export const STORAGE_KEY = {
projects: 'frequent-projects',
};
export const CONTEXT_NAMESPACE_GROUPS = 'groups';

View File

@ -3,7 +3,7 @@ import { GlToast } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
import createDefaultClient from '~/lib/graphql';
import { JS_TOGGLE_EXPAND_CLASS } from './constants';
import { JS_TOGGLE_EXPAND_CLASS, CONTEXT_NAMESPACE_GROUPS } from './constants';
import createStore from './components/global_search/store';
import {
bindSuperSidebarCollapsedEvents,
@ -104,6 +104,8 @@ export const initSuperSidebar = () => {
const { searchPath, issuesPath, mrPath, autocompletePath, searchContext } = searchData;
const isImpersonating = parseBoolean(sidebarData.is_impersonating);
const isGroup = Boolean(sidebarData.current_context?.namespace === CONTEXT_NAMESPACE_GROUPS);
return new Vue({
el,
name: 'SuperSidebarRoot',
@ -121,6 +123,8 @@ export const initSuperSidebar = () => {
projectBlobPath,
projectsPath,
groupsPath,
fullPath: sidebarData.work_items?.full_path,
isGroup,
},
store: createStore({
searchPath,

View File

@ -40,7 +40,7 @@ export default {
>
<div class="gl-display-inline-flex gl-align-items-center gl-relative">
<div
class="gl-display-inline gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-box-sizing-content-box gl-p-3 gl-mt-n2 gl-mr-6"
class="gl-display-inline gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-box-sizing-content-box gl-p-3 -gl-mt-2 gl-mr-6"
>
<gl-icon :name="note.systemNoteIconName" />
</div>

View File

@ -14,7 +14,7 @@ export default {
<template>
<timeline-entry-item class="note note-wrapper">
<div
class="gl-float-left gl--flex-center gl-rounded-full gl-mt-n1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
class="gl-float-left gl--flex-center gl-rounded-full -gl-mt-1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
></div>
<div class="timeline-content">
<div class="note-header"></div>

View File

@ -1,6 +1,6 @@
<template>
<div
class="gl-float-left gl--flex-center gl-rounded-full gl-mt-n1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
class="gl-float-left gl--flex-center gl-rounded-full -gl-mt-1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
>
<slot></slot>
</div>

View File

@ -20,7 +20,7 @@ export default {
<template>
<timeline-entry-item class="system-note note-wrapper">
<div
class="gl--flex-center gl-rounded-full gl-mt-n1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600 gl-float-left"
class="gl--flex-center gl-rounded-full -gl-mt-1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600 gl-float-left"
>
<gl-icon :name="icon" />
</div>

View File

@ -107,7 +107,7 @@ export default {
class="gl-py-5 gl-pl-8"
:class="{ 'gl-border-b': borderBottom(idx) }"
>
<div class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold">
<div class="-gl-mt-1 gl-pl-4 gl-pb-2 gl-font-weight-bold">
{{ easyButton.description }}
<gl-accordion :header-level="3" class="gl-pt-3">
<gl-accordion-item

View File

@ -1,5 +1,5 @@
<script>
import { GlButton, GlModal } from '@gitlab/ui';
import { GlButton, GlModal, GlDisclosureDropdownItem } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
import { I18N_NEW_WORK_ITEM_BUTTON_LABEL, sprintfWorkItem } from '../constants';
import CreateWorkItem from './create_work_item.vue';
@ -9,6 +9,7 @@ export default {
CreateWorkItem,
GlButton,
GlModal,
GlDisclosureDropdownItem,
},
props: {
workItemType: {
@ -16,6 +17,11 @@ export default {
required: false,
default: null,
},
asDropdownItem: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
@ -26,6 +32,12 @@ export default {
newWorkItemText() {
return sprintfWorkItem(I18N_NEW_WORK_ITEM_BUTTON_LABEL, this.workItemType);
},
dropdownItem() {
return {
text: this.newWorkItemText,
action: this.showModal,
};
},
},
methods: {
hideModal() {
@ -43,7 +55,9 @@ export default {
<template>
<div>
<gl-disclosure-dropdown-item v-if="asDropdownItem" :item="dropdownItem" />
<gl-button
v-else
category="primary"
variant="confirm"
data-testid="new-epic-button"

View File

@ -65,7 +65,7 @@ export default {
:aria-label="__('Title')"
:data-placeholder="placeholder"
:contenteditable="!disabled"
class="hide-unfocused-input-decoration gl-px-4 gl-py-3 gl-ml-n4 gl-border gl-rounded-base gl-display-block"
class="hide-unfocused-input-decoration gl-px-4 gl-py-3 -gl-ml-4 gl-border gl-rounded-base gl-display-block"
:class="{ 'gl-hover-border-gray-200 gl-pseudo-placeholder': !disabled }"
@paste="handlePaste"
@blur="handleBlur"

View File

@ -31,7 +31,7 @@ export default {
<template>
<li class="timeline-entry note note-wrapper discussion-filter-note">
<div
class="gl-float-left gl--flex-center gl-rounded-full gl-mt-n1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
class="gl-float-left gl--flex-center gl-rounded-full -gl-mt-1 gl-ml-2 gl-w-6 gl-h-6 gl-bg-gray-50 gl-text-gray-600"
>
<gl-icon name="comment" />
</div>

View File

@ -236,7 +236,7 @@ export default {
<div v-if="canUpdate">
<gl-button
v-gl-tooltip
class="gl-mt-n2 gl-mr-n2"
class="-gl-mt-2 -gl-mr-2"
category="tertiary"
size="small"
icon="close"

View File

@ -355,7 +355,7 @@ export default {
:title="token.name"
:data-user-id="getUserId(token.id)"
data-placement="top"
class="gl-ml-n2 gl-text-decoration-none! gl-text-body! gl-display-flex gl-md-display-inline-flex! gl-align-items-center js-user-link"
class="-gl-ml-2 gl-text-decoration-none! gl-text-body! gl-display-flex gl-md-display-inline-flex! gl-align-items-center js-user-link"
>
<gl-avatar :size="24" :src="token.avatarUrl" />
<span class="gl-pl-2">{{ token.name }}</span>

View File

@ -127,7 +127,7 @@ export default {
is-modal
:work-item-iid="displayedWorkItemIid"
:modal-work-item-full-path="workItemFullPath"
class="gl-p-5 gl-mt-n3 gl-reset-bg gl-isolate"
class="gl-p-5 -gl-mt-3 gl-reset-bg gl-isolate"
@close="hide"
@deleteWorkItem="deleteWorkItem"
@update-modal="updateModal"

View File

@ -208,7 +208,7 @@ export default {
<div v-else class="gl-display-flex gl-flex-wrap gl-gap-5">
<gl-form-group
class="gl-display-flex gl-align-items-center gl-m-0"
:class="{ 'gl-ml-n3': isReadonlyWithOnlyDueDate }"
:class="{ '-gl-ml-3': isReadonlyWithOnlyDueDate }"
:label="$options.i18n.startDate"
:label-for="$options.startDateInputId"
:label-sr-only="!showStartDateInput"
@ -238,7 +238,7 @@ export default {
<gl-form-group
v-if="!isReadonlyWithOnlyStartDate"
class="gl-display-flex gl-align-items-center gl-m-0"
:class="{ 'gl-ml-n3': isReadonlyWithOnlyDueDate }"
:class="{ '-gl-ml-3': isReadonlyWithOnlyDueDate }"
:label="$options.i18n.dueDate"
:label-for="$options.dueDateInputId"
:label-sr-only="!showDueDateInput"

View File

@ -254,7 +254,7 @@ export default {
<span
:style="{ background: item.color }"
:class="{ 'gl-border gl-border-white': isSelected(item.value) }"
class="gl-display-inline-block gl-rounded-base gl-mr-1 gl-w-5 gl-h-3 gl-align-middle gl-mt-n1"
class="gl-display-inline-block gl-rounded-base gl-mr-1 gl-w-5 gl-h-3 gl-align-middle -gl-mt-1"
></span>
{{ item.text }}
</span>

View File

@ -342,3 +342,5 @@ export const EPIC_COLORS = [
];
export const DEFAULT_EPIC_COLORS = '#1068bf';
export const CREATE_NEW_WORK_ITEM_MODAL = 'create_new_work_item_modal';

View File

@ -17,10 +17,10 @@ class Projects::MirrorsController < Projects::ApplicationController
end
def update
result = ::Projects::UpdateService.new(project, current_user, mirror_params).execute
result = ::Projects::UpdateService.new(project, current_user, safe_mirror_params).execute
if result[:status] == :success
flash[:notice] = _('Mirroring settings were successfully updated.')
flash[:notice] = notice_message
else
flash[:alert] = project.errors.full_messages.join(', ').html_safe
end
@ -64,6 +64,14 @@ class Projects::MirrorsController < Projects::ApplicationController
private
def safe_mirror_params
mirror_params
end
def notice_message
_('Mirroring settings were successfully updated.')
end
def remote_mirror
@remote_mirror = project.remote_mirrors.first_or_initialize
end

View File

@ -113,10 +113,15 @@ module SidebarsHelper
is_impersonating: impersonating?,
stop_impersonation_path: admin_impersonation_path,
shortcut_links: shortcut_links(user: user, project: project),
track_visits_path: track_namespace_visits_path
track_visits_path: track_namespace_visits_path,
work_items: work_items_modal_data(group)
})
end
def work_items_modal_data(group)
{ full_path: group.full_path } if group
end
def super_sidebar_nav_panel(
nav: nil, project: nil, user: nil, group: nil, current_ref: nil, ref_type: nil,
viewed_user: nil, organization: nil)

View File

@ -11,14 +11,15 @@
- filter_by_done = params[:state] == 'done'
- open_todo_count = todos_has_filtered_results? && !filter_by_done ? @allowed_todos.count : todos_pending_count
- done_todo_count = todos_has_filtered_results? && filter_by_done ? @allowed_todos.count : todos_done_count
- show_header = @allowed_todos.any? || current_user.todos.any?
- user_have_todos = current_user.todos.any?
- show_header = @allowed_todos.any? || user_have_todos
- if show_header
.page-title-holder.d-flex.gl-align-items-center
%h1.page-title.gl-font-size-h-display= _("To-Do List")
.js-todos-all
- if current_user.todos.any?
- if user_have_todos
.top-area
= gl_tabs_nav({ class: 'gl-flex-grow-1 gl-border-0' }) do
= gl_tab_link_to todos_filter_path(state: 'pending'), item_active: params[:state].blank? || params[:state] == 'pending', class: "js-todos-pending" do
@ -92,7 +93,7 @@
= render Pajamas::EmptyStateComponent.new(svg_path: 'illustrations/empty-todos-all-done-md.svg',
title: s_("Todos|You're all done!"))
- elsif current_user.todos.any?
- elsif user_have_todos
- empty_state_image = (!todos_filter_empty? && !todos_has_filtered_results?) ? 'illustrations/empty-todos-all-done-md.svg' : 'illustrations/empty-todos-md.svg'
- empty_state_title = s_("Todos|Nothing is on your to-do list. Nice work!")
- if todos_filter_empty?

View File

@ -0,0 +1,9 @@
---
name: web_hook_test_api_endpoint_rate_limit
feature_issue_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150066
rollout_issue_url:
milestone: '17.0'
group: group::import and integrate
type: ops
default_enabled: true

View File

@ -83,6 +83,5 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.

View File

@ -217,11 +217,18 @@ On multinode deployments, make sure that the issuer configured on the Sidekiq no
### Manually trigger a container registry sync event
To help with troubleshooting, you can manually trigger the container registry replication process by running the following commands on the secondary's Rails console:
To help with troubleshooting, you can manually trigger the container registry replication process:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Geo > Sites**.
1. In **Replication Details** for a **Secondary Site**, select **Container Repositories**.
1. Select **Resync** for one row, or **Resync all**.
You can also manually trigger a resync by running the following commands on the secondary's Rails console:
```ruby
registry = Geo::ContainerRepositoryRegistry.first # Choose a Geo registry entry
registry.replicator.sync_repository # Resync the container repository
registry.replicator.resync # Resync the container repository
pp registry.reload # Look at replication state fields
#<Geo::ContainerRepositoryRegistry:0x00007f54c2a36060

View File

@ -2876,9 +2876,14 @@ is returned.
### Trigger a test project hook
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147656) in GitLab 16.11.
> - Special rate limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150066) in GitLab 17.0 [with a flag](../administration/feature_flags.md) named `web_hook_test_api_endpoint_rate_limit`. Enabled by default.
Trigger a test hook for a specified project.
In GitLab 17.0 and later, this endpoint has a special rate limit of three requests per minute per project hook.
To disable this limit on self-managed GitLab and GitLab Dedicated, an administrator can
[disable the feature flag](../administration/feature_flags.md) named `web_hook_test_api_endpoint_rate_limit`.
```plaintext
POST /projects/:id/hooks/:hook_id/test/:trigger
```
@ -2889,6 +2894,10 @@ POST /projects/:id/hooks/:hook_id/test/:trigger
| `id` | integer or string | Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `trigger` | string | Yes | One of `push_events`, `tag_push_events`, `issues_events`, `confidential_issues_events`, `note_events`, `merge_requests_events`, `job_events`, `pipeline_events`, `wiki_page_events`, `releases_events`, `emoji_events`, or `resource_access_token_events`. |
```json
{"message":"201 Created"}
```
## Fork relationship
Allows modification of the forked relationship between existing projects.

View File

@ -14,8 +14,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
In GitLab 16.0, we introduced a new runner creation workflow that uses runner authentication tokens to register

View File

@ -33,14 +33,22 @@ To connect a feature in an existing backend service to Cloud Connector:
#### GitLab Rails
1. Call `CloudConnector::AccessService.new.access_token(scopes: [...])` with the list of scopes your feature requires and include
this token in the `Authorization` HTTP header field.
Note that this can return `nil` if there is no valid token available. If there is no token, the call to Cloud Connector will
not pass authorization, so it is recommended to return early.
1. Call `CloudConnector::AvailableServices.find_by_name(:feature_name).access_token(user_or_namespace)`
and include this token in the `Authorization` HTTP header field.
On GitLab.com, it will self-issue a token with scopes that depend on the provided resource:
- For a user: scopes will be based on the user's seat assignment
- For a namespace: scopes will be based on purchased add-ons for this namespace
- If a feature is a `free_access?` (no addon purchase is required): the token will include all available scopes for that feature
On self-managed, it will always return `::CloudConnector::ServiceAccessToken` instance token.
The backend service must validate this token and any scopes it carries when receiving the request.
If you need to embed additional claims in the token specific to your use case, you can pass these
in the `extra_claims` argument. **Scopes and other claims passed here will only be included in self-issued tokens on GitLab.com.**
Refer to [CustomersDot](#customersdot) to see how custom claims are handled for self-managed instances.
1. Ensure your request sends the required headers to the [backend service](#backend-service).
These headers are:
@ -53,26 +61,27 @@ Refer to [CustomersDot](#customersdot) to see how custom claims are handled for
Some of these headers can be injected by merging the result of the `API::Helpers::CloudConnector#cloud_connector_headers`
method to your payload.
The following example is for a request that includes the `new_feature_scope` scope.
The following example is for a request to the feature called `:new_feature`.
Here we assume your backend service is called `foo` and is already reachable at `https://cloud.gitlab.com/foo`.
We also assume that the backend service exposes the feature using a `/new_feature_endpoint` endpoint.
This allows clients to access the feature at `https://cloud.gitlab.com/foo/new_feature_endpoint`.
Here, the parameters you pass to `access_token` have the following meaning:
- `audience`: The name of the backend service. The token is bound to this backend
using the JWT `aud` claim.
- `scopes`: The list of access scopes carried in this token. They should map to access points
in your backend, which could be HTTP endpoints or RPC calls.
```ruby
include API::Helpers::CloudConnector
token = ::CloudConnector::AccessService.new.access_token(
audience: 'foo',
scopes: [:new_feature_scope]
)
return unauthorized! if token.nil?
new_feature = ::CloudConnector::AvailableServices.find_by_name(:new_feature)
# (Optional) Handle the free access case separately, if needed
if new_feature.free_access?
# ...
return
end
# Check if the feature is available for the given user based on seat assignment, add-on purchases
return unauthorized! unless new_feature.allowed_for?(current_user)
# Obtain a token
token = new_feature.access_token(current_user)
Gitlab::HTTP.post(
"https://cloud.gitlab.com/foo/new_feature_endpoint",
@ -83,7 +92,7 @@ Gitlab::HTTP.post(
```
NOTE:
Any arguments you pass to `access_token` that configure the token returned only take hold for
Any arguments you pass to `access_token` that configure the token returned (`user` or `namespace`, `extra_claims`) only take hold for
tokens issued on GitLab.com. For self-managed GitLab instances the token is read as-is from
the database and never modified.

View File

@ -286,8 +286,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
```
@ -297,8 +296,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
If all of the content on the page is not available, use the disclaimer about forward-looking statements once at the top of the page.

View File

@ -10,8 +10,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
This page provides a high-level overview of the aggregated backend for

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** GitLab.com
**Status:** Experiment
**Status:** Beta
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124966) in GitLab 16.7 [with a flag](../administration/feature_flags.md) named `observability_metrics`. Disabled by default. This feature is an [Experiment](../policy/experiment-beta-support.md#experiment).
@ -67,13 +67,36 @@ You can view the metrics for a given project:
A list of metrics is displayed.
Select a metric to view its details.
![list of metrics](img/metrics_list_v16_8.png)
![list of metrics](img/metrics_list_v17_0.png)
Each metric contains one or more attributes. You can filter
metrics by attribute with the search bar.
### Metric details
Metrics are displayed as either a sum, a gauge, or a histogram.
The metric details page displays a chart depending on the type of metric.
On the metric details page, you can also view a metric for a specific time range.
On the metric details page, you can also view metrics for a specific time range, and
aggregate metrics by attribute:
![metrics details](img/metrics_details_v16_8.png)
![metrics details](img/metrics_detail_v17_0.png)
To make data lookups fast, depending on what time period you filter by,
GitLab automatically chooses the proper aggregation.
For example, if you search for more than seven days of data, the API returns only daily aggregates.
### Aggregations by search period
The following table shows what type of aggregation is used for each search period:
|Period|Aggregation used|
|---|---|
| Less than 30 minutes | Raw data as ingested |
| More than 30 minutes and less than one hour | By minute |
| More than one hour and less than 72 hours | Hourly |
| More than 72 hours | Daily |
### Data retention
GitLab has a retention limit of 30 days for all ingested metrics.

View File

@ -172,3 +172,18 @@ Prerequisites:
1. Select **Submit**.
The trial automatically syncs to your instance within 24 hours. After the trial has synced, [assign seats](#assign-gitlab-duo-pro-seats) to users that you want to access GitLab Duo Pro.
## Automatic seat removal for seat overages
If your quantity of purchased GitLab Duo Pro seats is reduced, seat assignments are automatically removed to match the seat quantity available in the subscription.
For example:
- You have a 50 seat GitLab Duo Pro subscription with all seats assigned.
- You renew the subscription for 30 seats. The 20 users over subscription are automatically removed from GitLab Duo Pro seat assignment.
- If only 20 users were assigned a GitLab Duo Pro seat before renewal, then no removal of seats would occur.
Seats are selected for removal based on the following criteria, in this order:
1. Users who have not yet used Code Suggestions, ordered by most recently assigned.
1. Users who have used Code Suggestions, ordered by least recent usage of Code Suggestions.

View File

@ -5721,6 +5721,5 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.

View File

@ -63,15 +63,22 @@ To enable Beta and Experimental AI-powered features, use the [Experiment and Bet
To enable Beta and Experimental AI-powered features for GitLab versions where GitLab Duo Chat is not yet generally available, see the [GitLab Duo Chat documentation](gitlab_duo_chat.md#for-self-managed).
### Enable outbound connections to enable GitLab Duo features on self-managed instances
### Network Requirements to enable GitLab Duo features for self-managed GitLab
#### Enable outbound connections from GitLab instances
- Your firewalls and HTTP/S proxy servers must allow outbound connections
to `cloud.gitlab.com` and `customers.gitlab.com` on port `443` both with `https://` and `wws://`.
- Both `HTTP2` and the `'upgrade'` header must be allowed, because GitLab Duo
uses both REST and WebSockets.
to `cloud.gitlab.com` and `customers.gitlab.com` on port `443` both with `https://`.
- To use an HTTP/S proxy, both `gitLab_workhorse` and `gitLab_rails` must have the necessary
[web proxy environment variables](https://docs.gitlab.com/omnibus/settings/environment-variables.html) set.
- Check for restrictions on WebSocket (`wss://`) traffic to `wss://gitlab.com/-/cable` and other `.com` domains.
#### Enable inbound connections from Clients to GitLab instances
- GitLab instances must allow inbound connections from Duo clients (IDEs, Code Editors, and GitLab Web Frontend)
on port 443 with `https://` and `wss://`.
- Both `HTTP2` and the `'upgrade'` header must be allowed, because GitLab Duo
uses both REST and WebSockets.
- Check for restrictions on WebSocket (`wss://`) traffic to `wss://gitlab.example.com/-/cable` and other `.com` domains.
Network policy restrictions on `wss://` traffic can cause issues with some GitLab Duo Chat
services. Consider policy updates to allow these services.

View File

@ -114,8 +114,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
Perform Out-of-Band Application Security Testing (OAST) for certain [active checks](../dast/browser/checks/index.md#active-checks).

View File

@ -17,8 +17,7 @@ DISCLAIMER:
This page contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
NOTE:

View File

@ -146,7 +146,8 @@ module API
failure [
{ code: 400, message: 'Bad request' },
{ code: 404, message: 'Not found' },
{ code: 422, message: 'Unprocessable entity' }
{ code: 422, message: 'Unprocessable entity' },
{ code: 429, message: 'Too many requests' }
]
end
params do
@ -155,8 +156,13 @@ module API
desc: 'The type of trigger hook',
values: ProjectHook.triggers.values.map(&:to_s)
end
post ":id/hooks/:hook_id/test/:trigger" do
post ":id/hooks/:hook_id/test/:trigger", urgency: :low do
hook = find_hook
if Feature.enabled?(:web_hook_test_api_endpoint_rate_limit)
check_rate_limit!(:web_hook_test_api_endpoint, scope: hook)
end
result = TestHooks::ProjectService.new(hook, current_user, params[:trigger]).execute
success = (200..299).cover?(result.payload[:http_status])
if success

View File

@ -35,6 +35,7 @@ module Gitlab
web_hook_calls: { interval: 1.minute },
web_hook_calls_mid: { interval: 1.minute },
web_hook_calls_low: { interval: 1.minute },
web_hook_test_api_endpoint: { threshold: 3, interval: 1.minute },
users_get_by_id: { threshold: -> { application_settings.users_get_by_id_limit }, interval: 10.minutes },
username_exists: { threshold: 20, interval: 1.minute },
user_sign_up: { threshold: 20, interval: 1.minute },

View File

@ -159,27 +159,3 @@ gemnasium-python-dependency_scanning:
- if: $CI_COMMIT_BRANCH &&
$GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
$PIP_REQUIREMENTS_FILE
bundler-audit-dependency_scanning:
extends: .ds-analyzer
variables:
DS_ANALYZER_NAME: "bundler-audit"
DS_MAJOR_VERSION: 2
script:
- echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
- echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/347491"
- exit 1
rules:
- when: never
retire-js-dependency_scanning:
extends: .ds-analyzer
variables:
DS_ANALYZER_NAME: "retire.js"
DS_MAJOR_VERSION: 2
script:
- echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
- echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/289830"
- exit 1
rules:
- when: never

View File

@ -46587,6 +46587,9 @@ msgstr ""
msgid "SecurityOrchestration|No exceptions"
msgstr ""
msgid "SecurityOrchestration|No policies in the security policy project will be enforced until the invalid policies are fixed."
msgstr ""
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
@ -46634,6 +46637,9 @@ msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
msgid "SecurityOrchestration|Policies are invalid"
msgstr ""
msgid "SecurityOrchestration|Policy Type"
msgstr ""
@ -46646,15 +46652,15 @@ msgstr ""
msgid "SecurityOrchestration|Policy changes may take some time to be applied."
msgstr ""
msgid "SecurityOrchestration|Policy contains deprecated syntax"
msgstr ""
msgid "SecurityOrchestration|Policy definition"
msgstr ""
msgid "SecurityOrchestration|Policy editor"
msgstr ""
msgid "SecurityOrchestration|Policy is invalid"
msgstr ""
msgid "SecurityOrchestration|Policy scope"
msgstr ""
@ -46847,9 +46853,6 @@ msgstr ""
msgid "SecurityOrchestration|This policy is inherited from the %{linkStart}namespace%{linkEnd} and must be edited there"
msgstr ""
msgid "SecurityOrchestration|This policy won't work after GitLab 17.0 (May 16, 2024). You must edit the policy and replace the deprecated syntax%{deprecatedProperties}. For details on which syntax has been deprecated, see %{linkStart}Documentation%{linkEnd}."
msgstr ""
msgid "SecurityOrchestration|This project"
msgstr ""
@ -46940,6 +46943,9 @@ msgstr ""
msgid "SecurityOrchestration|You don't have any security policies yet"
msgstr ""
msgid "SecurityOrchestration|You must edit the policy and replace the deprecated syntax%{deprecatedProperties}. For details on it's replacement, see the %{linkStart}policy documentation%{linkEnd}."
msgstr ""
msgid "SecurityOrchestration|You must select one or more compliance frameworks to which this policy should apply."
msgstr ""

View File

@ -62,7 +62,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/fonts": "^1.3.0",
"@gitlab/svgs": "3.97.0",
"@gitlab/ui": "79.3.0",
"@gitlab/ui": "79.4.1",
"@gitlab/web-ide": "^0.0.1-dev-20240422132849",
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
"@rails/actioncable": "7.0.8-1",
@ -139,7 +139,7 @@
"deckar01-task_list": "^2.3.1",
"dexie": "^3.2.3",
"diff": "^3.4.0",
"dompurify": "^3.1.1",
"dompurify": "^3.1.2",
"dropzone": "^4.2.0",
"editorconfig": "^0.15.3",
"emoji-regex": "^10.0.0",

View File

@ -12,79 +12,16 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
<li
class="gl-breadcrumb-item"
>
<div
class="gl-disclosure-dropdown gl-new-dropdown"
style="height: 16px;"
<a
target="_self"
>
<button
aria-controls="reference-1"
aria-expanded="false"
aria-labelledby="reference-0"
class="btn btn-default btn-icon btn-sm gl-button gl-new-dropdown-icon-only gl-new-dropdown-toggle gl-new-dropdown-toggle-no-caret"
data-testid="base-dropdown-toggle"
id="reference-0"
type="button"
>
<svg
aria-hidden="true"
class="gl-button-icon gl-icon s16"
data-testid="ellipsis_h-icon"
role="img"
>
<use
href="file-mock#ellipsis_h"
/>
</svg>
<span
class="gl-button-text"
>
<span
class="gl-new-dropdown-button-text gl-sr-only"
>
Show more breadcrumbs
</span>
</span>
</button>
<div
class="gl-new-dropdown-panel"
data-testid="base-dropdown-menu"
id="reference-1"
>
<div
class="gl-new-dropdown-inner"
>
<ul
aria-labelledby="reference-0"
class="gl-new-dropdown-contents"
data-testid="disclosure-content"
id="reference-2"
tabindex="-1"
>
<li
class="gl-new-dropdown-item"
data-testid="disclosure-dropdown-item"
tabindex="0"
>
<a
class="gl-new-dropdown-item-content"
tabindex="-1"
target="_self"
>
<span
class="gl-new-dropdown-item-text-wrapper"
>
mock name
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<span>
mock name
</span>
</a>
</li>
<li
class="gl-breadcrumb-item"
style="flex-shrink: 1; text-overflow: ellipsis; overflow-x: hidden; text-wrap: nowrap;"
>
<a
aria-current="page"

View File

@ -6,6 +6,7 @@ import {
} from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import CreateWorkItemModal from '~/work_items/components/create_work_item_modal.vue';
import { __ } from '~/locale';
import CreateMenu from '~/super_sidebar/components/create_menu.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@ -18,6 +19,7 @@ describe('CreateMenu component', () => {
const findGlDisclosureDropdownGroups = () => wrapper.findAllComponents(GlDisclosureDropdownGroup);
const findGlDisclosureDropdownItems = () => wrapper.findAllComponents(GlDisclosureDropdownItem);
const findInviteMembersTrigger = () => wrapper.findComponent(InviteMembersTrigger);
const findCreateWorkItemModal = () => wrapper.findComponent(CreateWorkItemModal);
const createWrapper = ({ provide = {} } = {}) => {
wrapper = shallowMountExtended(CreateMenu, {
@ -30,6 +32,7 @@ describe('CreateMenu component', () => {
},
stubs: {
InviteMembersTrigger,
CreateWorkItemModal,
GlDisclosureDropdown,
GlEmoji: { template: '<div/>' },
},
@ -77,6 +80,10 @@ describe('CreateMenu component', () => {
expect(findInviteMembersTrigger().exists()).toBe(true);
});
it('renders the create new work item modal', () => {
expect(findCreateWorkItemModal().exists()).toBe(true);
});
it('hides the tooltip when the dropdown is opened', async () => {
findGlDisclosureDropdown().vm.$emit('shown');
await nextTick();

View File

@ -1,6 +1,47 @@
import invalidUrl from '~/lib/utils/invalid_url';
export const createNewMenuGroups = [
{
name: 'This group',
items: [
{
text: 'New project/repository',
href: '/projects/new?namespace_id=22',
},
{
text: 'New subgroup',
href: '/groups/new?parent_id=22#create-group-pane',
},
{
text: 'New epic',
component: 'create_new_work_item_modal',
},
{
text: 'Invite members',
component: 'invite_members',
},
],
},
{
name: 'GitLab',
items: [
{
text: 'New project/repository',
href: '/projects/new',
},
{
text: 'New group',
href: '/groups/new',
},
{
text: 'New snippet',
href: '/-/snippets/new',
},
],
},
];
export const createNewMenuGroupsLegacy = [
{
name: 'This group',
items: [

View File

@ -8,7 +8,7 @@ exports[`History Item renders the correct markup 1`] = `
class="timeline-entry-inner"
>
<div
class="gl--flex-center gl-bg-gray-50 gl-float-left gl-h-6 gl-ml-2 gl-mt-n1 gl-rounded-full gl-text-gray-600 gl-w-6"
class="-gl-mt-1 gl--flex-center gl-bg-gray-50 gl-float-left gl-h-6 gl-ml-2 gl-rounded-full gl-text-gray-600 gl-w-6"
>
<gl-icon-stub
name="pencil"

View File

@ -1,5 +1,5 @@
import { nextTick } from 'vue';
import { GlModal } from '@gitlab/ui';
import { GlDisclosureDropdownItem, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CreateWorkItem from '~/work_items/components/create_work_item.vue';
import CreateWorkItemModal from '~/work_items/components/create_work_item_modal.vue';
@ -13,13 +13,15 @@ describe('CreateWorkItemModal', () => {
let wrapper;
const findTrigger = () => wrapper.find('[data-testid="new-epic-button"]');
const findDropdownItem = () => wrapper.findComponent(GlDisclosureDropdownItem);
const findModal = () => wrapper.findComponent(GlModal);
const findForm = () => wrapper.findComponent(CreateWorkItem);
const createComponent = ({ workItemType } = {}) => {
const createComponent = ({ workItemType, asDropdownItem = false } = {}) => {
wrapper = shallowMount(CreateWorkItemModal, {
propsData: {
workItemType,
asDropdownItem,
},
});
};
@ -38,14 +40,24 @@ describe('CreateWorkItemModal', () => {
expect(visitUrl).toHaveBeenCalledWith('/');
});
it('opens modal on trigger click', async () => {
createComponent();
describe('default trigger', () => {
it('opens modal on trigger click', async () => {
createComponent();
findTrigger().vm.$emit('click');
findTrigger().vm.$emit('click');
await nextTick();
await nextTick();
expect(findModal().props('visible')).toBe(true);
expect(findModal().props('visible')).toBe(true);
});
});
describe('dropdown item trigger', () => {
it('renders a dropdown item component', () => {
createComponent({ asDropdownItem: true });
expect(findDropdownItem().exists()).toBe(true);
});
});
it('closes modal on cancel event from form', () => {

View File

@ -179,7 +179,8 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
pinned_items: %w[foo bar],
update_pins_url: pins_path,
shortcut_links: global_shortcut_links,
track_visits_path: track_namespace_visits_path
track_visits_path: track_namespace_visits_path,
work_items: { full_path: group.full_path }
})
end

View File

@ -67,13 +67,38 @@ RSpec.describe API::ProjectHooks, 'ProjectHooks', feature_category: :webhooks do
{ push_events: true, confidential_note_events: nil }
end
context "when trigger project webhook test", :aggregate_failures do
context "when trigger project webhook test", :aggregate_failures, :clean_gitlab_redis_rate_limiting do
using RSpec::Parameterized::TableSyntax
before do
stub_full_request(hook.url, method: :post).to_return(status: 200)
end
specify do
expect(post(api("#{hook_uri}/test/push_events", user), params: {}))
.to have_request_urgency(:low)
end
it_behaves_like 'rate limited endpoint', rate_limit_key: :web_hook_test_api_endpoint do
let(:current_user) { user }
def request
post api("#{hook_uri}/test/push_events", user), params: {}
end
context 'when ops flag is disabled' do
before do
stub_feature_flags(web_hook_test_api_endpoint_rate_limit: false)
end
it 'does not block the request' do
request
expect(response).to have_gitlab_http_status(:created)
end
end
end
context 'when testing is not available for trigger' do
where(:trigger_name) do
%w[confidential_note_events deployment_events feature_flag_events]

View File

@ -187,7 +187,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
expect(json_response[k.to_s]).to eq(v)
end
event_names.each do |name|
expect(json_response[name.to_s]).to eq(true), name
expect(json_response[name.to_s]).to eq(true), name.to_s
end
expect(json_response['url_variables']).to match_array [
{ 'key' => 'token' },
@ -232,7 +232,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
expect(response).to match_hook_schema
expect(json_response['enable_ssl_verification']).to be true
event_names.each do |name|
expect(json_response[name.to_s]).to eq(default_values.fetch(name, false)), name
expect(json_response[name.to_s]).to eq(default_values.fetch(name, false)), name.to_s
end
end

View File

@ -1331,10 +1331,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.97.0.tgz#d6ffbfdf1a7b78fa35bc9ebec0b3d34376ccee58"
integrity sha512-Bt/3k+mHY3Qi+2xjl7tTkhfBMiG8XeE0dTrR+/e6QITYqc7/L/QUFey1iym0cfv1y+iddcUZKDCfgdFyCRnEhg==
"@gitlab/ui@79.3.0":
version "79.3.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-79.3.0.tgz#7aae82e23e79aae77c6bad074f3d5a273da7eee5"
integrity sha512-LWallyRPizI/wVx+Ykm3VuvVcfYQBlUtmphTHkgU41r4Iq8VzhxrrzxQo2lVYFVCJFi260hyBguE+WwFkW0HjA==
"@gitlab/ui@79.4.1":
version "79.4.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-79.4.1.tgz#500753516a4f35b4ea71b01916cc2f771f3baf3f"
integrity sha512-wvCqDaaFiveTsm+XasdMP0Rvk2iGO3BZCSpKSfiwgdj8NrNfyEH7Bs1ZXjaXVeiLM5XvNO30sUwAaK7e+lAvtg==
dependencies:
"@floating-ui/dom" "1.4.3"
bootstrap-vue "2.23.1"
@ -6185,10 +6185,10 @@ dommatrix@^1.0.3:
resolved "https://registry.yarnpkg.com/dommatrix/-/dommatrix-1.0.3.tgz#e7c18e8d6f3abdd1fef3dd4aa74c4d2e620a0525"
integrity sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww==
dompurify@^3.0.5, dompurify@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.1.tgz#e83de1e0ba7f1014f36686fbc63a2a3a1bdb93f6"
integrity sha512-tVP8C/GJwnABOn/7cx/ymx/hXpmBfWIPihC1aOEvS8GbMqy3pgeYtJk1HXN3CO7tu+8bpY18f6isjR5Cymj0TQ==
dompurify@^3.0.5, dompurify@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.2.tgz#d1e158457e00666ab40c9c3d8aab57586a072bd1"
integrity sha512-hLGGBI1tw5N8qTELr3blKjAML/LY4ANxksbS612UiJyDfyf/2D092Pvm+S7pmeTGJRqvlJkFzBoHBQKgQlOQVg==
dropzone@^4.2.0:
version "4.2.0"