diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-24 00:12:16 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-24 00:12:16 +0300 |
commit | a0686b4653208e66c768b63e249bd73406f9e267 (patch) | |
tree | 4df20a2bac7ff9057e60e022b34aad42cfd73dc0 /app | |
parent | c5da163db1c10676b1a01a898b7b3a4506e65b89 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
18 files changed, 62 insertions, 572 deletions
diff --git a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue index 63243539575..acfe14051aa 100644 --- a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue +++ b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue @@ -48,9 +48,6 @@ export default { starCount() { return this.resource?.starCount || 0; }, - forksCount() { - return this.resource?.forksCount || 0; - }, hasReleasedVersion() { return Boolean(this.latestVersion?.releasedAt); }, @@ -111,10 +108,6 @@ export default { <gl-icon name="star" :size="14" class="gl-mr-1" /> <span class="gl-mr-3">{{ starCount }}</span> </span> - <span class="gl--flex-center" data-testid="stats-forks"> - <gl-icon name="fork" :size="14" class="gl-mr-1" /> - <span>{{ forksCount }}</span> - </span> </span> </div> </div> diff --git a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql index f4d1bb0eaaf..a86db4c1b03 100644 --- a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql +++ b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql @@ -4,7 +4,6 @@ fragment CatalogResourceFields on CiCatalogResource { name description starCount - forksCount latestVersion { id tagName diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_modal.vue deleted file mode 100644 index cc664d76267..00000000000 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_modal.vue +++ /dev/null @@ -1,511 +0,0 @@ -<script> -import { - GlAlert, - GlButton, - GlCollapse, - GlFormCheckbox, - GlFormCombobox, - GlFormGroup, - GlFormSelect, - GlFormInput, - GlFormTextarea, - GlIcon, - GlLink, - GlModal, - GlSprintf, -} from '@gitlab/ui'; -import { helpPagePath } from '~/helpers/help_page_helper'; -import { getCookie, setCookie } from '~/lib/utils/common_utils'; -import { __ } from '~/locale'; -import Tracking from '~/tracking'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; - -import { - allEnvironments, - AWS_TOKEN_CONSTANTS, - ADD_CI_VARIABLE_MODAL_ID, - AWS_TIP_DISMISSED_COOKIE_NAME, - AWS_TIP_TITLE, - AWS_TIP_MESSAGE, - CONTAINS_VARIABLE_REFERENCE_MESSAGE, - defaultVariableState, - ENVIRONMENT_SCOPE_LINK_TITLE, - EVENT_LABEL, - EVENT_ACTION, - EXPANDED_VARIABLES_NOTE, - EDIT_VARIABLE_ACTION, - FLAG_LINK_TITLE, - VARIABLE_ACTIONS, - variableOptions, -} from '../constants'; -import CiEnvironmentsDropdown from './ci_environments_dropdown.vue'; -import { awsTokens, awsTokenList } from './ci_variable_autocomplete_tokens'; - -const trackingMixin = Tracking.mixin({ label: EVENT_LABEL }); - -export default { - components: { - CiEnvironmentsDropdown, - GlAlert, - GlButton, - GlCollapse, - GlFormCheckbox, - GlFormCombobox, - GlFormGroup, - GlFormSelect, - GlFormInput, - GlFormTextarea, - GlIcon, - GlLink, - GlModal, - GlSprintf, - }, - mixins: [glFeatureFlagsMixin(), trackingMixin], - inject: [ - 'containsVariableReferenceLink', - 'environmentScopeLink', - 'isProtectedByDefault', - 'maskedEnvironmentVariablesLink', - 'maskableRawRegex', - 'maskableRegex', - ], - props: { - areEnvironmentsLoading: { - type: Boolean, - required: true, - }, - areScopedVariablesAvailable: { - type: Boolean, - required: false, - default: false, - }, - environments: { - type: Array, - required: false, - default: () => [], - }, - hideEnvironmentScope: { - type: Boolean, - required: false, - default: false, - }, - mode: { - type: String, - required: true, - validator(val) { - return VARIABLE_ACTIONS.includes(val); - }, - }, - selectedVariable: { - type: Object, - required: false, - default: () => {}, - }, - variables: { - type: Array, - required: false, - default: () => [], - }, - }, - data() { - return { - newEnvironments: [], - isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true', - validationErrorEventProperty: '', - variable: { ...defaultVariableState, ...this.selectedVariable }, - }; - }, - computed: { - canMask() { - const regex = RegExp(this.useRawMaskableRegexp ? this.maskableRawRegex : this.maskableRegex); - return regex.test(this.variable.value); - }, - canSubmit() { - return this.variableValidationState && this.variable.key !== ''; - }, - containsVariableReference() { - const regex = /\$/; - return regex.test(this.variable.value) && this.isExpanded; - }, - displayMaskedError() { - return !this.canMask && this.variable.masked; - }, - isEditing() { - return this.mode === EDIT_VARIABLE_ACTION; - }, - isExpanded() { - return !this.isRaw; - }, - isRaw() { - return this.variable.raw; - }, - isTipVisible() { - return !this.isTipDismissed && AWS_TOKEN_CONSTANTS.includes(this.variable.key); - }, - maskedFeedback() { - return this.displayMaskedError - ? __('This variable value does not meet the masking requirements.') - : ''; - }, - maskedState() { - if (this.displayMaskedError) { - return false; - } - return true; - }, - modalActionText() { - return this.isEditing ? __('Update variable') : __('Add variable'); - }, - tokenValidationFeedback() { - const tokenSpecificFeedback = this.$options.tokens?.[this.variable.key]?.invalidMessage; - if (!this.tokenValidationState && tokenSpecificFeedback) { - return tokenSpecificFeedback; - } - return ''; - }, - tokenValidationState() { - const validator = this.$options.tokens?.[this.variable.key]?.validation; - - if (validator) { - return validator(this.variable.value); - } - - return true; - }, - useRawMaskableRegexp() { - return this.isRaw; - }, - variableValidationFeedback() { - return `${this.tokenValidationFeedback} ${this.maskedFeedback}`; - }, - variableValidationState() { - return this.variable.value === '' || (this.tokenValidationState && this.maskedState); - }, - variableValueHelpText() { - return this.variable.masked - ? __('Value must meet regular expression requirements to be masked.') - : ''; - }, - }, - watch: { - variable: { - handler() { - this.trackVariableValidationErrors(); - }, - deep: true, - }, - }, - methods: { - addVariable() { - this.$emit('add-variable', this.variable); - }, - deleteVariable() { - this.$emit('delete-variable', this.variable); - }, - updateVariable() { - this.$emit('update-variable', this.variable); - }, - dismissTip() { - setCookie(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 }); - this.isTipDismissed = true; - }, - deleteVarAndClose() { - this.deleteVariable(); - this.hideModal(); - }, - hideModal() { - this.$refs.modal.hide(); - }, - onShow() { - this.setVariableProtectedByDefault(); - }, - resetModalHandler() { - this.resetVariableData(); - this.resetValidationErrorEvents(); - - this.$emit('close-form'); - }, - resetVariableData() { - this.variable = { ...defaultVariableState }; - }, - setEnvironmentScope(scope) { - this.variable = { ...this.variable, environmentScope: scope }; - }, - setVariableRaw(expanded) { - this.variable = { ...this.variable, raw: !expanded }; - }, - setVariableProtected() { - this.variable = { ...this.variable, protected: true }; - }, - updateOrAddVariable() { - if (this.isEditing) { - this.updateVariable(); - } else { - this.addVariable(); - } - this.hideModal(); - }, - setVariableProtectedByDefault() { - if (this.isProtectedByDefault && !this.isEditing) { - this.setVariableProtected(); - } - }, - trackVariableValidationErrors() { - const property = this.getTrackingErrorProperty(); - if (!this.validationErrorEventProperty && property) { - this.track(EVENT_ACTION, { property }); - this.validationErrorEventProperty = property; - } - }, - getTrackingErrorProperty() { - let property; - if (this.variable.value?.length && !property) { - if (this.displayMaskedError && this.maskableRegex?.length) { - const supportedChars = this.maskableRegex.replace('^', '').replace(/{(\d,)}\$/, ''); - const regex = new RegExp(supportedChars, 'g'); - property = this.variable.value.replace(regex, ''); - } - if (this.containsVariableReference) { - property = '$'; - } - } - - return property; - }, - resetValidationErrorEvents() { - this.validationErrorEventProperty = ''; - }, - }, - i18n: { - awsTipTitle: AWS_TIP_TITLE, - awsTipMessage: AWS_TIP_MESSAGE, - containsVariableReferenceMessage: CONTAINS_VARIABLE_REFERENCE_MESSAGE, - defaultScope: allEnvironments.text, - environmentScopeLinkTitle: ENVIRONMENT_SCOPE_LINK_TITLE, - expandedVariablesNote: EXPANDED_VARIABLES_NOTE, - flagsLinkTitle: FLAG_LINK_TITLE, - }, - flagLink: helpPagePath('ci/variables/index', { - anchor: 'define-a-cicd-variable-in-the-ui', - }), - oidcLink: helpPagePath('ci/cloud_services/index', { - anchor: 'oidc-authorization-with-your-cloud-provider', - }), - modalId: ADD_CI_VARIABLE_MODAL_ID, - tokens: awsTokens, - tokenList: awsTokenList, - variableOptions, -}; -</script> - -<template> - <gl-modal - ref="modal" - :modal-id="$options.modalId" - :title="modalActionText" - static - lazy - @hidden="resetModalHandler" - @shown="onShow" - > - <gl-collapse :visible="isTipVisible"> - <gl-alert - :title="$options.i18n.awsTipTitle" - variant="warning" - class="gl-mb-5" - data-testid="aws-guidance-tip" - @dismiss="dismissTip" - > - <gl-sprintf :message="$options.i18n.awsTipMessage"> - <template #link="{ content }"> - <gl-link :href="$options.oidcLink"> - {{ content }} - </gl-link> - </template> - </gl-sprintf> - </gl-alert> - </gl-collapse> - <form> - <gl-form-combobox - v-model="variable.key" - :token-list="$options.tokenList" - :label-text="__('Key')" - data-testid="pipeline-form-ci-variable-key" - data-qa-selector="ci_variable_key_field" - /> - - <gl-form-group - :label="__('Value')" - label-for="ci-variable-value" - :state="variableValidationState" - :description="variableValueHelpText" - :invalid-feedback="variableValidationFeedback" - > - <gl-form-textarea - id="ci-variable-value" - ref="valueField" - v-model="variable.value" - :state="variableValidationState" - rows="3" - max-rows="10" - data-testid="pipeline-form-ci-variable-value" - data-qa-selector="ci_variable_value_field" - class="gl-font-monospace!" - spellcheck="false" - /> - <p v-if="isRaw" class="gl-mt-2 gl-mb-0 text-secondary" data-testid="raw-variable-tip"> - {{ __('Variable value will be evaluated as raw string.') }} - </p> - </gl-form-group> - - <div class="gl-display-flex"> - <gl-form-group :label="__('Type')" label-for="ci-variable-type" class="gl-w-half gl-mr-5"> - <gl-form-select - id="ci-variable-type" - v-model="variable.variableType" - :options="$options.variableOptions" - /> - </gl-form-group> - - <template v-if="!hideEnvironmentScope"> - <gl-form-group - label-for="ci-variable-env" - class="gl-w-half" - data-testid="environment-scope" - > - <template #label> - <div class="gl-display-flex gl-align-items-center"> - <span class="gl-mr-2"> - {{ __('Environment scope') }} - </span> - <gl-link - class="gl-display-flex" - :title="$options.i18n.environmentScopeLinkTitle" - :href="environmentScopeLink" - target="_blank" - data-testid="environment-scope-link" - > - <gl-icon name="question-o" :size="14" /> - </gl-link> - </div> - </template> - <ci-environments-dropdown - v-if="areScopedVariablesAvailable" - :are-environments-loading="areEnvironmentsLoading" - :selected-environment-scope="variable.environmentScope" - :environments="environments" - @select-environment="setEnvironmentScope" - @search-environment-scope="$emit('search-environment-scope', $event)" - /> - - <gl-form-input v-else :value="$options.i18n.defaultScope" class="gl-w-full" readonly /> - </gl-form-group> - </template> - </div> - - <gl-form-group> - <template #label> - <div class="gl-display-flex gl-align-items-center"> - <span class="gl-mr-2"> - {{ __('Flags') }} - </span> - <gl-link - class="gl-display-flex" - :title="$options.i18n.flagsLinkTitle" - :href="$options.flagLink" - target="_blank" - > - <gl-icon name="question-o" :size="14" /> - </gl-link> - </div> - </template> - <gl-form-checkbox - v-model="variable.protected" - class="gl-mb-0" - data-testid="ci-variable-protected-checkbox" - :data-is-protected-checked="variable.protected" - > - {{ __('Protect variable') }} - <p class="gl-mt-2 text-secondary"> - {{ __('Export variable to pipelines running on protected branches and tags only.') }} - </p> - </gl-form-checkbox> - <gl-form-checkbox - ref="masked-ci-variable" - v-model="variable.masked" - data-testid="ci-variable-masked-checkbox" - > - {{ __('Mask variable') }} - <p class="gl-mt-2 text-secondary"> - <gl-sprintf - :message=" - __( - 'Mask this variable in job logs if it meets %{linkStart}regular expression requirements%{linkEnd}.', - ) - " - > - <template #link="{ content }" - ><gl-link target="_blank" :href="maskedEnvironmentVariablesLink">{{ - content - }}</gl-link> - </template> - </gl-sprintf> - </p> - </gl-form-checkbox> - <gl-form-checkbox - ref="expanded-ci-variable" - :checked="isExpanded" - data-testid="ci-variable-expanded-checkbox" - @change="setVariableRaw" - > - {{ __('Expand variable reference') }} - <p class="gl-mt-2 gl-mb-0 gl-text-secondary"> - <gl-sprintf :message="$options.i18n.expandedVariablesNote"> - <template #code="{ content }"> - <code>{{ content }}</code> - </template> - </gl-sprintf> - </p> - </gl-form-checkbox> - </gl-form-group> - </form> - - <gl-alert - v-if="containsVariableReference" - :title="__('Value might contain a variable reference')" - :dismissible="false" - variant="warning" - data-testid="contains-variable-reference" - > - <gl-sprintf :message="$options.i18n.containsVariableReferenceMessage"> - <template #code="{ content }"> - <code>{{ content }}</code> - </template> - <template #docsLink="{ content }"> - <gl-link :href="containsVariableReferenceLink" target="_blank">{{ content }}</gl-link> - </template> - </gl-sprintf> - </gl-alert> - <template #modal-footer> - <gl-button @click="hideModal">{{ __('Cancel') }}</gl-button> - <gl-button - v-if="isEditing" - ref="deleteCiVariable" - variant="danger" - category="secondary" - @click="deleteVarAndClose" - >{{ __('Delete variable') }}</gl-button - > - <gl-button - ref="updateOrAddVariable" - :disabled="!canSubmit" - variant="confirm" - category="primary" - data-testid="ciUpdateOrAddVariableBtn" - data-qa-selector="ci_variable_save_button" - @click="updateOrAddVariable" - >{{ modalActionText }} - </gl-button> - </template> - </gl-modal> -</template> diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue index f2d81b3f271..99270d36df7 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue @@ -3,13 +3,11 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { ADD_VARIABLE_ACTION, EDIT_VARIABLE_ACTION, VARIABLE_ACTIONS } from '../constants'; import CiVariableDrawer from './ci_variable_drawer.vue'; import CiVariableTable from './ci_variable_table.vue'; -import CiVariableModal from './ci_variable_modal.vue'; export default { components: { CiVariableDrawer, CiVariableTable, - CiVariableModal, }, mixins: [glFeatureFlagsMixin()], props: { @@ -65,15 +63,6 @@ export default { showForm() { return VARIABLE_ACTIONS.includes(this.mode); }, - useDrawerForm() { - return this.glFeatures?.ciVariableDrawer; - }, - showDrawer() { - return this.showForm && this.useDrawerForm; - }, - showModal() { - return this.showForm && !this.useDrawerForm; - }, }, methods: { addVariable(variable) { @@ -116,23 +105,8 @@ export default { @delete-variable="deleteVariable" @sort-changed="(val) => $emit('sort-changed', val)" /> - <ci-variable-modal - v-if="showModal" - :are-environments-loading="areEnvironmentsLoading" - :are-scoped-variables-available="areScopedVariablesAvailable" - :environments="environments" - :hide-environment-scope="hideEnvironmentScope" - :variables="variables" - :mode="mode" - :selected-variable="selectedVariable" - @add-variable="addVariable" - @delete-variable="deleteVariable" - @close-form="closeForm" - @update-variable="updateVariable" - @search-environment-scope="$emit('search-environment-scope', $event)" - /> <ci-variable-drawer - v-if="showDrawer" + v-if="showForm" :are-environments-loading="areEnvironmentsLoading" :are-scoped-variables-available="areScopedVariablesAvailable" :environments="environments" diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue index 3d62313815c..87d8b98b025 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue @@ -16,7 +16,6 @@ import { import { __, s__, sprintf } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { - ADD_CI_VARIABLE_MODAL_ID, DEFAULT_EXCEEDS_VARIABLE_LIMIT_TEXT, EXCEEDS_VARIABLE_LIMIT_TEXT, MAXIMUM_VARIABLE_LIMIT_REACHED, @@ -25,7 +24,6 @@ import { import { convertEnvironmentScope } from '../utils'; export default { - modalId: ADD_CI_VARIABLE_MODAL_ID, defaultFields: [ { key: 'key', @@ -243,7 +241,6 @@ export default { >{{ valuesButtonText }}</gl-button > <gl-button - v-gl-modal-directive="$options.modalId" size="small" :disabled="exceedsVariableLimit" data-qa-selector="add_ci_variable_button" @@ -375,7 +372,6 @@ export default { <template v-if="!isInheritedGroupVars" #cell(actions)="{ item }"> <div class="gl-display-flex gl-justify-content-end gl-mt-n2 gl-mb-n2"> <gl-button - v-gl-modal-directive="$options.modalId" icon="pencil" size="small" class="gl-mr-3" diff --git a/app/assets/javascripts/ci/ci_variable_list/constants.js b/app/assets/javascripts/ci/ci_variable_list/constants.js index fc37b62299d..d85827b8220 100644 --- a/app/assets/javascripts/ci/ci_variable_list/constants.js +++ b/app/assets/javascripts/ci/ci_variable_list/constants.js @@ -1,6 +1,5 @@ import { __, s__, sprintf } from '~/locale'; -export const ADD_CI_VARIABLE_MODAL_ID = 'add-ci-variable'; export const ENVIRONMENT_QUERY_LIMIT = 30; export const SORT_DIRECTIONS = { @@ -45,7 +44,6 @@ export const AWS_TIP_MESSAGE = s__( 'CiVariable|GitLab CI/CD supports OpenID Connect (OIDC) to give your build and deployment jobs access to cloud credentials and services. %{linkStart}How do I configure OIDC for my cloud provider?%{linkEnd}', ); -export const EVENT_LABEL = 'ci_variable_modal'; export const DRAWER_EVENT_LABEL = 'ci_variable_drawer'; export const EVENT_ACTION = 'validation_error'; diff --git a/app/assets/javascripts/lib/utils/forms.js b/app/assets/javascripts/lib/utils/forms.js index 652ae337506..6713a18cbf3 100644 --- a/app/assets/javascripts/lib/utils/forms.js +++ b/app/assets/javascripts/lib/utils/forms.js @@ -69,18 +69,32 @@ export const isIntegerGreaterThan = (value, greaterThan) => isParseableAsInteger(value) && parseInt(value, 10) > greaterThan; /** - * Regexp that matches email structure. + * Regexp that matches service desk setting email structure. * Taken from app/models/service_desk_setting.rb custom_email */ -export const EMAIL_REGEXP = /^[\w\-._]+@[\w\-.]+\.[a-zA-Z]{2,}$/; +const SERVICE_DESK_SETTING_EMAIL_REGEXP = /^[\w\-._]+@[\w\-.]+\.[a-zA-Z]{2,}$/; /** - * Checks if the input is a valid email address + * Checks if the input is a valid service desk setting email address * * @param {String} - value * @returns {Boolean} */ -export const isEmail = (value) => EMAIL_REGEXP.test(value); +export const isServiceDeskSettingEmail = (value) => SERVICE_DESK_SETTING_EMAIL_REGEXP.test(value); + +/** + * Regexp that matches user email structure. + * Taken from DeviseEmailValidator + */ +const USER_EMAIL_REGEXP = /^[^@\s]+@[^@\s]+$/; + +/** + * Checks if the input is a valid user email address + * + * @param {String} - value + * @returns {Boolean} + */ +export const isUserEmail = (value) => USER_EMAIL_REGEXP.test(value); /** * A form object serializer diff --git a/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue b/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue index 09bc275cbd4..8edf2cfb4aa 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue @@ -9,7 +9,12 @@ import { GlSprintf, } from '@gitlab/ui'; import { helpPagePath } from '~/helpers/help_page_helper'; -import { isEmptyValue, hasMinimumLength, isIntegerGreaterThan, isEmail } from '~/lib/utils/forms'; +import { + isEmptyValue, + hasMinimumLength, + isIntegerGreaterThan, + isServiceDeskSettingEmail, +} from '~/lib/utils/forms'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import { I18N_FORM_INTRODUCTION_PARAGRAPH, @@ -124,7 +129,7 @@ export default { } }, validateCustomEmail() { - this.validationState.customEmail = isEmail(this.customEmail); + this.validationState.customEmail = isServiceDeskSettingEmail(this.customEmail); }, validateSmtpAddress() { this.validationState.smtpAddress = !isEmptyValue(this.smtpAddress); diff --git a/app/assets/javascripts/sessions/new/components/update_email.vue b/app/assets/javascripts/sessions/new/components/update_email.vue index 124cd671169..f9b9a063808 100644 --- a/app/assets/javascripts/sessions/new/components/update_email.vue +++ b/app/assets/javascripts/sessions/new/components/update_email.vue @@ -1,6 +1,7 @@ <script> import { GlForm, GlFormGroup, GlFormInput, GlButton } from '@gitlab/ui'; import { createAlert, VARIANT_SUCCESS } from '~/alert'; +import { isUserEmail } from '~/lib/utils/forms'; import axios from '~/lib/utils/axios_utils'; import { I18N_EMAIL, @@ -10,7 +11,6 @@ import { I18N_EMAIL_INVALID, I18N_UPDATE_EMAIL_SUCCESS, I18N_GENERIC_ERROR, - EMAIL_REGEXP, SUCCESS_RESPONSE, FAILURE_RESPONSE, } from '../constants'; @@ -48,7 +48,7 @@ export default { return ''; } - if (!EMAIL_REGEXP.test(this.email)) { + if (!isUserEmail(this.email)) { return I18N_EMAIL_INVALID; } diff --git a/app/assets/javascripts/sessions/new/constants.js b/app/assets/javascripts/sessions/new/constants.js index e9bd26099aa..eb2bc25d958 100644 --- a/app/assets/javascripts/sessions/new/constants.js +++ b/app/assets/javascripts/sessions/new/constants.js @@ -25,6 +25,5 @@ export const I18N_UPDATE_EMAIL_SUCCESS = s__( ); export const VERIFICATION_CODE_REGEX = /^\d{6}$/; -export const EMAIL_REGEXP = /^[^@\s]+@[^@\s]+$/; // Taken from DeviseEmailValidator export const SUCCESS_RESPONSE = 'success'; export const FAILURE_RESPONSE = 'failure'; diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index be1edeb0d37..f0b6d86d48d 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -15,7 +15,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController before_action do push_frontend_feature_flag(:ci_variables_pages, current_user) - push_frontend_feature_flag(:ci_variable_drawer, current_user) end feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index c606ccf4a07..f8c3e125c3b 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -246,7 +246,7 @@ module WikiActions @sidebar_page = wiki.find_sidebar(params[:version_id]) unless @sidebar_page # Fallback to default sidebar - @sidebar_wiki_entries, @sidebar_limited = wiki.sidebar_entries + @sidebar_wiki_entries, @sidebar_limited = wiki.sidebar_entries(load_content: Feature.enabled?(:wiki_front_matter_title, container)) end rescue ::Gitlab::Git::CommandTimedOut => e @sidebar_error = e @@ -326,7 +326,9 @@ module WikiActions end def load_content? - return false if %w[history destroy diff show].include?(params[:action]) + skip_actions = Feature.enabled?(:wiki_front_matter_title, container) ? %w[history destroy diff] : %w[history destroy diff show] + + return false if skip_actions.include?(params[:action]) true end diff --git a/app/controllers/explore/catalog_controller.rb b/app/controllers/explore/catalog_controller.rb new file mode 100644 index 00000000000..54f1e0b3722 --- /dev/null +++ b/app/controllers/explore/catalog_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Explore + class CatalogController < Explore::ApplicationController + feature_category :pipeline_composition + before_action :check_feature_flag + + def show; end + + def index + render 'show' + end + + private + + def check_feature_flag + render_404 unless Feature.enabled?(:global_ci_catalog) + end + end +end diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index f50cdd2b1de..371db7b30b6 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -15,7 +15,6 @@ module Groups before_action do push_frontend_feature_flag(:ci_variables_pages, current_user) - push_frontend_feature_flag(:ci_variable_drawer, current_user) end urgency :low diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 84ccfbc603a..faa5967d64e 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -98,11 +98,7 @@ class JwtController < ApplicationController return unless params[:scope].present? scopes = Array(Rack::Utils.parse_query(request.query_string)['scope']) - if Feature.enabled?(:jwt_auth_space_delimited_scopes, Feature.current_request) - scopes.flat_map(&:split) - else - scopes - end + scopes.flat_map(&:split) end def auth_user diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 0845fbc9713..9a128adb926 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -14,7 +14,6 @@ module Projects before_action do push_frontend_feature_flag(:ci_variables_pages, current_user) - push_frontend_feature_flag(:ci_variable_drawer, current_user) end helper_method :highlight_badge diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 2eed693ca76..3dd8f334a68 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -80,6 +80,7 @@ class WikiPage alias_method :to_param, :slug def human_title + return front_matter_title if Feature.enabled?(:wiki_front_matter_title, container) && front_matter_title.present? return 'Home' if title == Wiki::HOMEPAGE title @@ -95,6 +96,10 @@ class WikiPage attributes[:title] = new_title end + def front_matter_title + front_matter[:title] + end + def raw_content attributes[:content] ||= page&.text_data end @@ -320,7 +325,7 @@ class WikiPage def serialize_front_matter(hash) return '' unless hash.present? - YAML.dump(hash.transform_keys(&:to_s)) + "---\n" + YAML.dump(hash.to_h.transform_keys(&:to_s)) + "---\n" end def update_front_matter(attrs) diff --git a/app/views/explore/catalog/show.html.haml b/app/views/explore/catalog/show.html.haml new file mode 100644 index 00000000000..6c10ba7dfd7 --- /dev/null +++ b/app/views/explore/catalog/show.html.haml @@ -0,0 +1,3 @@ +- page_title _('CI/CD Catalog') + +#js-ci-cd-catalog |