Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b9f4411b1b
commit
cbb6a29694
|
|
@ -76,7 +76,7 @@ workflow:
|
|||
# they serve no purpose and will run anyway when the changes are merged.
|
||||
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
|
||||
when: never
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3_1/'
|
||||
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3_1/ || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/'
|
||||
variables:
|
||||
<<: [*default-ruby-variables, *default-merge-request-variables]
|
||||
PIPELINE_NAME: 'Ruby $RUBY_VERSION MR'
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@
|
|||
{"name":"gitlab-glfm-markdown","version":"0.0.17","platform":"ruby","checksum":"f379545fc53a71c31525025fdb422f46081133af5cced3130ce680b155c2aa69"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.17","platform":"x86_64-darwin","checksum":"50e0f4865ef7c455426c7c058fc10ff9c8366482d48a63d6f6693b38c4a49c1c"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.17","platform":"x86_64-linux","checksum":"cc877ff8ceb3aa8a331fdb8991592e35897823e0f77ba9e4b2b65082c665089b"},
|
||||
{"name":"gitlab-labkit","version":"0.36.0","platform":"ruby","checksum":"35f21d1c3870ed0c9b8321e25d0b0b0b5021805a5d0525d1eb0fde6b103af981"},
|
||||
{"name":"gitlab-labkit","version":"0.36.1","platform":"ruby","checksum":"04fb6941b7e5fc1fdcee8f9971fa2086a4dc442e39e67a74b992403dd580c300"},
|
||||
{"name":"gitlab-license","version":"2.5.0","platform":"ruby","checksum":"4c166c469c2ad17876ca43188a4ccebe3feb0726c4c1770047f8dcef96573f4d"},
|
||||
{"name":"gitlab-mail_room","version":"0.0.25","platform":"ruby","checksum":"223ce7c3c0797b6015eaa37147884e6ddc7be9a7ee90a424358c96bc18613b1a"},
|
||||
{"name":"gitlab-markup","version":"1.9.0","platform":"ruby","checksum":"7eda045a08ec2d110084252fa13a8c9eac8bdac0e302035ca7db4b82bcbd7ed4"},
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ GEM
|
|||
mime-types
|
||||
gitlab-glfm-markdown (0.0.17)
|
||||
rb_sys (= 0.9.94)
|
||||
gitlab-labkit (0.36.0)
|
||||
gitlab-labkit (0.36.1)
|
||||
actionpack (>= 5.0.0, < 8.0.0)
|
||||
activesupport (>= 5.0.0, < 8.0.0)
|
||||
grpc (>= 1.62)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export default {
|
|||
<gl-collapsible-listbox
|
||||
v-model="selected"
|
||||
:items="databases"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="selectedDatabase"
|
||||
toggle-aria-labelled-by="label"
|
||||
@select="selectDatabase"
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ export default {
|
|||
<template>
|
||||
<gl-disclosure-dropdown
|
||||
ref="submitDropdown"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="submit-review-dropdown"
|
||||
:class="{ 'submit-review-dropdown-animated': shouldAnimateReviewButton }"
|
||||
data-testid="submit-review-dropdown"
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ export default {
|
|||
:toggle-text="$options.i18n.toggleText"
|
||||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
data-testid="branch-more-actions"
|
||||
text-sr-only
|
||||
no-caret
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
no-caret
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="gl-hidden md:!gl-block"
|
||||
:items="dropdownItems"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export default {
|
|||
text-sr-only
|
||||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="note-action-button more-actions-toggle"
|
||||
no-caret
|
||||
>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export default {
|
|||
v-else-if="isManualJob"
|
||||
icon="retry"
|
||||
category="primary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
positioning-strategy="fixed"
|
||||
variant="confirm"
|
||||
:items="dropdownItems"
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ export default {
|
|||
:aria-label="$options.i18n.downloadArtifacts"
|
||||
:items="items"
|
||||
icon="download"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
text-sr-only
|
||||
data-testid="pipeline-multi-actions-dropdown"
|
||||
@shown="onDisclosureDropdownShown"
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export default {
|
|||
:toggle-text="$options.i18n.artifacts"
|
||||
:aria-label="$options.i18n.artifacts"
|
||||
icon="download"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
text-sr-only
|
||||
:items="items"
|
||||
data-testid="artifacts-dropdown"
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ export default {
|
|||
v-if="actionItems.length"
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="defaultActionText"
|
||||
:items="actionItems"
|
||||
:disabled="!canAddCluster"
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
no-caret
|
||||
text-sr-only
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="__('Comment template actions')"
|
||||
:loading="isDeleting"
|
||||
category="tertiary"
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export default {
|
|||
}));
|
||||
},
|
||||
placement() {
|
||||
return this.right ? 'right' : 'left';
|
||||
return this.right ? 'bottom-end' : 'bottom-start';
|
||||
},
|
||||
newCustomEmoji() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -824,7 +824,7 @@ export default {
|
|||
no-caret
|
||||
icon="ellipsis_v"
|
||||
category="secondary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="__('More actions')"
|
||||
>
|
||||
<rollback-component
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ export default {
|
|||
block
|
||||
:toggle-text="__('Options')"
|
||||
toggle-class="md:gl-hidden"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:disabled="issueUpdateInProgress"
|
||||
:items="dropdownItems"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ export const resolvers = {
|
|||
healthStatus,
|
||||
isGroup,
|
||||
fullPath,
|
||||
workItemType,
|
||||
assignees,
|
||||
color,
|
||||
title,
|
||||
|
|
@ -301,9 +302,10 @@ export const resolvers = {
|
|||
const query = isGroup ? groupWorkItemByIidQuery : workItemByIidQuery;
|
||||
|
||||
const variables = {
|
||||
fullPath: newWorkItemFullPath(fullPath),
|
||||
fullPath: newWorkItemFullPath(fullPath, workItemType),
|
||||
iid: NEW_WORK_ITEM_IID,
|
||||
};
|
||||
|
||||
cache.updateQuery({ query, variables }, (sourceData) =>
|
||||
produce(sourceData, (draftData) => {
|
||||
if (healthStatus) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-badge v-gl-tooltip :title="title" variant="warning">
|
||||
<gl-badge v-gl-tooltip :title="title" variant="warning" class="gl-shrink-0">
|
||||
<gl-icon name="spam" />
|
||||
<span class="gl-sr-only">{{ __('Hidden') }}</span>
|
||||
</gl-badge>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,13 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-badge v-gl-tooltip :title="title" variant="warning" data-testid="locked-badge">
|
||||
<gl-badge
|
||||
v-gl-tooltip
|
||||
:title="title"
|
||||
variant="warning"
|
||||
data-testid="locked-badge"
|
||||
class="gl-shrink-0"
|
||||
>
|
||||
<gl-icon name="lock" />
|
||||
<span class="gl-sr-only">{{ __('Locked') }}</span>
|
||||
</gl-badge>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,11 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-badge :variant="badgeProperties.variant" :aria-label="badgeProperties.text">
|
||||
<gl-badge
|
||||
:variant="badgeProperties.variant"
|
||||
:aria-label="badgeProperties.text"
|
||||
class="gl-shrink-0"
|
||||
>
|
||||
<gl-icon :name="badgeProperties.icon" />
|
||||
{{ badgeProperties.text }}
|
||||
</gl-badge>
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ export default {
|
|||
:auto-close="false"
|
||||
data-testid="mobile-dropdown"
|
||||
:loading="isToggleStateButtonLoading"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
>
|
||||
<template v-if="showMovedSidebarOptions && !glFeatures.notificationsTodosButtons">
|
||||
<sidebar-subscriptions-widget
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export default {
|
|||
</div>
|
||||
<gl-disclosure-dropdown
|
||||
v-if="canUpdateTimelineEvent"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="event-note-actions gl-align-self-start"
|
||||
icon="ellipsis_v"
|
||||
text-sr-only
|
||||
|
|
|
|||
|
|
@ -81,10 +81,8 @@ export default {
|
|||
class="issue-sticky-header gl-fixed gl-z-3 gl-bg-white gl-border-1 gl-border-b-solid gl-border-b-gray-100 gl-py-3"
|
||||
data-testid="issue-sticky-header"
|
||||
>
|
||||
<div
|
||||
class="issue-sticky-header-text gl-display-flex gl-align-items-center gl-gap-2 gl-mx-auto"
|
||||
>
|
||||
<gl-badge :variant="statusVariant" :icon="statusIcon">
|
||||
<div class="issue-sticky-header-text gl-flex gl-items-center gl-gap-2 gl-mx-auto">
|
||||
<gl-badge :variant="statusVariant" :icon="statusIcon" class="gl-shrink-0">
|
||||
{{ statusText }}
|
||||
</gl-badge>
|
||||
<confidentiality-badge
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
category="tertiary"
|
||||
icon="ellipsis_v"
|
||||
no-caret
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="$options.i18n.taskActions"
|
||||
text-sr-only
|
||||
toggle-class="task-list-item-actions gl-opacity-0 gl-p-2! "
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export default {
|
|||
:toggle-text="preferredLocale.text"
|
||||
:items="locales"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
icon="earth"
|
||||
size="small"
|
||||
toggle-class="py-0 gl-h-6"
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
no-caret
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
data-testid="user-action-dropdown"
|
||||
>
|
||||
<disable-two-factor-dropdown-item
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ export default {
|
|||
<div>
|
||||
<gl-collapsible-listbox
|
||||
v-if="permissions.canUpdate"
|
||||
:placement="isDesktop ? 'left' : 'right'"
|
||||
:placement="isDesktop ? 'bottom-start' : 'bottom-end'"
|
||||
:header-text="__('Change role')"
|
||||
:disabled="disabled"
|
||||
:loading="busy"
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<gl-disclosure-dropdown
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
category="tertiary"
|
||||
:aria-label="__('More actions')"
|
||||
icon="ellipsis_v"
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
size="small"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
no-caret
|
||||
:title="__('Thread options')"
|
||||
:aria-label="__('Thread options')"
|
||||
|
|
@ -179,7 +179,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
size="small"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
no-caret
|
||||
:title="__('Thread options')"
|
||||
:aria-label="__('Thread options')"
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ export default {
|
|||
data-testid="discussion-preferences-dropdown"
|
||||
:toggle-text="__('Sort or filter')"
|
||||
:disabled="isLoading"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
>
|
||||
<gl-disclosure-dropdown-group id="discussion-sort">
|
||||
<gl-disclosure-dropdown-item
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export default {
|
|||
:show-select-all-button-label="__('Select all')"
|
||||
:reset-button-label="__('Deselect all')"
|
||||
multiple
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
@shown="filterListShown"
|
||||
@hidden="applyFilters"
|
||||
@reset="deselectAll"
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ export default {
|
|||
text-sr-only
|
||||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="note-action-button more-actions-toggle"
|
||||
no-caret
|
||||
>
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ export default {
|
|||
<gl-disclosure-dropdown
|
||||
category="tertiary"
|
||||
icon="ellipsis_v"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="$options.i18n.MORE_ACTIONS_TEXT"
|
||||
text-sr-only
|
||||
no-caret
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ export default {
|
|||
:text-sr-only="true"
|
||||
category="tertiary"
|
||||
no-caret
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:class="{ 'gl-opacity-0 gl-pointer-events-none': disabled }"
|
||||
data-testid="additional-actions"
|
||||
:items="items"
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ export default {
|
|||
:toggle-text="__('More actions')"
|
||||
:text-sr-only="true"
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
no-caret
|
||||
>
|
||||
<gl-disclosure-dropdown-item v-gl-modal-directive="$options.confirmClearCacheModal">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
|
||||
|
||||
export default {
|
||||
|
|
@ -9,7 +10,7 @@ export default {
|
|||
GlLink,
|
||||
GlSprintf,
|
||||
},
|
||||
inject: ['terraformHelpPath', 'gitlabHost', 'projectPath'],
|
||||
inject: ['gitlabHost', 'projectPath'],
|
||||
props: {
|
||||
packageName: {
|
||||
type: String,
|
||||
|
|
@ -38,6 +39,9 @@ export default {
|
|||
'InfrastructureRegistry|For more information on the Terraform registry, %{linkStart}see our documentation%{linkEnd}.',
|
||||
),
|
||||
},
|
||||
terraformHelpPath: helpPagePath('user/packages/terraform_module_registry/index', {
|
||||
anchor: 'reference-a-terraform-module',
|
||||
}),
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -66,7 +70,7 @@ export default {
|
|||
/>
|
||||
<gl-sprintf :message="$options.i18n.helpText">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="terraformHelpPath">{{ content }}</gl-link>
|
||||
<gl-link :href="$options.terraformHelpPath">{{ content }}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ export default () => {
|
|||
const {
|
||||
package: packageJson,
|
||||
canDelete: canDeleteStr,
|
||||
terraformHelpPath,
|
||||
gitlabHost,
|
||||
projectPath,
|
||||
projectName,
|
||||
projectListUrl,
|
||||
svgPath,
|
||||
} = el.dataset;
|
||||
const packageEntity = JSON.parse(packageJson);
|
||||
const canDelete = parseBoolean(canDeleteStr);
|
||||
|
|
@ -34,7 +34,7 @@ export default () => {
|
|||
projectListUrl,
|
||||
projectName,
|
||||
projectPath,
|
||||
terraformHelpPath,
|
||||
svgPath,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(PackagesApp);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
#import "~/packages_and_registries/package_registry/graphql/fragments/package_group_settings.fragment.graphql"
|
||||
|
||||
query getGroupPackageSettings($fullPath: ID!) {
|
||||
project(fullPath: $fullPath) {
|
||||
query getGroupPackageSettings($fullPath: ID!, $isGroupPage: Boolean = false) {
|
||||
project(fullPath: $fullPath) @skip(if: $isGroupPage) {
|
||||
id
|
||||
group {
|
||||
...GroupPackageSettings
|
||||
}
|
||||
}
|
||||
group(fullPath: $fullPath) @include(if: $isGroupPage) {
|
||||
...GroupPackageSettings
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#import "~/packages_and_registries/package_registry/graphql/fragments/package_data.fragment.graphql"
|
||||
#import "~/packages_and_registries/package_registry/graphql/fragments/package_group_settings.fragment.graphql"
|
||||
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
|
||||
|
||||
query getPackages(
|
||||
|
|
@ -37,9 +36,6 @@ query getPackages(
|
|||
...PageInfo
|
||||
}
|
||||
}
|
||||
group {
|
||||
...GroupPackageSettings
|
||||
}
|
||||
}
|
||||
group(fullPath: $fullPath) @include(if: $isGroupPage) {
|
||||
id
|
||||
|
|
@ -67,6 +63,5 @@ query getPackages(
|
|||
...PageInfo
|
||||
}
|
||||
}
|
||||
...GroupPackageSettings
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { createAlert, VARIANT_INFO } from '~/alert';
|
|||
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import { historyReplaceState } from '~/lib/utils/common_utils';
|
||||
import * as Sentry from '~/sentry/sentry_browser_wrapper';
|
||||
import { s__ } from '~/locale';
|
||||
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages_and_registries/shared/constants';
|
||||
import {
|
||||
|
|
@ -15,6 +16,7 @@ import {
|
|||
PACKAGE_HELP_URL,
|
||||
} from '~/packages_and_registries/package_registry/constants';
|
||||
import getPackagesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql';
|
||||
import getGroupPackageSettings from '~/packages_and_registries/package_registry/graphql/queries/get_group_package_settings.query.graphql';
|
||||
import DeletePackages from '~/packages_and_registries/package_registry/components/functional/delete_packages.vue';
|
||||
import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue';
|
||||
import PackageSearch from '~/packages_and_registries/package_registry/components/list/package_search.vue';
|
||||
|
|
@ -41,7 +43,7 @@ export default {
|
|||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
inject: ['emptyListIllustration', 'isGroupPage', 'fullPath', 'settingsPath'],
|
||||
inject: ['emptyListIllustration', 'canDeletePackages', 'isGroupPage', 'fullPath', 'settingsPath'],
|
||||
data() {
|
||||
return {
|
||||
packagesResource: {},
|
||||
|
|
@ -49,6 +51,7 @@ export default {
|
|||
filters: {},
|
||||
isDeleteInProgress: false,
|
||||
pageParams: {},
|
||||
groupSettings: {},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
|
|
@ -65,16 +68,31 @@ export default {
|
|||
return !this.sort;
|
||||
},
|
||||
},
|
||||
groupSettings: {
|
||||
query: getGroupPackageSettings,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.fullPath,
|
||||
isGroupPage: this.isGroupPage,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
return this.isGroupPage
|
||||
? data[this.graphqlResource].packageSettings ?? {}
|
||||
: data[this.graphqlResource].group?.packageSettings ?? {};
|
||||
},
|
||||
skip() {
|
||||
return !(this.packagesCount > 0 && this.canDeletePackages);
|
||||
},
|
||||
error(error) {
|
||||
Sentry.captureException(error);
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
packages() {
|
||||
return this.packagesResource?.packages ?? {};
|
||||
},
|
||||
groupSettings() {
|
||||
return this.isGroupPage
|
||||
? this.packagesResource?.packageSettings ?? {}
|
||||
: this.packagesResource?.group?.packageSettings ?? {};
|
||||
},
|
||||
queryVariables() {
|
||||
return {
|
||||
isGroupPage: this.isGroupPage,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default {
|
|||
<gl-disclosure-dropdown
|
||||
:toggle-text="$options.i18n.QUICK_START"
|
||||
variant="confirm"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
@shown="track('click_dropdown')"
|
||||
>
|
||||
<div class="gl-px-3 gl-py-2">
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export default {
|
|||
v-model="sortOrder"
|
||||
:toggle-text="$options.sortOrderOptions[sortOrder].text"
|
||||
:items="Object.values($options.sortOrderOptions)"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
data-testid="performance-bar-sort-order"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export default {
|
|||
<gl-button-group>
|
||||
<gl-collapsible-listbox
|
||||
v-model="selectedSortOptionTitle"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="gl-z-1"
|
||||
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
|
||||
:toggle-text="selectedSortOptionTitle"
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ export default {
|
|||
|
||||
<gl-disclosure-dropdown
|
||||
data-testid="snippets-more-actions-dropdown"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
block
|
||||
@shown="onShowDropdown"
|
||||
@hidden="onHideDropdown"
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export default {
|
|||
v-model="selectedKey"
|
||||
data-testid="tags-dropdown"
|
||||
:items="sortOptionsListboxItems"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="selectedSortMethod"
|
||||
@select="visitUrlFromOption"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default {
|
|||
<gl-collapsible-listbox
|
||||
:items="filteredChanges"
|
||||
size="small"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
searchable
|
||||
@search="search"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<gl-disclosure-dropdown
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
toggle-text="Use an existing commit message"
|
||||
category="tertiary"
|
||||
:items="dropdownItems"
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
no-caret
|
||||
category="tertiary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
text-sr-only
|
||||
size="small"
|
||||
toggle-class="gl-p-2!"
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export default {
|
|||
<gl-collapsible-listbox
|
||||
ref="dropdown"
|
||||
v-model="alertStatus"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:header-text="headerText"
|
||||
:items="items"
|
||||
block
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ export default {
|
|||
:toggle-text="$options.i18n.defaultLabel"
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
class="code-dropdown gl-text-left"
|
||||
fluid-width
|
||||
data-testid="code-dropdown"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export default {
|
|||
<gl-disclosure-dropdown
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
block
|
||||
:toggle-text="$options.labels.defaultLabel"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-badge v-gl-tooltip :title="confidentialTooltip" variant="warning">
|
||||
<gl-badge v-gl-tooltip :title="confidentialTooltip" variant="warning" class="gl-shrink-0">
|
||||
<gl-icon name="eye-slash" :size="16" />
|
||||
<span data-testid="confidential-badge-text" :class="confidentialTextClass">{{
|
||||
__('Confidential')
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ export default {
|
|||
:toggle-text="$options.i18n.defaultLabel"
|
||||
:title="$options.i18n.defaultLabel"
|
||||
category="secondary"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
icon="download"
|
||||
text-sr-only
|
||||
fluid-width
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export default {
|
|||
<span v-if="textOnly" v-gl-tooltip="title">
|
||||
{{ __('Imported') }}
|
||||
</span>
|
||||
<gl-badge v-else v-gl-tooltip="title">
|
||||
<gl-badge v-else v-gl-tooltip="title" class="gl-shrink-0">
|
||||
{{ __('Imported') }}
|
||||
</gl-badge>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export default {
|
|||
no-caret
|
||||
:toggle-text="$options.i18n.actions"
|
||||
text-sr-only
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
category="tertiary"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default {
|
|||
<gl-disclosure-dropdown
|
||||
data-testid="apply-suggestion-dropdown"
|
||||
fluid-width
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
:toggle-text="dropdownText"
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ export default {
|
|||
v-gl-tooltip="showDropdownTooltip"
|
||||
:title="$options.i18n.mergeRequestActions"
|
||||
data-testid="dropdown-toggle"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
block
|
||||
class="gl-w-full"
|
||||
:auto-close="false"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import SettingsSection from './settings_section.vue';
|
||||
|
||||
export default {
|
||||
component: SettingsSection,
|
||||
title: 'vue_shared/settings/settings_section',
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
components: { SettingsSection },
|
||||
props: Object.keys(argTypes),
|
||||
template: `
|
||||
<settings-section v-bind="$props" heading="Settings section heading">
|
||||
<template #description>Settings section description</template>
|
||||
<template #default>
|
||||
<p>Settings section content</p>
|
||||
</template>
|
||||
</settings-section>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
props: {
|
||||
heading: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="settings-section">
|
||||
<div class="settings-sticky-header">
|
||||
<div class="settings-sticky-header-inner">
|
||||
<h2 class="gl-heading-2 !gl-mb-2">
|
||||
<slot v-if="$scopedSlots.heading" name="heading"></slot>
|
||||
<template v-else>{{ heading }}</template>
|
||||
</h2>
|
||||
<p v-if="$scopedSlots.description || description" class="gl-text-secondary gl-m-0">
|
||||
<slot v-if="$scopedSlots.description" name="description"></slot>
|
||||
<template v-else>{{ description }}</template>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
|
@ -55,6 +55,6 @@ export default {
|
|||
:loading="loading"
|
||||
icon="download"
|
||||
size="small"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
|
|||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import { setNewWorkItemCache } from '~/work_items/graphql/cache_utils';
|
||||
import { findWidget } from '~/issues/list/utils';
|
||||
import { newWorkItemFullPath, isWorkItemItemValidEnum } from '~/work_items/utils';
|
||||
import { newWorkItemFullPath } from '~/work_items/utils';
|
||||
import {
|
||||
I18N_WORK_ITEM_CREATE_BUTTON_LABEL,
|
||||
I18N_WORK_ITEM_ERROR_CREATING,
|
||||
|
|
@ -79,7 +79,6 @@ export default {
|
|||
selectedWorkItemTypeId: null,
|
||||
loading: false,
|
||||
showWorkItemTypeSelect: false,
|
||||
newWorkItemPath: newWorkItemFullPath(this.fullPath),
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
|
|
@ -94,7 +93,7 @@ export default {
|
|||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.fullPath;
|
||||
return !this.fullPath || !this.selectedWorkItemTypeName;
|
||||
},
|
||||
update(data) {
|
||||
return data?.workspace?.workItem ?? {};
|
||||
|
|
@ -119,13 +118,22 @@ export default {
|
|||
update(data) {
|
||||
return data.workspace?.workItemTypes?.nodes;
|
||||
},
|
||||
result() {
|
||||
async result() {
|
||||
if (!this.workItemTypes?.length) {
|
||||
return;
|
||||
}
|
||||
if (this.workItemTypes?.length === 1) {
|
||||
this.selectedWorkItemTypeId = this.workItemTypes[0].id;
|
||||
} else {
|
||||
this.workItemTypes.forEach(async (workItemType) => {
|
||||
await setNewWorkItemCache(
|
||||
this.isGroup,
|
||||
this.fullPath,
|
||||
workItemType?.widgetDefinitions,
|
||||
workItemType.name,
|
||||
workItemType.id,
|
||||
);
|
||||
});
|
||||
this.showWorkItemTypeSelect = true;
|
||||
}
|
||||
},
|
||||
|
|
@ -135,6 +143,9 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
newWorkItemPath() {
|
||||
return newWorkItemFullPath(this.fullPath, this.selectedWorkItemTypeName);
|
||||
},
|
||||
isLoading() {
|
||||
return this.$apollo.queries.workItemTypes.loading || this.$apollo.queries.workItem.loading;
|
||||
},
|
||||
|
|
@ -161,27 +172,28 @@ export default {
|
|||
selectedWorkItemType() {
|
||||
return this.workItemTypes?.find((item) => item.id === this.selectedWorkItemTypeId);
|
||||
},
|
||||
selectedWorkItemTypeName() {
|
||||
return this.selectedWorkItemType?.name;
|
||||
},
|
||||
formOptions() {
|
||||
return [{ value: null, text: s__('WorkItem|Select type') }, ...this.workItemTypesForSelect];
|
||||
},
|
||||
createErrorText() {
|
||||
const workItemType = this.selectedWorkItemType?.name;
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_ERROR_CREATING, workItemType);
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_ERROR_CREATING, this.selectedWorkItemTypeName);
|
||||
},
|
||||
createWorkItemText() {
|
||||
const workItemType = this.selectedWorkItemType?.name;
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_CREATE_BUTTON_LABEL, workItemType);
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_CREATE_BUTTON_LABEL, this.selectedWorkItemTypeName);
|
||||
},
|
||||
makeConfidentialText() {
|
||||
return sprintfWorkItem(
|
||||
s__(
|
||||
'WorkItem|This %{workItemType} is confidential and should only be visible to users having at least Reporter access.',
|
||||
),
|
||||
this.selectedWorkItemType?.name,
|
||||
this.selectedWorkItemTypeName,
|
||||
);
|
||||
},
|
||||
titleText() {
|
||||
return sprintfWorkItem(s__('WorkItem|New %{workItemType}'), this.selectedWorkItemType?.name);
|
||||
return sprintfWorkItem(s__('WorkItem|New %{workItemType}'), this.selectedWorkItemTypeName);
|
||||
},
|
||||
canUpdate() {
|
||||
return this.workItem?.userPermissions?.updateWorkItem;
|
||||
|
|
@ -228,17 +240,6 @@ export default {
|
|||
const title = newValue || this.workItemTitle;
|
||||
this.isTitleValid = Boolean(title.trim());
|
||||
},
|
||||
updateCache() {
|
||||
if (!this.selectedWorkItemTypeId || !isWorkItemItemValidEnum(this.workItemType)) {
|
||||
return;
|
||||
}
|
||||
setNewWorkItemCache(
|
||||
this.isGroup,
|
||||
this.fullPath,
|
||||
this.selectedWorkItemType?.widgetDefinitions,
|
||||
this.workItemType,
|
||||
);
|
||||
},
|
||||
async updateDraftData(type, value) {
|
||||
if (type === 'title') {
|
||||
this.validate(value);
|
||||
|
|
@ -251,6 +252,7 @@ export default {
|
|||
input: {
|
||||
isGroup: this.isGroup,
|
||||
fullPath: this.fullPath,
|
||||
workItemType: this.selectedWorkItemTypeName || this.workItemTypeName,
|
||||
[type]: value,
|
||||
},
|
||||
},
|
||||
|
|
@ -367,98 +369,100 @@ export default {
|
|||
v-model="selectedWorkItemTypeId"
|
||||
:options="formOptions"
|
||||
class="gl-max-w-26"
|
||||
@change="updateCache"
|
||||
/>
|
||||
</gl-form-group>
|
||||
</div>
|
||||
<work-item-title
|
||||
ref="title"
|
||||
data-testid="title-input"
|
||||
is-editing
|
||||
:is-valid="isTitleValid"
|
||||
:title="workItemTitle"
|
||||
@updateDraft="updateDraftData('title', $event)"
|
||||
@updateWorkItem="createWorkItem"
|
||||
/>
|
||||
<div data-testid="work-item-overview" class="work-item-overview">
|
||||
<section>
|
||||
<work-item-description
|
||||
edit-mode
|
||||
:autofocus="false"
|
||||
:full-path="fullPath"
|
||||
create-flow
|
||||
:show-buttons-below-field="false"
|
||||
:work-item-id="$options.NEW_WORK_ITEM_GID"
|
||||
:work-item-iid="$options.NEW_WORK_ITEM_IID"
|
||||
@error="updateError = $event"
|
||||
@updateDraft="updateDraftData('description', $event)"
|
||||
/>
|
||||
<gl-form-group :label="__('Confidentiality')" label-for="work-item-confidential">
|
||||
<gl-form-checkbox
|
||||
id="work-item-confidential"
|
||||
v-model="isConfidential"
|
||||
data-testid="confidential-checkbox"
|
||||
@change="updateDraftData('confidential', $event)"
|
||||
>
|
||||
{{ makeConfidentialText }}
|
||||
</gl-form-checkbox>
|
||||
</gl-form-group>
|
||||
</section>
|
||||
<aside
|
||||
v-if="hasWidgets"
|
||||
data-testid="work-item-overview-right-sidebar"
|
||||
class="work-item-overview-right-sidebar"
|
||||
:class="{ 'is-modal': true }"
|
||||
>
|
||||
<template v-if="workItemAssignees">
|
||||
<work-item-assignees
|
||||
class="gl-mb-5 js-assignee"
|
||||
:can-update="canUpdate"
|
||||
<div v-if="selectedWorkItemTypeId" data-testid="create-work-item">
|
||||
<work-item-title
|
||||
ref="title"
|
||||
data-testid="title-input"
|
||||
is-editing
|
||||
:is-valid="isTitleValid"
|
||||
:title="workItemTitle"
|
||||
@updateDraft="updateDraftData('title', $event)"
|
||||
@updateWorkItem="createWorkItem"
|
||||
/>
|
||||
<div data-testid="work-item-overview" class="work-item-overview">
|
||||
<section>
|
||||
<work-item-description
|
||||
edit-mode
|
||||
:autofocus="false"
|
||||
:full-path="fullPath"
|
||||
:work-item-id="workItem.id"
|
||||
:assignees="workItemAssignees.assignees.nodes"
|
||||
:participants="workItemParticipantNodes"
|
||||
:work-item-author="workItemAuthor"
|
||||
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
|
||||
:work-item-type="workItemType"
|
||||
:can-invite-members="workItemAssignees.canInviteMembers"
|
||||
@error="$emit('error', $event)"
|
||||
create-flow
|
||||
:show-buttons-below-field="false"
|
||||
:work-item-id="$options.NEW_WORK_ITEM_GID"
|
||||
:work-item-iid="$options.NEW_WORK_ITEM_IID"
|
||||
:work-item-type-name="selectedWorkItemTypeName"
|
||||
@error="updateError = $event"
|
||||
@updateDraft="updateDraftData('description', $event)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="workItemHealthStatus">
|
||||
<work-item-health-status
|
||||
class="gl-mb-5"
|
||||
:health-status="workItemHealthStatus.healthStatus"
|
||||
:can-update="canUpdate"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
:work-item-type="workItemType"
|
||||
:full-path="fullPath"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="workItemColor">
|
||||
<work-item-color
|
||||
class="gl-mb-5"
|
||||
:work-item="workItem"
|
||||
:full-path="fullPath"
|
||||
:can-update="canUpdate"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</template>
|
||||
</aside>
|
||||
<div class="gl-py-3 gl-flex gl-gap-3 gl-col-start-1">
|
||||
<gl-button
|
||||
variant="confirm"
|
||||
:loading="loading"
|
||||
data-testid="create-button"
|
||||
@click="createWorkItem"
|
||||
<gl-form-group :label="__('Confidentiality')" label-for="work-item-confidential">
|
||||
<gl-form-checkbox
|
||||
id="work-item-confidential"
|
||||
v-model="isConfidential"
|
||||
data-testid="confidential-checkbox"
|
||||
@change="updateDraftData('confidential', $event)"
|
||||
>
|
||||
{{ makeConfidentialText }}
|
||||
</gl-form-checkbox>
|
||||
</gl-form-group>
|
||||
</section>
|
||||
<aside
|
||||
v-if="hasWidgets"
|
||||
data-testid="work-item-overview-right-sidebar"
|
||||
class="work-item-overview-right-sidebar"
|
||||
:class="{ 'is-modal': true }"
|
||||
>
|
||||
{{ createWorkItemText }}
|
||||
</gl-button>
|
||||
<gl-button type="button" data-testid="cancel-button" @click="handleCancelClick">
|
||||
{{ __('Cancel') }}
|
||||
</gl-button>
|
||||
<template v-if="workItemAssignees">
|
||||
<work-item-assignees
|
||||
class="gl-mb-5 js-assignee"
|
||||
:can-update="canUpdate"
|
||||
:full-path="fullPath"
|
||||
:work-item-id="workItem.id"
|
||||
:assignees="workItemAssignees.assignees.nodes"
|
||||
:participants="workItemParticipantNodes"
|
||||
:work-item-author="workItemAuthor"
|
||||
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
|
||||
:work-item-type="selectedWorkItemTypeName"
|
||||
:can-invite-members="workItemAssignees.canInviteMembers"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="workItemHealthStatus">
|
||||
<work-item-health-status
|
||||
class="gl-mb-5"
|
||||
:health-status="workItemHealthStatus.healthStatus"
|
||||
:can-update="canUpdate"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
:work-item-type="selectedWorkItemTypeName"
|
||||
:full-path="fullPath"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="workItemColor">
|
||||
<work-item-color
|
||||
class="gl-mb-5"
|
||||
:work-item="workItem"
|
||||
:full-path="fullPath"
|
||||
:can-update="canUpdate"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</template>
|
||||
</aside>
|
||||
<div class="gl-py-3 gl-flex gl-gap-3 gl-col-start-1">
|
||||
<gl-button
|
||||
variant="confirm"
|
||||
:loading="loading"
|
||||
data-testid="create-button"
|
||||
@click="createWorkItem"
|
||||
>
|
||||
{{ createWorkItemText }}
|
||||
</gl-button>
|
||||
<gl-button type="button" data-testid="cancel-button" @click="handleCancelClick">
|
||||
{{ __('Cancel') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ export default {
|
|||
:disabled="loading"
|
||||
:items="items"
|
||||
:selected="sortFilterProp"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
size="small"
|
||||
@select="fetchFilteredDiscussions"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ export default {
|
|||
v-gl-tooltip
|
||||
icon="ellipsis_v"
|
||||
text-sr-only
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:toggle-text="$options.i18n.moreActionsText"
|
||||
:title="$options.i18n.moreActionsText"
|
||||
category="tertiary"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { unionBy } from 'lodash';
|
||||
import { sortNameAlphabetically } from '~/work_items/utils';
|
||||
import { sortNameAlphabetically, newWorkItemId } from '~/work_items/utils';
|
||||
import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphql';
|
||||
import usersSearchQuery from '~/graphql_shared/queries/workspace_autocomplete_users.query.graphql';
|
||||
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
|
||||
|
|
@ -12,7 +12,7 @@ import { s__, sprintf, __ } from '~/locale';
|
|||
import Tracking from '~/tracking';
|
||||
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
|
||||
import updateNewWorkItemMutation from '../graphql/update_new_work_item.mutation.graphql';
|
||||
import { i18n, TRACKING_CATEGORY_SHOW, NEW_WORK_ITEM_GID } from '../constants';
|
||||
import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -236,12 +236,13 @@ export default {
|
|||
this.updateInProgress = true;
|
||||
const { localAssigneeIds } = this;
|
||||
|
||||
if (this.workItemId === NEW_WORK_ITEM_GID) {
|
||||
if (this.workItemId === newWorkItemId(this.workItemType)) {
|
||||
this.$apollo.mutate({
|
||||
mutation: updateNewWorkItemMutation,
|
||||
variables: {
|
||||
input: {
|
||||
isGroup: this.isGroup,
|
||||
workItemType: this.workItemType,
|
||||
fullPath: this.fullPath,
|
||||
assignees: this.localAssignees,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
workItemTypeName: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
markdownDocsPath: helpPagePath('user/markdown'),
|
||||
data() {
|
||||
|
|
@ -99,7 +104,7 @@ export default {
|
|||
},
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.createFlow ? newWorkItemFullPath(this.fullPath) : this.fullPath,
|
||||
fullPath: this.workItemFullPath,
|
||||
iid: this.workItemIid,
|
||||
};
|
||||
},
|
||||
|
|
@ -117,6 +122,11 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
workItemFullPath() {
|
||||
return this.createFlow
|
||||
? newWorkItemFullPath(this.fullPath, this.workItemTypeName)
|
||||
: this.fullPath;
|
||||
},
|
||||
autosaveKey() {
|
||||
return this.workItemId || `new-${this.workItemType}-description-draft`;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default {
|
|||
<gl-disclosure-dropdown
|
||||
:toggle-text="__('Add')"
|
||||
size="small"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
:items="actions"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ export default {
|
|||
/>
|
||||
<gl-disclosure-dropdown
|
||||
v-if="canUpdate && canAddTask"
|
||||
placement="right"
|
||||
placement="bottom-end"
|
||||
size="small"
|
||||
:toggle-text="$options.i18n.addChildButtonLabel"
|
||||
data-testid="toggle-form"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@ import { TYPENAME_USER } from '~/graphql_shared/constants';
|
|||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { getBaseURL } from '~/lib/utils/url_utility';
|
||||
import { convertEachWordToTitleCase } from '~/lib/utils/text_utility';
|
||||
import { findHierarchyWidgetChildren, isNotesWidget, newWorkItemFullPath } from '../utils';
|
||||
import {
|
||||
findHierarchyWidgetChildren,
|
||||
isNotesWidget,
|
||||
newWorkItemFullPath,
|
||||
newWorkItemId,
|
||||
} from '../utils';
|
||||
import {
|
||||
WIDGET_TYPE_ASSIGNEES,
|
||||
WIDGET_TYPE_COLOR,
|
||||
|
|
@ -23,7 +28,6 @@ import {
|
|||
WIDGET_TYPE_HEALTH_STATUS,
|
||||
WIDGET_TYPE_DESCRIPTION,
|
||||
NEW_WORK_ITEM_IID,
|
||||
NEW_WORK_ITEM_GID,
|
||||
} from '../constants';
|
||||
import groupWorkItemByIidQuery from './group_work_item_by_iid.query.graphql';
|
||||
import workItemByIidQuery from './work_item_by_iid.query.graphql';
|
||||
|
|
@ -265,8 +269,8 @@ export const setNewWorkItemCache = async (
|
|||
);
|
||||
widgets.push({
|
||||
type: 'ASSIGNEES',
|
||||
allowsMultipleAssignees: assigneesWidgetData.allowsMultipleAssignees,
|
||||
canInviteMembers: assigneesWidgetData.canInviteMembers,
|
||||
allowsMultipleAssignees: assigneesWidgetData.allowsMultipleAssignees || false,
|
||||
canInviteMembers: assigneesWidgetData.canInviteMembers || false,
|
||||
assignees: {
|
||||
nodes: [],
|
||||
__typename: 'UserCoreConnection',
|
||||
|
|
@ -398,17 +402,19 @@ export const setNewWorkItemCache = async (
|
|||
? issuesListApolloProvider
|
||||
: apolloProvider;
|
||||
|
||||
const newWorkItemPath = newWorkItemFullPath(fullPath, workItemType);
|
||||
|
||||
cacheProvider.clients.defaultClient.cache.writeQuery({
|
||||
query: isGroup ? groupWorkItemByIidQuery : workItemByIidQuery,
|
||||
variables: {
|
||||
fullPath: newWorkItemFullPath(fullPath),
|
||||
fullPath: newWorkItemPath,
|
||||
iid: NEW_WORK_ITEM_IID,
|
||||
},
|
||||
data: {
|
||||
workspace: {
|
||||
id: newWorkItemFullPath(fullPath),
|
||||
id: newWorkItemPath,
|
||||
workItem: {
|
||||
id: NEW_WORK_ITEM_GID,
|
||||
id: newWorkItemId(workItemType),
|
||||
iid: NEW_WORK_ITEM_IID,
|
||||
archived: false,
|
||||
title: '',
|
||||
|
|
@ -422,9 +428,9 @@ export const setNewWorkItemCache = async (
|
|||
reference: '',
|
||||
createNoteEmail: null,
|
||||
namespace: {
|
||||
id: newWorkItemFullPath(fullPath),
|
||||
id: newWorkItemPath,
|
||||
fullPath,
|
||||
name: newWorkItemFullPath(fullPath),
|
||||
name: newWorkItemPath,
|
||||
__typename: 'Namespace', // eslint-disable-line @gitlab/require-i18n-strings
|
||||
},
|
||||
author: {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ extend type Mutation {
|
|||
|
||||
input LocalUpdateNewWorkItemInput {
|
||||
fullPath: String!
|
||||
workItemType: String!
|
||||
isGroup: Boolean!
|
||||
healthStatus: String
|
||||
assignees: [LocalUserInput]
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import {
|
|||
WORK_ITEM_TYPE_ENUM_OBJECTIVE,
|
||||
WORK_ITEM_TYPE_ENUM_KEY_RESULT,
|
||||
WORK_ITEM_TYPE_ENUM_REQUIREMENTS,
|
||||
NEW_WORK_ITEM_GID,
|
||||
} from './constants';
|
||||
|
||||
export const isAssigneesWidget = (widget) => widget.type === WIDGET_TYPE_ASSIGNEES;
|
||||
|
|
@ -156,11 +157,15 @@ export const workItemRoadmapPath = (fullPath, iid) => {
|
|||
* Builds unique path for new work item
|
||||
*
|
||||
* @param {string} fullPath the path to the namespace
|
||||
* @param {string} workItemType the type of work item
|
||||
*/
|
||||
|
||||
export const newWorkItemFullPath = (fullPath) => {
|
||||
export const newWorkItemFullPath = (fullPath, workItemType) => {
|
||||
if (!workItemType) return undefined;
|
||||
|
||||
const workItemTypeLowercase = workItemType.split(' ').join('-').toLowerCase();
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
return `${fullPath}-id`;
|
||||
return `${fullPath}-${workItemTypeLowercase}-id`;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -183,3 +188,10 @@ export const isWorkItemItemValidEnum = (workItemType) => {
|
|||
].indexOf(workItemType) >= 0
|
||||
);
|
||||
};
|
||||
|
||||
export const newWorkItemId = (workItemType) => {
|
||||
if (!workItemType) return undefined;
|
||||
|
||||
const workItemTypeLowercase = workItemType.split(' ').join('-').toLowerCase();
|
||||
return `${NEW_WORK_ITEM_GID}-${workItemTypeLowercase}`;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
.gl-grow
|
||||
%h2{ class: title_classes }
|
||||
= heading || @heading
|
||||
%p.gl-text-secondary.gl-m-0
|
||||
= description || @description
|
||||
- if description || @description
|
||||
%p.gl-text-secondary.gl-m-0
|
||||
= description || @description
|
||||
.gl-shrink-0.gl-px-2
|
||||
= render Pajamas::ButtonComponent.new(button_options: @button_options.merge(class: 'gl-min-w-12 js-settings-toggle')) do
|
||||
= button_text
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
%section.settings-section{ id: @id, data: (@testid ? { testid: @testid } : {}) }
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h2.gl-heading-2{ class: '!gl-mb-2' }
|
||||
= heading || @heading
|
||||
- if description || @description
|
||||
%p.gl-text-secondary.gl-m-0
|
||||
= description || @description
|
||||
%div{ data: { testid: 'settings-section-body' } }
|
||||
= body
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Layouts
|
||||
class SettingsSectionComponent < ViewComponent::Base
|
||||
# @param [String] heading
|
||||
# @param [String] description
|
||||
# @param [String] id
|
||||
# @param [String] testid
|
||||
def initialize(heading, description: nil, id: nil, testid: nil)
|
||||
@heading = heading
|
||||
@description = description
|
||||
@id = id
|
||||
@testid = testid
|
||||
end
|
||||
|
||||
renders_one :heading
|
||||
renders_one :description
|
||||
renders_one :body
|
||||
end
|
||||
end
|
||||
|
|
@ -20,7 +20,7 @@ module ProtectedRef
|
|||
end
|
||||
|
||||
def commit
|
||||
project.commit(self.name)
|
||||
project&.commit(name)
|
||||
end
|
||||
|
||||
class_methods do
|
||||
|
|
@ -59,7 +59,7 @@ module ProtectedRef
|
|||
end
|
||||
|
||||
def access_levels_for_ref(ref, action:, protected_refs: nil)
|
||||
self.matching(ref, protected_refs: protected_refs)
|
||||
matching(ref, protected_refs: protected_refs)
|
||||
.flat_map(&:"#{action}_access_levels")
|
||||
end
|
||||
|
||||
|
|
@ -70,14 +70,14 @@ module ProtectedRef
|
|||
# This method optionally takes in a list of `protected_refs` to search
|
||||
# through, to avoid calling out to the database.
|
||||
def matching(ref_name, protected_refs: nil)
|
||||
(protected_refs || self.all).select { |protected_ref| protected_ref.matches?(ref_name) }
|
||||
(protected_refs || all).select { |protected_ref| protected_ref.matches?(ref_name) }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ref_matcher
|
||||
@ref_matcher ||= RefMatcher.new(self.name)
|
||||
@ref_matcher ||= RefMatcher.new(name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ class ProtectedBranch < ApplicationRecord
|
|||
belongs_to :group, foreign_key: :namespace_id, touch: true, inverse_of: :protected_branches
|
||||
|
||||
validate :validate_either_project_or_top_group
|
||||
validates :name, presence: true
|
||||
validates :name, uniqueness: { scope: [:project_id, :namespace_id] }, if: :name_changed?
|
||||
|
||||
scope :requiring_code_owner_approval, -> { where(code_owner_approval_required: true) }
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ module Ci
|
|||
def execute
|
||||
in_lock(EXCLUSIVE_LOCK_KEY, ttl: LOCK_TIMEOUT, retries: 1) do
|
||||
destroy_unlocked_pipeline_artifacts
|
||||
|
||||
legacy_destroy_pipeline_artifacts
|
||||
end
|
||||
|
||||
@removed_artifacts_count
|
||||
|
|
@ -40,19 +38,6 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def legacy_destroy_pipeline_artifacts
|
||||
loop_until(timeout: LOOP_TIMEOUT, limit: LOOP_LIMIT) do
|
||||
destroy_artifacts_batch
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_artifacts_batch
|
||||
artifacts = ::Ci::PipelineArtifact.unlocked.expired.limit(BATCH_SIZE).to_a
|
||||
return false if artifacts.empty?
|
||||
|
||||
destroy_batch(artifacts)
|
||||
end
|
||||
|
||||
def destroy_batch(artifacts)
|
||||
artifacts.each(&:destroy!)
|
||||
increment_stats(artifacts.size)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
- if Gitlab.config.packages.enabled
|
||||
%section.settings.as-package.no-animate#js-package-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Package Registry')
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
= expanded_by_default? ? _('Collapse') : _('Expand')
|
||||
%p.gl-text-secondary
|
||||
= s_('PackageRegistry|Configure package forwarding and package file size limits.')
|
||||
|
||||
.settings-content
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Package Registry'),
|
||||
id: 'js-package-settings',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
= s_('PackageRegistry|Configure package forwarding and package file size limits.')
|
||||
- c.with_body do
|
||||
= render_if_exists 'admin/application_settings/ee_package_registry'
|
||||
= render 'admin/application_settings/nuget_skip_metadata_url_validation' unless Gitlab.ee?
|
||||
|
||||
|
||||
.gl-mt-7
|
||||
%h4
|
||||
= _('Package file size limits')
|
||||
|
|
|
|||
|
|
@ -3,161 +3,140 @@
|
|||
= gitlab_ui_form_for @appearance, url: admin_application_settings_appearances_path, html: { class: 'gl-mt-3' } do |f|
|
||||
= form_errors(@appearance)
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0 Favicon
|
||||
|
||||
.form-group
|
||||
= f.label :favicon, _('Favicon'), class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.favicon?
|
||||
= image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Favicon')) do |c|
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :favicon, _('Favicon'), class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.favicon?
|
||||
= image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: favicon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Favicon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove favicon') } }) do
|
||||
= _('Remove favicon')
|
||||
%hr
|
||||
= f.hidden_field :favicon_cache
|
||||
= f.file_field :favicon, class: '', accept: 'image/*'
|
||||
.form-text.gl-text-secondary
|
||||
= _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_allowlist}.") % { favicon_extension_allowlist: favicon_extension_allowlist }
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: favicon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Favicon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove favicon') } }) do
|
||||
= _('Remove favicon')
|
||||
%hr
|
||||
= f.hidden_field :favicon_cache
|
||||
= f.file_field :favicon, class: '', accept: 'image/*'
|
||||
.form-text.text-muted
|
||||
= _("Maximum file size is 1 MB. Image size must be 32 x 32 pixels. Allowed image formats are %{favicon_extension_allowlist}.") % { favicon_extension_allowlist: favicon_extension_allowlist }
|
||||
%br
|
||||
= _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
|
||||
= _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('Member guidelines')
|
||||
|
||||
.form-text.text-muted
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Member guidelines')) do |c|
|
||||
- c.with_description do
|
||||
= _('These guidelines are displayed on the group\'s or project\'s members page, and are visible to users who can manage team member permissions.')
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :member_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :member_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.gl-text-secondary
|
||||
= parsed_with_gfm
|
||||
|
||||
.form-group
|
||||
= f.label :member_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :member_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.text-muted
|
||||
= parsed_with_gfm
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Navigation bar')) do |c|
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :header_logo, _('Header logo'), class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.header_logo?
|
||||
= image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: header_logos_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Header logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove header logo') } }) do
|
||||
= _('Remove header logo')
|
||||
%hr
|
||||
= f.hidden_field :header_logo_cache
|
||||
= f.file_field :header_logo, class: "", accept: 'image/*'
|
||||
.form-text.gl-text-secondary
|
||||
= _('Maximum file size is 1MB. Pages are optimized for a 24px tall header logo')
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('Navigation bar')
|
||||
|
||||
.form-group
|
||||
= f.label :header_logo, _('Header logo'), class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.header_logo?
|
||||
= image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: header_logos_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Header logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove header logo') } }) do
|
||||
= _('Remove header logo')
|
||||
%hr
|
||||
= f.hidden_field :header_logo_cache
|
||||
= f.file_field :header_logo, class: "", accept: 'image/*'
|
||||
.form-text.text-muted
|
||||
= _('Maximum file size is 1MB. Pages are optimized for a 24px tall header logo')
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('New project pages')) do |c|
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :new_project_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :new_project_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.gl-text-secondary
|
||||
= parsed_with_gfm
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('New project pages')
|
||||
|
||||
.form-group
|
||||
= f.label :new_project_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :new_project_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.text-muted
|
||||
= parsed_with_gfm
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('Profile image guidelines')
|
||||
|
||||
%p.gl-text-secondary
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Profile image guidelines')) do |c|
|
||||
- c.with_description do
|
||||
= _('These guidelines for public avatars are displayed on the user settings page.')
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :profile_image_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :profile_image_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.gl-text-secondary
|
||||
= parsed_with_gfm
|
||||
|
||||
.form-group
|
||||
= f.label :profile_image_guidelines, class: 'col-form-label'
|
||||
%p
|
||||
= f.text_area :profile_image_guidelines, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.text-muted
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Progressive Web App (PWA)')) do |c|
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label _("Name"), class: 'col-form-label'
|
||||
= f.text_field :pwa_name, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label _("Short name"), class: 'col-form-label'
|
||||
= f.text_field :pwa_short_name, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label _("Description"), class: 'col-form-label'
|
||||
= f.text_area :pwa_description, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.gl-text-secondary
|
||||
= parsed_with_gfm
|
||||
.form-group
|
||||
= f.label :pwa_icon, class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.pwa_icon?
|
||||
= image_tag @appearance.pwa_icon_path, class: 'appearance-pwa-icon-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: pwa_icon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Icon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove icon') } }) do
|
||||
= _('Remove icon')
|
||||
%hr
|
||||
= f.hidden_field :pwa_icon_cache
|
||||
= f.file_field :pwa_icon, class: "", accept: 'image/*'
|
||||
.form-text.gl-text-secondary
|
||||
= _('Maximum file size is 1MB.')
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('Progressive Web App (PWA)')
|
||||
|
||||
.form-group
|
||||
= f.label _("Name"), class: 'col-form-label'
|
||||
= f.text_field :pwa_name, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label _("Short name"), class: 'col-form-label'
|
||||
= f.text_field :pwa_short_name, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label _("Description"), class: 'col-form-label'
|
||||
= f.text_area :pwa_description, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.text-muted
|
||||
= parsed_with_gfm
|
||||
.form-group
|
||||
= f.label :pwa_icon, class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.pwa_icon?
|
||||
= image_tag @appearance.pwa_icon_path, class: 'appearance-pwa-icon-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: pwa_icon_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Icon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove icon') } }) do
|
||||
= _('Remove icon')
|
||||
%hr
|
||||
= f.hidden_field :pwa_icon_cache
|
||||
= f.file_field :pwa_icon, class: "", accept: 'image/*'
|
||||
.form-text.text-muted
|
||||
= _('Maximum file size is 1MB.')
|
||||
|
||||
.settings-section
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0= _('Sign in/Sign up pages')
|
||||
|
||||
.form-group
|
||||
= f.label :title, class: 'col-form-label'
|
||||
= f.text_field :title, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label :description, class: 'col-form-label'
|
||||
= f.text_area :description, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.text-muted
|
||||
= parsed_with_gfm
|
||||
.form-group
|
||||
= f.label :logo, class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.logo?
|
||||
= image_tag @appearance.logo_path, class: 'appearance-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: logo_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove logo') } }) do
|
||||
= _('Remove logo')
|
||||
%hr
|
||||
= f.hidden_field :logo_cache
|
||||
= f.file_field :logo, class: "", accept: 'image/*'
|
||||
.form-text.text-muted
|
||||
= _('Maximum file size is 1 MB. Pages are optimized for a 128x128 px logo.')
|
||||
= render ::Layouts::SettingsSectionComponent.new(_('Sign in/Sign up pages')) do |c|
|
||||
- c.with_body do
|
||||
.form-group
|
||||
= f.label :title, class: 'col-form-label'
|
||||
= f.text_field :title, class: "form-control gl-form-input"
|
||||
.form-group
|
||||
= f.label :description, class: 'col-form-label'
|
||||
= f.text_area :description, class: "form-control gl-form-input", rows: 10
|
||||
.form-text.gl-text-secondary
|
||||
= parsed_with_gfm
|
||||
.form-group
|
||||
= f.label :logo, class: 'col-form-label gl-pt-0'
|
||||
%p
|
||||
- if @appearance.logo?
|
||||
= image_tag @appearance.logo_path, class: 'appearance-logo-preview'
|
||||
- if @appearance.persisted?
|
||||
%br
|
||||
= render Pajamas::ButtonComponent.new(variant: :danger, category: :secondary, size: :small, method: :delete, href: logo_admin_application_settings_appearances_path, button_options: { data: { confirm: _("Logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove logo') } }) do
|
||||
= _('Remove logo')
|
||||
%hr
|
||||
= f.hidden_field :logo_cache
|
||||
= f.file_field :logo, class: "", accept: 'image/*'
|
||||
.form-text.gl-text-secondary
|
||||
= _('Maximum file size is 1 MB. Pages are optimized for a 128x128 px logo.')
|
||||
|
||||
= render partial: 'admin/application_settings/appearances/system_header_footer_form', locals: { form: f }
|
||||
|
||||
- if @appearance.persisted? || @appearance.updated_at
|
||||
.settings-section
|
||||
- if @appearance.persisted?
|
||||
Preview last save:
|
||||
= s_('AppearanceSettings|Preview last save:')
|
||||
= link_to _('Sign-in page'), preview_sign_in_admin_application_settings_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
|
||||
= link_to _('New project page'), new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
- if @appearance.updated_at
|
||||
%span.gl-float-right
|
||||
Last edit #{time_ago_with_tooltip(@appearance.updated_at)}
|
||||
%span.gl-float-right.gl-text-secondary
|
||||
= s_('AppearanceSettings|Last edit')
|
||||
#{time_ago_with_tooltip(@appearance.updated_at)}
|
||||
|
||||
.settings-sticky-footer
|
||||
= f.submit _('Update appearance settings'), pajamas_button: true
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
- expanded = local_assigns.fetch(:expanded)
|
||||
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Variables')
|
||||
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
= expanded ? _('Collapse') : _('Expand')
|
||||
|
||||
%p.gl-text-secondary
|
||||
= s_('CiVariables|Variables store information that you can use in job scripts. All projects on the instance can use these variables.')
|
||||
= link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'for-an-instance'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
|
@ -3,10 +3,13 @@
|
|||
- add_page_specific_style 'page_bundles/settings'
|
||||
- @force_desktop_expanded_sidebar = true
|
||||
|
||||
%section.settings.no-animate#js-ci-cd-variables{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
= render 'admin/application_settings/ci/header', expanded: expanded_by_default?
|
||||
.settings-content
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Variables'),
|
||||
id: 'js-ci-cd-variables',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
= s_('CiVariables|Variables store information that you can use in job scripts. All projects on the instance can use these variables.')
|
||||
= link_to _('Learn more.'), help_page_path('ci/variables/index', anchor: 'for-an-instance'), target: '_blank', rel: 'noopener noreferrer'
|
||||
- c.with_body do
|
||||
= render 'ci/variables/attributes'
|
||||
- if ci_variable_protected_by_default?
|
||||
%p.settings-message.gl-text-center
|
||||
|
|
@ -14,35 +17,32 @@
|
|||
= safe_format(s_('Environment variables on this GitLab instance are configured to be %{help_link_start}protected%{help_link_end} by default.'), tag_pair(help_link, :help_link_start, :help_link_end))
|
||||
#js-instance-variables{ data: { endpoint: admin_ci_variables_path, maskable_regex: ci_variable_maskable_regex, protected_by_default: ci_variable_protected_by_default?.to_s} }
|
||||
|
||||
%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Continuous Integration and Deployment')
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
= expanded_by_default? ? _('Collapse') : _('Expand')
|
||||
%p.gl-text-secondary
|
||||
= _('Customize CI/CD settings, including Auto DevOps, instance runners, and job artifacts.')
|
||||
= render 'ci_cd'
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Continuous Integration and Deployment'),
|
||||
id: 'js-continuous-integration-settings',
|
||||
testid: 'ci-cd-settings',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
= _('Customize CI/CD settings, including Auto DevOps, instance runners, and job artifacts.')
|
||||
- c.with_body do
|
||||
= render 'ci_cd'
|
||||
|
||||
= render_if_exists 'admin/application_settings/package_registry', expanded: expanded_by_default?
|
||||
|
||||
- if Gitlab.config.registry.enabled
|
||||
%section.settings.as-registry.no-animate#js-registry-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Container Registry')
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
= expanded_by_default? ? _('Collapse') : _('Expand')
|
||||
%p.gl-text-secondary
|
||||
= _('Various container registry settings.')
|
||||
.settings-content
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Container Registry'),
|
||||
id: 'js-registry-settings',
|
||||
testid: 'registry-settings',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
= _('Various container registry settings.')
|
||||
- c.with_body do
|
||||
= render 'registry'
|
||||
|
||||
%section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= s_('Runners|Runners')
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
= expanded_by_default? ? 'Collapse' : 'Expand'
|
||||
.settings-content
|
||||
= render ::Layouts::SettingsBlockComponent.new(s_('Runners|Runners'),
|
||||
id: 'js-runner-settings',
|
||||
testid: 'runner-settings',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
= _('Configure runner version management and registration settings.')
|
||||
- c.with_body do
|
||||
= render 'runner_registrars_form'
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
%tr.section
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "text-align: left; width:100%;" }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" }= _("Project")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
%tr.section
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "text-align: left; width:100%;" }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" }= _('Project')
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
%tr.section
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "text-align: left; width:100%;" }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" }
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@
|
|||
- if setting
|
||||
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, help_page_path: help_page_path('user/profile/notifications'), group_id: group.id, show_label: "true" } }
|
||||
= form_for setting, url: profile_group_notifications_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f|
|
||||
.js-notification-email-listbox-input{ data: { name: 'notification_setting[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Global notification email') , value: setting.notification_email, placement: 'right' } }
|
||||
.js-notification-email-listbox-input{ data: { name: 'notification_setting[notification_email]', emails: @user.public_verified_emails.to_json, empty_value_text: _('Global notification email') , value: setting.notification_email, placement: 'bottom-end' } }
|
||||
|
|
|
|||
|
|
@ -11,5 +11,4 @@
|
|||
project_name: @project.name,
|
||||
project_path: @project.root_ancestor.full_path,
|
||||
gitlab_host: Gitlab.config.gitlab.host,
|
||||
terraform_help_path: help_page_path('user/infrastructure/index'),
|
||||
project_list_url: project_infrastructure_registry_index_path(@project)} }
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
migration_job_name: BackfillSbomOccurrencesTraversalIdsAndArchived
|
||||
description: >
|
||||
Backfills sbom_occurrences.traversal_ids and sbom_occurrences.archived columns with
|
||||
values from sbom_occurrences.project.namespace.traversal_ids and
|
||||
sbom_occurrences.project.archived.
|
||||
description: 'Backfills sbom_occurrences.traversal_ids and sbom_occurrences.archived
|
||||
columns with values from sbom_occurrences.project.namespace.traversal_ids and sbom_occurrences.project.archived.
|
||||
|
||||
'
|
||||
feature_category: dependency_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144802
|
||||
milestone: '16.10'
|
||||
queued_migration_version: 20240214203242
|
||||
finalize_after: '2024-04-11'
|
||||
finalized_by: # Not yet implemented
|
||||
finalized_by: '20240626231944'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveMemberRolesIndividualPermissionsColumns < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
PERMISSION_COLUMNS = %i[
|
||||
admin_cicd_variables
|
||||
admin_group_member
|
||||
admin_merge_request
|
||||
admin_terraform_state
|
||||
admin_vulnerability
|
||||
archive_project
|
||||
manage_group_access_tokens
|
||||
manage_project_access_tokens
|
||||
read_code
|
||||
read_dependency
|
||||
read_vulnerability
|
||||
remove_group
|
||||
remove_project
|
||||
]
|
||||
|
||||
def change
|
||||
remove_columns :member_roles, *PERMISSION_COLUMNS, type: :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropIndexSecurityFindingsConfidenceIdx < Gitlab::Database::Migration[2.2]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
milestone '17.2'
|
||||
|
||||
INDEX_NAME = 'security_findings_confidence_idx'
|
||||
TABLE_NAME = :security_findings
|
||||
|
||||
def up
|
||||
remove_concurrent_partitioned_index_by_name TABLE_NAME, INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_partitioned_index TABLE_NAME, :confidence, name: INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeBackfillSbomOccurrencesTraversalIdsAndArchived < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: 'BackfillSbomOccurrencesTraversalIdsAndArchived',
|
||||
table_name: :sbom_occurrences,
|
||||
column_name: :id,
|
||||
job_arguments: [],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
ba1a13140ac43c4640f2cb49bb1d162ed36751ba35cf66c45f49b3410a23507a
|
||||
|
|
@ -0,0 +1 @@
|
|||
3375b9d5de363d25c4be4669a94a68dbce9cec8a5e6954f01926057163e5650a
|
||||
|
|
@ -0,0 +1 @@
|
|||
767d2d4a0f15dfe73608c8db586777a1f55014d3e66f599e719ba3c997364a0d
|
||||
|
|
@ -12177,21 +12177,8 @@ CREATE TABLE member_roles (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
base_access_level integer NOT NULL,
|
||||
read_code boolean DEFAULT false,
|
||||
read_vulnerability boolean DEFAULT false NOT NULL,
|
||||
admin_vulnerability boolean DEFAULT false NOT NULL,
|
||||
read_dependency boolean DEFAULT false NOT NULL,
|
||||
name text DEFAULT 'Custom'::text NOT NULL,
|
||||
description text,
|
||||
admin_merge_request boolean DEFAULT false NOT NULL,
|
||||
admin_group_member boolean DEFAULT false NOT NULL,
|
||||
manage_project_access_tokens boolean DEFAULT false NOT NULL,
|
||||
archive_project boolean DEFAULT false NOT NULL,
|
||||
manage_group_access_tokens boolean DEFAULT false NOT NULL,
|
||||
remove_project boolean DEFAULT false NOT NULL,
|
||||
admin_terraform_state boolean DEFAULT false NOT NULL,
|
||||
admin_cicd_variables boolean DEFAULT false NOT NULL,
|
||||
remove_group boolean DEFAULT false NOT NULL,
|
||||
occupies_seat boolean DEFAULT false NOT NULL,
|
||||
permissions jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
CONSTRAINT check_4364846f58 CHECK ((char_length(description) <= 255)),
|
||||
|
|
@ -29649,8 +29636,6 @@ CREATE INDEX scan_finding_approval_project_rule_index_created_at_project_id ON a
|
|||
|
||||
CREATE INDEX scan_finding_approval_project_rule_index_project_id ON approval_project_rules USING btree (project_id) WHERE (report_type = 4);
|
||||
|
||||
CREATE INDEX security_findings_confidence_idx ON ONLY security_findings USING btree (confidence);
|
||||
|
||||
CREATE INDEX security_findings_project_fingerprint_idx ON ONLY security_findings USING btree (project_fingerprint);
|
||||
|
||||
CREATE INDEX security_findings_scan_id_deduplicated_idx ON ONLY security_findings USING btree (scan_id, deduplicated);
|
||||
|
|
|
|||
|
|
@ -615,6 +615,8 @@ flow of how we construct a Chat prompt:
|
|||
GitLab Duo Chat has error codes with specified meanings to assist in debugging.
|
||||
Currently, they are only logged, but in the future, they will be displayed on the UI.
|
||||
|
||||
See the [GitLab Duo Chat troubleshooting documentation](../../user/gitlab_duo_chat/troubleshooting.md) for a list of all GitLab Duo Chat error codes.
|
||||
|
||||
When developing for GitLab Duo Chat, please include these error codes when returning an error and [document them](../../user/gitlab_duo_chat/troubleshooting.md), especially for user-facing errors.
|
||||
|
||||
### Error Code Format
|
||||
|
|
|
|||
|
|
@ -230,10 +230,13 @@ To update the linting images:
|
|||
|
||||
1. In `gitlab-docs`, open a merge request to update `.gitlab-ci.yml` to use the new tooling
|
||||
version. ([Example MR](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/2571))
|
||||
1. When merged, start a `Build docs.gitlab.com every hour` [scheduled pipeline](https://gitlab.com/gitlab-org/gitlab-docs/-/pipeline_schedules).
|
||||
1. Go the pipeline you started, and manually run the relevant build-images job,
|
||||
for example, `image:docs-lint-markdown`.
|
||||
1. In the job output, get the name of the new image.
|
||||
1. When merged, start a `Build docker images manually` [scheduled pipeline](https://gitlab.com/gitlab-org/gitlab-docs/-/pipeline_schedules).
|
||||
1. Go the pipeline you started, and wait for the relevant `test:image` job to complete,
|
||||
for example `test:image:docs-lint-markdown`. If the job:
|
||||
- Passes, start the relevant `image:` job, for example, `image:docs-lint-markdown`.
|
||||
- Fails, review the test job log and start troubleshooting the issue. The image configuration
|
||||
likely needs some manual tweaks to work with the updated dependency.
|
||||
1. After the `image:` job passes, check the job's log for the name of the new image.
|
||||
([Example job output](https://gitlab.com/gitlab-org/gitlab-docs/-/jobs/2335033884#L334))
|
||||
1. Verify that the new image was added to the container registry.
|
||||
1. Open merge requests to update each of these configuration files to point to the new image.
|
||||
|
|
|
|||
|
|
@ -747,55 +747,64 @@ When GitLab receives a SAML response from a SAML SSO provider, GitLab looks for
|
|||
|
||||
You must include these values correctly in the attribute `Name` field so that GitLab can parse the SAML response. For example, GitLab can parse the following SAML response snippets:
|
||||
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
- This is accepted because the `Name` attribute is set to one of the required values from the previous table.
|
||||
|
||||
```xml
|
||||
<Attribute Name="firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="email">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
- This is accepted because the `Name` attribute matches one of the values from the previous table.
|
||||
|
||||
```xml
|
||||
<Attribute Name="firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="email">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
However, GitLab cannot parse the following SAML response snippets:
|
||||
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
- This will not be accepted because value in the `Name` attribute is not one of the supported
|
||||
values in the previous table.
|
||||
|
||||
```xml
|
||||
<Attribute FriendlyName="firstname" Name="urn:oid:2.5.4.42">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="lastname" Name="urn:oid:2.5.4.4">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="email" Name="urn:oid:0.9.2342.19200300.100.1.3">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
- This will fail because, even though the `FriendlyName` has a supported value, the `Name` attribute does not.
|
||||
|
||||
```xml
|
||||
<Attribute FriendlyName="firstname" Name="urn:oid:2.5.4.42">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="lastname" Name="urn:oid:2.5.4.4">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="email" Name="urn:oid:0.9.2342.19200300.100.1.3">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
See [`attribute_statements`](#map-saml-response-attribute-names) for:
|
||||
|
||||
|
|
|
|||
|
|
@ -6341,6 +6341,12 @@ msgstr ""
|
|||
msgid "Appearance was successfully updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "AppearanceSettings|Last edit"
|
||||
msgstr ""
|
||||
|
||||
msgid "AppearanceSettings|Preview last save:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Append the comment with %{shrug}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13991,6 +13997,9 @@ msgstr ""
|
|||
msgid "Configure repository storage."
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure runner version management and registration settings."
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure settings for Advanced Search with Elasticsearch."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -215,14 +215,14 @@
|
|||
"url-loader": "^4.1.1",
|
||||
"uuid": "8.1.0",
|
||||
"visibilityjs": "^1.2.4",
|
||||
"vue": "2.7.15",
|
||||
"vue": "2.7.16",
|
||||
"vue-apollo": "^3.0.7",
|
||||
"vue-loader": "15.11.1",
|
||||
"vue-observe-visibility": "^1.0.0",
|
||||
"vue-resize": "^1.0.1",
|
||||
"vue-router": "3.6.5",
|
||||
"vue-router-vue3": "npm:vue-router@4.1.6",
|
||||
"vue-template-compiler": "2.7.15",
|
||||
"vue-template-compiler": "2.7.16",
|
||||
"vue-virtual-scroll-list": "^1.4.7",
|
||||
"vuedraggable": "^2.23.0",
|
||||
"vuex": "^3.6.2",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/node_modules/vue/node_modules/@vue/compiler-sfc/dist/compiler-sfc.js b/node_modules/vue/node_modules/@vue/compiler-sfc/dist/compiler-sfc.js
|
||||
index ec32339..91e43a7 100644
|
||||
index 91da3e0..001cf4f 100644
|
||||
--- a/node_modules/vue/node_modules/@vue/compiler-sfc/dist/compiler-sfc.js
|
||||
+++ b/node_modules/vue/node_modules/@vue/compiler-sfc/dist/compiler-sfc.js
|
||||
@@ -9645,7 +9645,23 @@ const splitRE = /\r?\n/g;
|
||||
@@ -9658,7 +9658,23 @@ const splitRE = /\r?\n/g;
|
||||
const emptyRE = /^(?:\/\/)?\s*$/;
|
||||
function parse(options) {
|
||||
const { source, filename = DEFAULT_FILENAME, compiler, compilerParseOptions = { pad: false }, sourceRoot = '', needMap = true, sourceMap = needMap } = options;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Layouts::SettingsSectionComponent, type: :component, feature_category: :shared do
|
||||
let(:heading) { 'Settings section heading' }
|
||||
let(:description) { 'Settings section description' }
|
||||
let(:body) { 'Settings section content' }
|
||||
let(:id) { 'js-settings-section-id' }
|
||||
let(:testid) { 'settings-section-testid' }
|
||||
|
||||
describe 'slots' do
|
||||
it 'renders heading' do
|
||||
render_inline described_class.new(heading)
|
||||
|
||||
expect(page).to have_css('h2.gl-heading-2', text: heading)
|
||||
end
|
||||
|
||||
it 'renders description' do
|
||||
render_inline described_class.new(heading, description: description)
|
||||
|
||||
expect(page).to have_css('.gl-text-secondary', text: description)
|
||||
end
|
||||
|
||||
it 'renders description slot' do
|
||||
render_inline described_class.new(heading) do |c|
|
||||
c.with_description { description }
|
||||
end
|
||||
|
||||
expect(page).to have_css('.gl-text-secondary', text: description)
|
||||
end
|
||||
|
||||
it 'renders body slot' do
|
||||
render_inline described_class.new(heading) do |c|
|
||||
c.with_body { body }
|
||||
end
|
||||
|
||||
expect(page).to have_css('[data-testid="settings-section-body"]', text: body)
|
||||
end
|
||||
|
||||
it 'renders id' do
|
||||
render_inline described_class.new(heading, id: id)
|
||||
|
||||
expect(page).to have_css('#js-settings-section-id')
|
||||
end
|
||||
|
||||
it 'renders testid' do
|
||||
render_inline described_class.new(heading, testid: testid)
|
||||
|
||||
expect(page).to have_css('[data-testid="settings-section-testid"]')
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue