diff options
Diffstat (limited to 'app/assets/javascripts/ci_variable_list')
30 files changed, 0 insertions, 2477 deletions
diff --git a/app/assets/javascripts/ci_variable_list/ci_variable_list.js b/app/assets/javascripts/ci_variable_list/ci_variable_list.js deleted file mode 100644 index 574a5e7fd99..00000000000 --- a/app/assets/javascripts/ci_variable_list/ci_variable_list.js +++ /dev/null @@ -1,262 +0,0 @@ -import $ from 'jquery'; -import SecretValues from '~/behaviors/secret_values'; -import CreateItemDropdown from '~/create_item_dropdown'; -import { parseBoolean } from '~/lib/utils/common_utils'; -import { s__ } from '~/locale'; - -const ALL_ENVIRONMENTS_STRING = s__('CiVariable|All environments'); - -function createEnvironmentItem(value) { - return { - title: value === '*' ? ALL_ENVIRONMENTS_STRING : value, - id: value, - text: value === '*' ? s__('CiVariable|* (All environments)') : value, - }; -} - -export default class VariableList { - constructor({ container, formField, maskableRegex }) { - this.$container = $(container); - this.formField = formField; - this.maskableRegex = new RegExp(maskableRegex); - this.environmentDropdownMap = new WeakMap(); - - this.inputMap = { - id: { - selector: '.js-ci-variable-input-id', - default: '', - }, - variable_type: { - selector: '.js-ci-variable-input-variable-type', - default: 'env_var', - }, - key: { - selector: '.js-ci-variable-input-key', - default: '', - }, - secret_value: { - selector: '.js-ci-variable-input-value', - default: '', - }, - protected: { - selector: '.js-ci-variable-input-protected', - // use `attr` instead of `data` as we don't want the value to be - // converted. we need the value as a string. - default: $('.js-ci-variable-input-protected').attr('data-default'), - }, - masked: { - selector: '.js-ci-variable-input-masked', - // use `attr` instead of `data` as we don't want the value to be - // converted. we need the value as a string. - default: $('.js-ci-variable-input-masked').attr('data-default'), - }, - environment_scope: { - // We can't use a `.js-` class here because - // deprecated_jquery_dropdown replaces the <input> and doesn't copy over the class - // See https://gitlab.com/gitlab-org/gitlab-foss/issues/42458 - selector: `input[name="${this.formField}[variables_attributes][][environment_scope]"]`, - default: '*', - }, - _destroy: { - selector: '.js-ci-variable-input-destroy', - default: '', - }, - }; - - this.secretValues = new SecretValues({ - container: this.$container[0], - valueSelector: '.js-row:not(:last-child) .js-secret-value', - placeholderSelector: '.js-row:not(:last-child) .js-secret-value-placeholder', - }); - } - - init() { - this.bindEvents(); - this.secretValues.init(); - } - - bindEvents() { - this.$container.find('.js-row').each((index, rowEl) => { - this.initRow(rowEl); - }); - - this.$container.on('click', '.js-row-remove-button', (e) => { - e.preventDefault(); - this.removeRow($(e.currentTarget).closest('.js-row')); - }); - - const inputSelector = Object.keys(this.inputMap) - .map((name) => this.inputMap[name].selector) - .join(','); - - // Remove any empty rows except the last row - this.$container.on('blur', inputSelector, (e) => { - const $row = $(e.currentTarget).closest('.js-row'); - - if ($row.is(':not(:last-child)') && !this.checkIfRowTouched($row)) { - this.removeRow($row); - } - }); - - this.$container.on('input trigger-change', inputSelector, (e) => { - // Always make sure there is an empty last row - const $lastRow = this.$container.find('.js-row').last(); - - if (this.checkIfRowTouched($lastRow)) { - this.insertRow($lastRow); - } - - // If masked, validate value against regex - this.validateMaskability($(e.currentTarget).closest('.js-row')); - }); - } - - initRow(rowEl) { - const $row = $(rowEl); - - // Reset the resizable textarea - $row.find(this.inputMap.secret_value.selector).css('height', ''); - - const $environmentSelect = $row.find('.js-variable-environment-toggle'); - if ($environmentSelect.length) { - const createItemDropdown = new CreateItemDropdown({ - $dropdown: $environmentSelect, - defaultToggleLabel: ALL_ENVIRONMENTS_STRING, - fieldName: `${this.formField}[variables_attributes][][environment_scope]`, - getData: (term, callback) => callback(this.getEnvironmentValues()), - createNewItemFromValue: createEnvironmentItem, - onSelect: () => { - // Refresh the other dropdowns in the variable list - // so they have the new value we just picked - this.refreshDropdownData(); - - $row.find(this.inputMap.environment_scope.selector).trigger('trigger-change'); - }, - }); - - // Clear out any data that might have been left-over from the row clone - createItemDropdown.clearDropdown(); - - this.environmentDropdownMap.set($row[0], createItemDropdown); - } - } - - insertRow($row) { - const $rowClone = $row.clone(); - $rowClone.removeAttr('data-is-persisted'); - - // Reset the inputs to their defaults - Object.keys(this.inputMap).forEach((name) => { - const entry = this.inputMap[name]; - $rowClone.find(entry.selector).val(entry.default); - }); - - // Close any dropdowns - $rowClone.find('.dropdown-menu.show').each((index, $dropdown) => { - $dropdown.classList.remove('show'); - }); - - this.initRow($rowClone); - - $row.after($rowClone); - } - - removeRow(row) { - const $row = $(row); - const isPersisted = parseBoolean($row.attr('data-is-persisted')); - - if (isPersisted) { - $row.hide(); - $row - // eslint-disable-next-line no-underscore-dangle - .find(this.inputMap._destroy.selector) - .val(true); - } else { - $row.remove(); - } - - // Refresh the other dropdowns in the variable list - // so any value with the variable deleted is gone - this.refreshDropdownData(); - } - - checkIfRowTouched($row) { - return Object.keys(this.inputMap).some((name) => { - // Row should not qualify as touched if only switches have been touched - if (['protected', 'masked'].includes(name)) return false; - - const entry = this.inputMap[name]; - const $el = $row.find(entry.selector); - return $el.length && $el.val() !== entry.default; - }); - } - - validateMaskability($row) { - const invalidInputClass = 'gl-field-error-outline'; - - const variableValue = $row.find(this.inputMap.secret_value.selector).val(); - const isValueMaskable = this.maskableRegex.test(variableValue) || variableValue === ''; - const isMaskedChecked = $row.find(this.inputMap.masked.selector).val() === 'true'; - - // Show a validation error if the user wants to mask an unmaskable variable value - $row - .find(this.inputMap.secret_value.selector) - .toggleClass(invalidInputClass, isMaskedChecked && !isValueMaskable); - $row - .find('.js-secret-value-placeholder') - .toggleClass(invalidInputClass, isMaskedChecked && !isValueMaskable); - $row.find('.masking-validation-error').toggle(isMaskedChecked && !isValueMaskable); - } - - toggleEnableRow(isEnabled = true) { - this.$container.find(this.inputMap.key.selector).attr('disabled', !isEnabled); - this.$container.find('.js-row-remove-button').attr('disabled', !isEnabled); - } - - hideValues() { - this.secretValues.updateDom(false); - } - - getAllData() { - // Ignore the last empty row because we don't want to try persist - // a blank variable and run into validation problems. - const validRows = this.$container.find('.js-row').toArray().slice(0, -1); - - return validRows.map((rowEl) => { - const resultant = {}; - Object.keys(this.inputMap).forEach((name) => { - const entry = this.inputMap[name]; - const $input = $(rowEl).find(entry.selector); - if ($input.length) { - resultant[name] = $input.val(); - } - }); - - return resultant; - }); - } - - getEnvironmentValues() { - const valueMap = this.$container - .find(this.inputMap.environment_scope.selector) - .toArray() - .reduce( - (prevValueMap, envInput) => ({ - ...prevValueMap, - [envInput.value]: envInput.value, - }), - {}, - ); - - return Object.keys(valueMap).map(createEnvironmentItem); - } - - refreshDropdownData() { - this.$container.find('.js-row').each((index, rowEl) => { - const environmentDropdown = this.environmentDropdownMap.get(rowEl); - if (environmentDropdown) { - environmentDropdown.refreshData(); - } - }); - } -} diff --git a/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue deleted file mode 100644 index 719696f682e..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue +++ /dev/null @@ -1,36 +0,0 @@ -<script> -import { ADD_MUTATION_ACTION, DELETE_MUTATION_ACTION, UPDATE_MUTATION_ACTION } from '../constants'; -import getAdminVariables from '../graphql/queries/variables.query.graphql'; -import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql'; -import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql'; -import updateAdminVariable from '../graphql/mutations/admin_update_variable.mutation.graphql'; -import CiVariableShared from './ci_variable_shared.vue'; - -export default { - components: { - CiVariableShared, - }, - mutationData: { - [ADD_MUTATION_ACTION]: addAdminVariable, - [UPDATE_MUTATION_ACTION]: updateAdminVariable, - [DELETE_MUTATION_ACTION]: deleteAdminVariable, - }, - queryData: { - ciVariables: { - lookup: (data) => data?.ciVariables, - query: getAdminVariables, - }, - }, -}; -</script> - -<template> - <ci-variable-shared - :are-scoped-variables-available="false" - component-name="InstanceVariables" - :hide-environment-scope="true" - :mutation-data="$options.mutationData" - :refetch-after-mutation="true" - :query-data="$options.queryData" - /> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue b/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue deleted file mode 100644 index c9002edc1ab..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue +++ /dev/null @@ -1,90 +0,0 @@ -<script> -import { GlDropdown, GlDropdownItem, GlDropdownDivider, GlSearchBoxByType } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; -import { convertEnvironmentScope } from '../utils'; - -export default { - name: 'CiEnvironmentsDropdown', - components: { - GlDropdown, - GlDropdownItem, - GlDropdownDivider, - GlSearchBoxByType, - }, - props: { - environments: { - type: Array, - required: true, - }, - selectedEnvironmentScope: { - type: String, - required: false, - default: '', - }, - }, - data() { - return { - searchTerm: '', - }; - }, - computed: { - composedCreateButtonLabel() { - return sprintf(__('Create wildcard: %{searchTerm}'), { searchTerm: this.searchTerm }); - }, - filteredEnvironments() { - const lowerCasedSearchTerm = this.searchTerm.toLowerCase(); - return this.environments.filter((environment) => { - return environment.toLowerCase().includes(lowerCasedSearchTerm); - }); - }, - shouldRenderCreateButton() { - return this.searchTerm && !this.environments.includes(this.searchTerm); - }, - environmentScopeLabel() { - return convertEnvironmentScope(this.selectedEnvironmentScope); - }, - }, - methods: { - selectEnvironment(selected) { - this.$emit('select-environment', selected); - this.clearSearch(); - }, - convertEnvironmentScopeValue(scope) { - return convertEnvironmentScope(scope); - }, - createEnvironmentScope() { - this.$emit('create-environment-scope', this.searchTerm); - this.selectEnvironment(this.searchTerm); - }, - isSelected(env) { - return this.selectedEnvironmentScope === env; - }, - clearSearch() { - this.searchTerm = ''; - }, - }, -}; -</script> -<template> - <gl-dropdown :text="environmentScopeLabel" @show="clearSearch"> - <gl-search-box-by-type v-model.trim="searchTerm" data-testid="ci-environment-search" /> - <gl-dropdown-item - v-for="environment in filteredEnvironments" - :key="environment" - :is-checked="isSelected(environment)" - is-check-item - @click="selectEnvironment(environment)" - > - {{ convertEnvironmentScopeValue(environment) }} - </gl-dropdown-item> - <gl-dropdown-item v-if="!filteredEnvironments.length" ref="noMatchingResults">{{ - __('No matching results') - }}</gl-dropdown-item> - <template v-if="shouldRenderCreateButton"> - <gl-dropdown-divider /> - <gl-dropdown-item data-testid="create-wildcard-button" @click="createEnvironmentScope"> - {{ composedCreateButtonLabel }} - </gl-dropdown-item> - </template> - </gl-dropdown> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue deleted file mode 100644 index 4466a6a8081..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue +++ /dev/null @@ -1,54 +0,0 @@ -<script> -import { convertToGraphQLId } from '~/graphql_shared/utils'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import { - ADD_MUTATION_ACTION, - DELETE_MUTATION_ACTION, - GRAPHQL_GROUP_TYPE, - UPDATE_MUTATION_ACTION, -} from '../constants'; -import getGroupVariables from '../graphql/queries/group_variables.query.graphql'; -import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql'; -import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql'; -import updateGroupVariable from '../graphql/mutations/group_update_variable.mutation.graphql'; -import CiVariableShared from './ci_variable_shared.vue'; - -export default { - components: { - CiVariableShared, - }, - mixins: [glFeatureFlagsMixin()], - inject: ['groupPath', 'groupId'], - computed: { - areScopedVariablesAvailable() { - return this.glFeatures.groupScopedCiVariables; - }, - graphqlId() { - return convertToGraphQLId(GRAPHQL_GROUP_TYPE, this.groupId); - }, - }, - mutationData: { - [ADD_MUTATION_ACTION]: addGroupVariable, - [UPDATE_MUTATION_ACTION]: updateGroupVariable, - [DELETE_MUTATION_ACTION]: deleteGroupVariable, - }, - queryData: { - ciVariables: { - lookup: (data) => data?.group?.ciVariables, - query: getGroupVariables, - }, - }, -}; -</script> - -<template> - <ci-variable-shared - :id="graphqlId" - :are-scoped-variables-available="areScopedVariablesAvailable" - component-name="GroupVariables" - entity="group" - :full-path="groupPath" - :mutation-data="$options.mutationData" - :query-data="$options.queryData" - /> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue deleted file mode 100644 index 6326940148a..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue +++ /dev/null @@ -1,56 +0,0 @@ -<script> -import { convertToGraphQLId } from '~/graphql_shared/utils'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import { - ADD_MUTATION_ACTION, - DELETE_MUTATION_ACTION, - GRAPHQL_PROJECT_TYPE, - UPDATE_MUTATION_ACTION, -} from '../constants'; -import getProjectEnvironments from '../graphql/queries/project_environments.query.graphql'; -import getProjectVariables from '../graphql/queries/project_variables.query.graphql'; -import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql'; -import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql'; -import updateProjectVariable from '../graphql/mutations/project_update_variable.mutation.graphql'; -import CiVariableShared from './ci_variable_shared.vue'; - -export default { - components: { - CiVariableShared, - }, - mixins: [glFeatureFlagsMixin()], - inject: ['projectFullPath', 'projectId'], - computed: { - graphqlId() { - return convertToGraphQLId(GRAPHQL_PROJECT_TYPE, this.projectId); - }, - }, - mutationData: { - [ADD_MUTATION_ACTION]: addProjectVariable, - [UPDATE_MUTATION_ACTION]: updateProjectVariable, - [DELETE_MUTATION_ACTION]: deleteProjectVariable, - }, - queryData: { - ciVariables: { - lookup: (data) => data?.project?.ciVariables, - query: getProjectVariables, - }, - environments: { - lookup: (data) => data?.project?.environments, - query: getProjectEnvironments, - }, - }, -}; -</script> - -<template> - <ci-variable-shared - :id="graphqlId" - :are-scoped-variables-available="true" - component-name="ProjectVariables" - entity="project" - :full-path="projectFullPath" - :mutation-data="$options.mutationData" - :query-data="$options.queryData" - /> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_autocomplete_tokens.js b/app/assets/javascripts/ci_variable_list/components/ci_variable_autocomplete_tokens.js deleted file mode 100644 index 3f25e3df305..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_autocomplete_tokens.js +++ /dev/null @@ -1,15 +0,0 @@ -import { AWS_ACCESS_KEY_ID, AWS_DEFAULT_REGION, AWS_SECRET_ACCESS_KEY } from '../constants'; - -export const awsTokens = { - [AWS_ACCESS_KEY_ID]: { - name: AWS_ACCESS_KEY_ID, - }, - [AWS_DEFAULT_REGION]: { - name: AWS_DEFAULT_REGION, - }, - [AWS_SECRET_ACCESS_KEY]: { - name: AWS_SECRET_ACCESS_KEY, - }, -}; - -export const awsTokenList = Object.keys(awsTokens); diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue deleted file mode 100644 index 00177539cdc..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue +++ /dev/null @@ -1,503 +0,0 @@ -<script> -import { - GlAlert, - GlButton, - GlCollapse, - GlFormCheckbox, - GlFormCombobox, - GlFormGroup, - GlFormSelect, - GlFormInput, - GlFormTextarea, - GlIcon, - GlLink, - GlModal, - GlSprintf, -} from '@gitlab/ui'; -import { getCookie, setCookie } from '~/lib/utils/common_utils'; -import { __ } from '~/locale'; -import Tracking from '~/tracking'; - -import { - allEnvironments, - AWS_TOKEN_CONSTANTS, - ADD_CI_VARIABLE_MODAL_ID, - AWS_TIP_DISMISSED_COOKIE_NAME, - AWS_TIP_MESSAGE, - CONTAINS_VARIABLE_REFERENCE_MESSAGE, - defaultVariableState, - ENVIRONMENT_SCOPE_LINK_TITLE, - EVENT_LABEL, - EVENT_ACTION, - EXPANDED_VARIABLES_NOTE, - EDIT_VARIABLE_ACTION, - VARIABLE_ACTIONS, - variableOptions, -} from '../constants'; -import { createJoinedEnvironments } from '../utils'; -import CiEnvironmentsDropdown from './ci_environments_dropdown.vue'; -import { awsTokens, awsTokenList } from './ci_variable_autocomplete_tokens'; - -const trackingMixin = Tracking.mixin({ label: EVENT_LABEL }); - -export default { - modalId: ADD_CI_VARIABLE_MODAL_ID, - tokens: awsTokens, - tokenList: awsTokenList, - awsTipMessage: AWS_TIP_MESSAGE, - containsVariableReferenceMessage: CONTAINS_VARIABLE_REFERENCE_MESSAGE, - environmentScopeLinkTitle: ENVIRONMENT_SCOPE_LINK_TITLE, - expandedVariablesNote: EXPANDED_VARIABLES_NOTE, - components: { - CiEnvironmentsDropdown, - GlAlert, - GlButton, - GlCollapse, - GlFormCheckbox, - GlFormCombobox, - GlFormGroup, - GlFormSelect, - GlFormInput, - GlFormTextarea, - GlIcon, - GlLink, - GlModal, - GlSprintf, - }, - mixins: [trackingMixin], - inject: [ - 'awsLogoSvgPath', - 'awsTipCommandsLink', - 'awsTipDeployLink', - 'awsTipLearnLink', - 'containsVariableReferenceLink', - 'environmentScopeLink', - 'isProtectedByDefault', - 'maskedEnvironmentVariablesLink', - 'maskableRegex', - 'protectedEnvironmentVariablesLink', - ], - props: { - 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.maskableRegex); - return regex.test(this.variable.value); - }, - canSubmit() { - return this.variableValidationState && this.variable.key !== '' && this.variable.value !== ''; - }, - 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.variable.raw; - }, - isTipVisible() { - return !this.isTipDismissed && AWS_TOKEN_CONSTANTS.includes(this.variable.key); - }, - joinedEnvironments() { - return createJoinedEnvironments(this.variables, this.environments, this.newEnvironments); - }, - maskedFeedback() { - return this.displayMaskedError ? __('This variable can not be masked.') : ''; - }, - 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; - }, - variableValidationFeedback() { - return `${this.tokenValidationFeedback} ${this.maskedFeedback}`; - }, - variableValidationState() { - return this.variable.value === '' || (this.tokenValidationState && this.maskedState); - }, - }, - watch: { - variable: { - handler() { - this.trackVariableValidationErrors(); - }, - deep: true, - }, - }, - methods: { - addVariable() { - this.$emit('add-variable', this.variable); - }, - createEnvironmentScope(env) { - this.newEnvironments.push(env); - }, - 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('hideModal'); - }, - 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 = ''; - }, - }, - defaultScope: allEnvironments.text, - variableOptions, -}; -</script> - -<template> - <gl-modal - ref="modal" - :modal-id="$options.modalId" - :title="modalActionText" - static - lazy - @hidden="resetModalHandler" - @shown="onShow" - > - <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" - :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="variable.raw" - 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> - {{ __('Environment scope') }} - <gl-link - :title="$options.environmentScopeLinkTitle" - :href="environmentScopeLink" - target="_blank" - data-testid="environment-scope-link" - > - <gl-icon name="question" :size="12" /> - </gl-link> - </template> - <ci-environments-dropdown - v-if="areScopedVariablesAvailable" - class="gl-w-full" - :selected-environment-scope="variable.environmentScope" - :environments="joinedEnvironments" - @select-environment="setEnvironmentScope" - @create-environment-scope="createEnvironmentScope" - /> - - <gl-form-input v-else :value="$options.defaultScope" class="gl-w-full" readonly /> - </gl-form-group> - </template> - </div> - - <gl-form-group :label="__('Flags')" label-for="ci-variable-flags"> - <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') }} - <gl-link target="_blank" :href="protectedEnvironmentVariablesLink"> - <gl-icon name="question" :size="12" /> - </gl-link> - <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') }} - <gl-link target="_blank" :href="maskedEnvironmentVariablesLink"> - <gl-icon name="question" :size="12" /> - </gl-link> - <p class="gl-mt-2 text-secondary"> - {{ __('Variable will be masked in job logs.') }} - <span - :class="{ - 'bold text-plain': displayMaskedError, - }" - > - {{ __('Requires values to meet regular expression requirements.') }}</span - > - <gl-link target="_blank" :href="maskedEnvironmentVariablesLink">{{ - __('More information') - }}</gl-link> - </p> - </gl-form-checkbox> - <gl-form-checkbox - ref="expanded-ci-variable" - :checked="isExpanded" - data-testid="ci-variable-expanded-checkbox" - @change="setVariableRaw" - > - {{ __('Expand variable reference') }} - <gl-link target="_blank" :href="containsVariableReferenceLink"> - <gl-icon name="question" :size="12" /> - </gl-link> - <p class="gl-mt-2 gl-mb-0 gl-text-secondary"> - <gl-sprintf :message="$options.expandedVariablesNote"> - <template #code="{ content }"> - <code>{{ content }}</code> - </template> - </gl-sprintf> - </p> - </gl-form-checkbox> - </gl-form-group> - </form> - <gl-collapse :visible="isTipVisible"> - <gl-alert - :title="__('Deploying to AWS is easy with GitLab')" - variant="tip" - data-testid="aws-guidance-tip" - @dismiss="dismissTip" - > - <div class="gl-display-flex gl-flex-direction-row gl-flex-wrap-wrap gl-md-flex-wrap-nowrap"> - <div> - <p> - <gl-sprintf :message="$options.awsTipMessage"> - <template #deployLink="{ content }"> - <gl-link :href="awsTipDeployLink" target="_blank">{{ content }}</gl-link> - </template> - <template #commandsLink="{ content }"> - <gl-link :href="awsTipCommandsLink" target="_blank">{{ content }}</gl-link> - </template> - </gl-sprintf> - </p> - <p> - <gl-button - :href="awsTipLearnLink" - target="_blank" - category="secondary" - variant="confirm" - class="gl-overflow-wrap-break" - >{{ __('Learn more about deploying to AWS') }}</gl-button - > - </p> - </div> - <img - class="gl-mt-3" - :alt="__('Amazon Web Services Logo')" - :src="awsLogoSvgPath" - height="32" - /> - </div> - </gl-alert> - </gl-collapse> - <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.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" - data-qa-selector="ci_variable_delete_button" - @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_variable_list/components/ci_variable_settings.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_settings.vue deleted file mode 100644 index 3c6114b38ce..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_settings.vue +++ /dev/null @@ -1,108 +0,0 @@ -<script> -import { ADD_VARIABLE_ACTION, EDIT_VARIABLE_ACTION, VARIABLE_ACTIONS } from '../constants'; -import CiVariableTable from './ci_variable_table.vue'; -import CiVariableModal from './ci_variable_modal.vue'; - -export default { - components: { - CiVariableTable, - CiVariableModal, - }, - props: { - areScopedVariablesAvailable: { - type: Boolean, - required: false, - default: false, - }, - entity: { - type: String, - required: false, - default: '', - }, - environments: { - type: Array, - required: false, - default: () => [], - }, - hideEnvironmentScope: { - type: Boolean, - required: false, - default: false, - }, - isLoading: { - type: Boolean, - required: false, - }, - maxVariableLimit: { - type: Number, - required: false, - default: 0, - }, - variables: { - type: Array, - required: true, - }, - }, - data() { - return { - selectedVariable: {}, - mode: null, - }; - }, - computed: { - showModal() { - return VARIABLE_ACTIONS.includes(this.mode); - }, - }, - methods: { - addVariable(variable) { - this.$emit('add-variable', variable); - }, - deleteVariable(variable) { - this.$emit('delete-variable', variable); - }, - updateVariable(variable) { - this.$emit('update-variable', variable); - }, - hideModal() { - this.mode = null; - }, - setSelectedVariable(variable = null) { - if (!variable) { - this.selectedVariable = {}; - this.mode = ADD_VARIABLE_ACTION; - } else { - this.selectedVariable = variable; - this.mode = EDIT_VARIABLE_ACTION; - } - }, - }, -}; -</script> - -<template> - <div class="row"> - <div class="col-lg-12"> - <ci-variable-table - :entity="entity" - :is-loading="isLoading" - :max-variable-limit="maxVariableLimit" - :variables="variables" - @set-selected-variable="setSelectedVariable" - /> - <ci-variable-modal - v-if="showModal" - :are-scoped-variables-available="areScopedVariablesAvailable" - :environments="environments" - :hide-environment-scope="hideEnvironmentScope" - :variables="variables" - :mode="mode" - :selected-variable="selectedVariable" - @add-variable="addVariable" - @delete-variable="deleteVariable" - @hideModal="hideModal" - @update-variable="updateVariable" - /> - </div> - </div> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_shared.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_shared.vue deleted file mode 100644 index 6e39bda0b07..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_shared.vue +++ /dev/null @@ -1,242 +0,0 @@ -<script> -import { createAlert } from '~/flash'; -import { __ } from '~/locale'; -import { mapEnvironmentNames, reportMessageToSentry } from '../utils'; -import { - ADD_MUTATION_ACTION, - DELETE_MUTATION_ACTION, - UPDATE_MUTATION_ACTION, - environmentFetchErrorText, - genericMutationErrorText, - variableFetchErrorText, -} from '../constants'; -import CiVariableSettings from './ci_variable_settings.vue'; - -export default { - components: { - CiVariableSettings, - }, - inject: ['endpoint'], - props: { - areScopedVariablesAvailable: { - required: true, - type: Boolean, - }, - componentName: { - required: true, - type: String, - }, - entity: { - required: false, - type: String, - default: '', - }, - fullPath: { - required: false, - type: String, - default: null, - }, - hideEnvironmentScope: { - type: Boolean, - required: false, - default: false, - }, - id: { - required: false, - type: String, - default: null, - }, - mutationData: { - required: true, - type: Object, - validator: (obj) => { - const hasValidKeys = Object.keys(obj).includes( - ADD_MUTATION_ACTION, - UPDATE_MUTATION_ACTION, - DELETE_MUTATION_ACTION, - ); - - const hasValidValues = Object.values(obj).reduce((acc, val) => { - return acc && typeof val === 'object'; - }, true); - - return hasValidKeys && hasValidValues; - }, - }, - refetchAfterMutation: { - required: false, - type: Boolean, - default: false, - }, - queryData: { - required: true, - type: Object, - validator: (obj) => { - const { ciVariables, environments } = obj; - const hasCiVariablesKey = Boolean(ciVariables); - let hasCorrectEnvData = true; - - const hasCorrectVariablesData = - typeof ciVariables?.lookup === 'function' && typeof ciVariables.query === 'object'; - - if (environments) { - hasCorrectEnvData = - typeof environments?.lookup === 'function' && typeof environments.query === 'object'; - } - - return hasCiVariablesKey && hasCorrectVariablesData && hasCorrectEnvData; - }, - }, - }, - data() { - return { - ciVariables: [], - hasNextPage: false, - isInitialLoading: true, - isLoadingMoreItems: false, - loadingCounter: 0, - maxVariableLimit: 0, - pageInfo: {}, - }; - }, - apollo: { - ciVariables: { - query() { - return this.queryData.ciVariables.query; - }, - variables() { - return { - fullPath: this.fullPath || undefined, - }; - }, - update(data) { - return this.queryData.ciVariables.lookup(data)?.nodes || []; - }, - result({ data }) { - this.maxVariableLimit = this.queryData.ciVariables.lookup(data)?.limit || 0; - - this.pageInfo = this.queryData.ciVariables.lookup(data)?.pageInfo || this.pageInfo; - this.hasNextPage = this.pageInfo?.hasNextPage || false; - - // Because graphQL has a limit of 100 items, - // we batch load all the variables by making successive queries - // to keep the same UX. As a safeguard, we make sure that we cannot go over - // 20 consecutive API calls, which means 2000 variables loaded maximum. - if (!this.hasNextPage) { - this.isLoadingMoreItems = false; - } else if (this.loadingCounter < 20) { - this.hasNextPage = false; - this.fetchMoreVariables(); - this.loadingCounter += 1; - } else { - createAlert({ message: this.$options.tooManyCallsError }); - reportMessageToSentry(this.componentName, this.$options.tooManyCallsError, {}); - } - }, - error() { - this.isLoadingMoreItems = false; - this.hasNextPage = false; - createAlert({ message: variableFetchErrorText }); - }, - watchLoading(flag) { - if (!flag) { - this.isInitialLoading = false; - } - }, - }, - environments: { - query() { - return this.queryData?.environments?.query || {}; - }, - skip() { - return !this.queryData?.environments?.query; - }, - variables() { - return { - fullPath: this.fullPath, - }; - }, - update(data) { - return mapEnvironmentNames(this.queryData.environments.lookup(data)?.nodes); - }, - error() { - createAlert({ message: environmentFetchErrorText }); - }, - }, - }, - computed: { - isLoading() { - return ( - (this.$apollo.queries.ciVariables.loading && this.isInitialLoading) || - this.$apollo.queries.environments.loading || - this.isLoadingMoreItems - ); - }, - }, - methods: { - addVariable(variable) { - this.variableMutation(ADD_MUTATION_ACTION, variable); - }, - deleteVariable(variable) { - this.variableMutation(DELETE_MUTATION_ACTION, variable); - }, - fetchMoreVariables() { - this.isLoadingMoreItems = true; - - this.$apollo.queries.ciVariables.fetchMore({ - variables: { - after: this.pageInfo.endCursor, - }, - }); - }, - updateVariable(variable) { - this.variableMutation(UPDATE_MUTATION_ACTION, variable); - }, - async variableMutation(mutationAction, variable) { - try { - const currentMutation = this.mutationData[mutationAction]; - - const { data } = await this.$apollo.mutate({ - mutation: currentMutation, - variables: { - endpoint: this.endpoint, - fullPath: this.fullPath || undefined, - id: this.id || undefined, - variable, - }, - }); - - if (data.ciVariableMutation?.errors?.length) { - const { errors } = data.ciVariableMutation; - createAlert({ message: errors[0] }); - } else if (this.refetchAfterMutation) { - // The writing to cache for admin variable is not working - // because there is no ID in the cache at the top level. - // We therefore need to manually refetch. - this.$apollo.queries.ciVariables.refetch(); - } - } catch (e) { - createAlert({ message: genericMutationErrorText }); - } - }, - }, - i18n: { - tooManyCallsError: __('Maximum number of variables loaded (2000)'), - }, -}; -</script> - -<template> - <ci-variable-settings - :are-scoped-variables-available="areScopedVariablesAvailable" - :entity="entity" - :hide-environment-scope="hideEnvironmentScope" - :is-loading="isLoading" - :variables="ciVariables" - :max-variable-limit="maxVariableLimit" - :environments="environments" - @add-variable="addVariable" - @delete-variable="deleteVariable" - @update-variable="updateVariable" - /> -</template> diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue deleted file mode 100644 index 345a8def49d..00000000000 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue +++ /dev/null @@ -1,298 +0,0 @@ -<script> -import { - GlAlert, - GlButton, - GlLoadingIcon, - GlModalDirective, - GlTable, - GlTooltipDirective, -} from '@gitlab/ui'; -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, - variableText, -} from '../constants'; -import { convertEnvironmentScope } from '../utils'; - -export default { - modalId: ADD_CI_VARIABLE_MODAL_ID, - fields: [ - { - key: 'variableType', - label: s__('CiVariables|Type'), - thClass: 'gl-w-10p', - }, - { - key: 'key', - label: s__('CiVariables|Key'), - tdClass: 'text-plain', - sortable: true, - }, - { - key: 'value', - label: s__('CiVariables|Value'), - thClass: 'gl-w-15p', - }, - { - key: 'options', - label: s__('CiVariables|Options'), - thClass: 'gl-w-10p', - }, - { - key: 'environmentScope', - label: s__('CiVariables|Environments'), - }, - { - key: 'actions', - label: '', - tdClass: 'text-right', - thClass: 'gl-w-5p', - }, - ], - components: { - GlAlert, - GlButton, - GlLoadingIcon, - GlTable, - }, - directives: { - GlModalDirective, - GlTooltip: GlTooltipDirective, - }, - mixins: [glFeatureFlagsMixin()], - props: { - entity: { - type: String, - required: false, - default: '', - }, - isLoading: { - type: Boolean, - required: true, - }, - maxVariableLimit: { - type: Number, - required: true, - }, - variables: { - type: Array, - required: true, - }, - }, - data() { - return { - areValuesHidden: true, - }; - }, - computed: { - exceedsVariableLimit() { - return this.maxVariableLimit > 0 && this.variables.length >= this.maxVariableLimit; - }, - exceedsVariableLimitText() { - if (this.exceedsVariableLimit && this.entity) { - return sprintf(EXCEEDS_VARIABLE_LIMIT_TEXT, { - entity: this.entity, - currentVariableCount: this.variables.length, - maxVariableLimit: this.maxVariableLimit, - }); - } - - return DEFAULT_EXCEEDS_VARIABLE_LIMIT_TEXT; - }, - showAlert() { - return !this.isLoading && this.exceedsVariableLimit; - }, - valuesButtonText() { - return this.areValuesHidden ? __('Reveal values') : __('Hide values'); - }, - isTableEmpty() { - return !this.variables || this.variables.length === 0; - }, - fields() { - return this.$options.fields; - }, - variablesWithOptions() { - return this.variables?.map((item, index) => ({ - ...item, - options: this.getOptions(item), - index, - })); - }, - }, - methods: { - convertEnvironmentScopeValue(env) { - return convertEnvironmentScope(env); - }, - generateTypeText(item) { - return variableText[item.variableType]; - }, - toggleHiddenState() { - this.areValuesHidden = !this.areValuesHidden; - }, - setSelectedVariable(index = -1) { - this.$emit('set-selected-variable', this.variables[index] ?? null); - }, - getOptions(item) { - const options = []; - if (item.protected) { - options.push(s__('CiVariables|Protected')); - } - if (item.masked) { - options.push(s__('CiVariables|Masked')); - } - if (!item.raw) { - options.push(s__('CiVariables|Expanded')); - } - return options.join(', '); - }, - }, - maximumVariableLimitReached: MAXIMUM_VARIABLE_LIMIT_REACHED, -}; -</script> - -<template> - <div class="ci-variable-table" data-testid="ci-variable-table"> - <gl-loading-icon v-if="isLoading" /> - <gl-alert - v-if="showAlert" - :dismissible="false" - :title="$options.maximumVariableLimitReached" - variant="info" - > - {{ exceedsVariableLimitText }} - </gl-alert> - <gl-table - v-if="!isLoading" - :fields="fields" - :items="variablesWithOptions" - tbody-tr-class="js-ci-variable-row" - data-qa-selector="ci_variable_table_content" - sort-by="key" - sort-direction="asc" - stacked="lg" - table-class="text-secondary" - fixed - show-empty - sort-icon-left - no-sort-reset - > - <template #table-colgroup="scope"> - <col v-for="field in scope.fields" :key="field.key" :style="field.customStyle" /> - </template> - <template #cell(variableType)="{ item }"> - {{ generateTypeText(item) }} - </template> - <template #cell(key)="{ item }"> - <div - class="gl-display-flex gl-align-items-flex-start gl-justify-content-end gl-lg-justify-content-start gl-mr-n3" - > - <span - :id="`ci-variable-key-${item.id}`" - class="gl-display-inline-block gl-max-w-full gl-word-break-word" - >{{ item.key }}</span - > - <gl-button - v-gl-tooltip - category="tertiary" - icon="copy-to-clipboard" - class="gl-my-n3 gl-ml-2" - :title="__('Copy key')" - :data-clipboard-text="item.key" - :aria-label="__('Copy to clipboard')" - /> - </div> - </template> - <template #cell(value)="{ item }"> - <div - class="gl-display-flex gl-align-items-flex-start gl-justify-content-end gl-lg-justify-content-start gl-mr-n3" - > - <span v-if="areValuesHidden" data-testid="hiddenValue">*****</span> - <span - v-else - :id="`ci-variable-value-${item.id}`" - class="gl-display-inline-block gl-max-w-full gl-text-truncate" - data-testid="revealedValue" - >{{ item.value }}</span - > - <gl-button - v-gl-tooltip - category="tertiary" - icon="copy-to-clipboard" - class="gl-my-n3 gl-ml-2" - :title="__('Copy value')" - :data-clipboard-text="item.value" - :aria-label="__('Copy to clipboard')" - /> - </div> - </template> - <template #cell(options)="{ item }"> - <span data-testid="ci-variable-table-row-options">{{ item.options }}</span> - </template> - <template #cell(environmentScope)="{ item }"> - <div - class="gl-display-flex gl-align-items-flex-start gl-justify-content-end gl-lg-justify-content-start gl-mr-n3" - > - <span - :id="`ci-variable-env-${item.id}`" - class="gl-display-inline-block gl-max-w-full gl-word-break-word" - >{{ convertEnvironmentScopeValue(item.environmentScope) }}</span - > - <gl-button - v-gl-tooltip - category="tertiary" - icon="copy-to-clipboard" - class="gl-my-n3 gl-ml-2" - :title="__('Copy environment')" - :data-clipboard-text="convertEnvironmentScopeValue(item.environmentScope)" - :aria-label="__('Copy to clipboard')" - /> - </div> - </template> - <template #cell(actions)="{ item }"> - <gl-button - v-gl-modal-directive="$options.modalId" - icon="pencil" - :aria-label="__('Edit')" - data-qa-selector="edit_ci_variable_button" - @click="setSelectedVariable(item.index)" - /> - </template> - <template #empty> - <p class="gl-text-center gl-py-6 gl-text-black-normal gl-mb-0"> - {{ __('There are no variables yet.') }} - </p> - </template> - </gl-table> - <gl-alert - v-if="showAlert" - :dismissible="false" - :title="$options.maximumVariableLimitReached" - variant="info" - > - {{ exceedsVariableLimitText }} - </gl-alert> - <div class="ci-variable-actions gl-display-flex gl-mt-5"> - <gl-button - v-gl-modal-directive="$options.modalId" - class="gl-mr-3" - data-qa-selector="add_ci_variable_button" - variant="confirm" - category="primary" - :aria-label="__('Add')" - :disabled="exceedsVariableLimit" - @click="setSelectedVariable()" - >{{ __('Add variable') }}</gl-button - > - <gl-button - v-if="!isTableEmpty" - data-qa-selector="reveal_ci_variable_value_button" - @click="toggleHiddenState" - >{{ valuesButtonText }}</gl-button - > - </div> - </div> -</template> diff --git a/app/assets/javascripts/ci_variable_list/constants.js b/app/assets/javascripts/ci_variable_list/constants.js deleted file mode 100644 index 828d0724d93..00000000000 --- a/app/assets/javascripts/ci_variable_list/constants.js +++ /dev/null @@ -1,106 +0,0 @@ -import { __, s__ } from '~/locale'; - -export const ADD_CI_VARIABLE_MODAL_ID = 'add-ci-variable'; - -// This const will be deprecated once we remove VueX from the section -export const displayText = { - variableText: __('Variable'), - fileText: __('File'), - allEnvironmentsText: __('All (default)'), -}; - -export const variableTypes = { - envType: 'ENV_VAR', - fileType: 'FILE', -}; - -// Once REST is removed, we won't need `types` -export const types = { - variableType: 'env_var', - fileType: 'file', -}; - -export const allEnvironments = { - type: '*', - text: __('All (default)'), -}; - -// Once REST is removed, we won't need `types` key -export const variableText = { - [types.variableType]: __('Variable'), - [types.fileType]: __('File'), - [variableTypes.envType]: __('Variable'), - [variableTypes.fileType]: __('File'), -}; - -export const variableOptions = [ - { value: variableTypes.envType, text: variableText[variableTypes.envType] }, - { value: variableTypes.fileType, text: variableText[variableTypes.fileType] }, -]; - -export const defaultVariableState = { - environmentScope: allEnvironments.type, - key: '', - masked: false, - protected: false, - raw: false, - value: '', - variableType: variableTypes.envType, -}; - -// eslint-disable-next-line @gitlab/require-i18n-strings -export const groupString = 'Group'; -// eslint-disable-next-line @gitlab/require-i18n-strings -export const instanceString = 'Instance'; -// eslint-disable-next-line @gitlab/require-i18n-strings -export const projectString = 'Project'; - -export const AWS_TIP_DISMISSED_COOKIE_NAME = 'ci_variable_list_constants_aws_tip_dismissed'; -export const AWS_TIP_MESSAGE = __( - '%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use a docker image to %{commandsLinkStart}run AWS commands in GitLab CI/CD%{commandsLinkEnd}.', -); - -export const EVENT_LABEL = 'ci_variable_modal'; -export const EVENT_ACTION = 'validation_error'; - -// AWS TOKEN CONSTANTS -export const AWS_ACCESS_KEY_ID = 'AWS_ACCESS_KEY_ID'; -export const AWS_DEFAULT_REGION = 'AWS_DEFAULT_REGION'; -export const AWS_SECRET_ACCESS_KEY = 'AWS_SECRET_ACCESS_KEY'; -export const AWS_TOKEN_CONSTANTS = [AWS_ACCESS_KEY_ID, AWS_DEFAULT_REGION, AWS_SECRET_ACCESS_KEY]; - -export const CONTAINS_VARIABLE_REFERENCE_MESSAGE = __( - 'Unselect "Expand variable reference" if you want to use the variable value as a raw string.', -); - -export const ENVIRONMENT_SCOPE_LINK_TITLE = __('Learn more'); -export const EXCEEDS_VARIABLE_LIMIT_TEXT = s__( - 'CiVariables|This %{entity} has %{currentVariableCount} defined CI/CD variables. The maximum number of variables per %{entity} is %{maxVariableLimit}. To add new variables, you must reduce the number of defined variables.', -); -export const DEFAULT_EXCEEDS_VARIABLE_LIMIT_TEXT = s__( - 'CiVariables|You have reached the maximum number of variables available. To add new variables, you must reduce the number of defined variables.', -); -export const MAXIMUM_VARIABLE_LIMIT_REACHED = s__( - 'CiVariables|Maximum number of variables reached.', -); - -export const ADD_VARIABLE_ACTION = 'ADD_VARIABLE'; -export const EDIT_VARIABLE_ACTION = 'EDIT_VARIABLE'; -export const VARIABLE_ACTIONS = [ADD_VARIABLE_ACTION, EDIT_VARIABLE_ACTION]; - -export const GRAPHQL_PROJECT_TYPE = 'Project'; -export const GRAPHQL_GROUP_TYPE = 'Group'; - -export const ADD_MUTATION_ACTION = 'add'; -export const UPDATE_MUTATION_ACTION = 'update'; -export const DELETE_MUTATION_ACTION = 'delete'; - -export const EXPANDED_VARIABLES_NOTE = __( - '%{codeStart}$%{codeEnd} will be treated as the start of a reference to another variable.', -); - -export const environmentFetchErrorText = __( - 'There was an error fetching the environments information.', -); -export const genericMutationErrorText = __('Something went wrong on our end. Please try again.'); -export const variableFetchErrorText = __('There was an error fetching the variables.'); diff --git a/app/assets/javascripts/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql b/app/assets/javascripts/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql deleted file mode 100644 index a28ca4eebc9..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql +++ /dev/null @@ -1,7 +0,0 @@ -fragment BaseCiVariable on CiVariable { - __typename - id - key - value - variableType -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_add_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_add_variable.mutation.graphql deleted file mode 100644 index 9208c34f154..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_add_variable.mutation.graphql +++ /dev/null @@ -1,16 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation addAdminVariable($variable: CiVariable!, $endpoint: String!) { - ciVariableMutation: addAdminVariable(variable: $variable, endpoint: $endpoint) @client { - ciVariables { - nodes { - ...BaseCiVariable - ... on CiInstanceVariable { - protected - masked - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_delete_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_delete_variable.mutation.graphql deleted file mode 100644 index a79b98f5e95..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_delete_variable.mutation.graphql +++ /dev/null @@ -1,16 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation deleteAdminVariable($variable: CiVariable!, $endpoint: String!) { - ciVariableMutation: deleteAdminVariable(variable: $variable, endpoint: $endpoint) @client { - ciVariables { - nodes { - ...BaseCiVariable - ... on CiInstanceVariable { - protected - masked - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_update_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_update_variable.mutation.graphql deleted file mode 100644 index ddea753bf90..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/admin_update_variable.mutation.graphql +++ /dev/null @@ -1,16 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation updateAdminVariable($variable: CiVariable!, $endpoint: String!) { - ciVariableMutation: updateAdminVariable(variable: $variable, endpoint: $endpoint) @client { - ciVariables { - nodes { - ...BaseCiVariable - ... on CiInstanceVariable { - protected - masked - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql deleted file mode 100644 index 45109762e80..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation addProjectEnvironment($environment: CiEnvironment, $fullPath: ID!) { - addProjectEnvironment(environment: $environment, fullPath: $fullPath) @client -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_add_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/group_add_variable.mutation.graphql deleted file mode 100644 index 24388637672..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_add_variable.mutation.graphql +++ /dev/null @@ -1,26 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation addGroupVariable($variable: CiVariable!, $endpoint: String!, $fullPath: ID!, $id: ID!) { - ciVariableMutation: addGroupVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - group { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiGroupVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_delete_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/group_delete_variable.mutation.graphql deleted file mode 100644 index f7c8e209ccd..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_delete_variable.mutation.graphql +++ /dev/null @@ -1,26 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation deleteGroupVariable($variable: CiVariable!, $endpoint: String!, $fullPath: ID!, $id: ID!) { - ciVariableMutation: deleteGroupVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - group { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiGroupVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_update_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/group_update_variable.mutation.graphql deleted file mode 100644 index 757e61a5cd3..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/group_update_variable.mutation.graphql +++ /dev/null @@ -1,26 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation updateGroupVariable($variable: CiVariable!, $endpoint: String!, $fullPath: ID!, $id: ID!) { - ciVariableMutation: updateGroupVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - group { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiGroupVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql deleted file mode 100644 index fa315084d86..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql +++ /dev/null @@ -1,26 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation addProjectVariable($variable: CiVariable!, $endpoint: String!, $fullPath: ID!, $id: ID!) { - ciVariableMutation: addProjectVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - project { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiProjectVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql deleted file mode 100644 index c3358cc35b9..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql +++ /dev/null @@ -1,31 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation deleteProjectVariable( - $variable: CiVariable! - $endpoint: String! - $fullPath: ID! - $id: ID! -) { - ciVariableMutation: deleteProjectVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - project { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiProjectVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql deleted file mode 100644 index fde92cef4cb..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql +++ /dev/null @@ -1,31 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" - -mutation updateProjectVariable( - $variable: CiVariable! - $endpoint: String! - $fullPath: ID! - $id: ID! -) { - ciVariableMutation: updateProjectVariable( - variable: $variable - endpoint: $endpoint - fullPath: $fullPath - id: $id - ) @client { - project { - id - ciVariables { - nodes { - ...BaseCiVariable - ... on CiProjectVariable { - environmentScope - masked - protected - raw - } - } - } - } - errors - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/group_variables.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/group_variables.query.graphql deleted file mode 100644 index 900154cd24d..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/queries/group_variables.query.graphql +++ /dev/null @@ -1,23 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" -#import "~/graphql_shared/fragments/page_info.fragment.graphql" - -query getGroupVariables($after: String, $first: Int = 100, $fullPath: ID!) { - group(fullPath: $fullPath) { - id - ciVariables(after: $after, first: $first) { - limit - pageInfo { - ...PageInfo - } - nodes { - ...BaseCiVariable - ... on CiGroupVariable { - environmentScope - masked - protected - raw - } - } - } - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql deleted file mode 100644 index 921e0ca25b9..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query getProjectEnvironments($fullPath: ID!) { - project(fullPath: $fullPath) { - id - environments { - nodes { - id - name - } - } - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql deleted file mode 100644 index ee75eba7547..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql +++ /dev/null @@ -1,21 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" -#import "~/graphql_shared/fragments/page_info.fragment.graphql" - -query getProjectVariables($after: String, $first: Int = 100, $fullPath: ID!) { - project(fullPath: $fullPath) { - id - ciVariables(after: $after, first: $first) { - limit - pageInfo { - ...PageInfo - } - nodes { - ...BaseCiVariable - environmentScope - masked - protected - raw - } - } - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/variables.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/variables.query.graphql deleted file mode 100644 index 9b255c3c182..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/queries/variables.query.graphql +++ /dev/null @@ -1,18 +0,0 @@ -#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql" -#import "~/graphql_shared/fragments/page_info.fragment.graphql" - -query getVariables($after: String, $first: Int = 100) { - ciVariables(after: $after, first: $first) { - pageInfo { - ...PageInfo - } - nodes { - ...BaseCiVariable - ... on CiInstanceVariable { - masked - protected - raw - } - } - } -} diff --git a/app/assets/javascripts/ci_variable_list/graphql/settings.js b/app/assets/javascripts/ci_variable_list/graphql/settings.js deleted file mode 100644 index 02f6c226b0f..00000000000 --- a/app/assets/javascripts/ci_variable_list/graphql/settings.js +++ /dev/null @@ -1,242 +0,0 @@ -import axios from 'axios'; -import { - convertObjectPropsToCamelCase, - convertObjectPropsToSnakeCase, -} from '../../lib/utils/common_utils'; -import { convertToGraphQLId, getIdFromGraphQLId } from '../../graphql_shared/utils'; -import { - GRAPHQL_GROUP_TYPE, - GRAPHQL_PROJECT_TYPE, - groupString, - instanceString, - projectString, -} from '../constants'; -import getProjectVariables from './queries/project_variables.query.graphql'; -import getGroupVariables from './queries/group_variables.query.graphql'; -import getAdminVariables from './queries/variables.query.graphql'; - -const prepareVariableForApi = ({ variable, destroy = false }) => { - return { - ...convertObjectPropsToSnakeCase(variable), - id: getIdFromGraphQLId(variable?.id), - variable_type: variable.variableType.toLowerCase(), - secret_value: variable.value, - _destroy: destroy, - }; -}; - -const mapVariableTypes = (variables = [], kind) => { - return variables.map((ciVar) => { - return { - __typename: `Ci${kind}Variable`, - ...convertObjectPropsToCamelCase(ciVar), - id: convertToGraphQLId('Ci::Variable', ciVar.id), - variableType: ciVar.variable_type ? ciVar.variable_type.toUpperCase() : ciVar.variableType, - }; - }); -}; - -const prepareProjectGraphQLResponse = ({ data, id, errors = [] }) => { - return { - errors, - project: { - __typename: GRAPHQL_PROJECT_TYPE, - id: convertToGraphQLId(GRAPHQL_PROJECT_TYPE, id), - ciVariables: { - __typename: `Ci${GRAPHQL_PROJECT_TYPE}VariableConnection`, - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: false, - startCursor: '', - endCursor: '', - }, - nodes: mapVariableTypes(data.variables, projectString), - }, - }, - }; -}; - -const prepareGroupGraphQLResponse = ({ data, id, errors = [] }) => { - return { - errors, - group: { - __typename: GRAPHQL_GROUP_TYPE, - id: convertToGraphQLId(GRAPHQL_GROUP_TYPE, id), - ciVariables: { - __typename: `Ci${GRAPHQL_GROUP_TYPE}VariableConnection`, - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: false, - startCursor: '', - endCursor: '', - }, - nodes: mapVariableTypes(data.variables, groupString), - }, - }, - }; -}; - -const prepareAdminGraphQLResponse = ({ data, errors = [] }) => { - return { - errors, - ciVariables: { - __typename: `Ci${instanceString}VariableConnection`, - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: false, - startCursor: '', - endCursor: '', - }, - nodes: mapVariableTypes(data.variables, instanceString), - }, - }; -}; - -async function callProjectEndpoint({ endpoint, fullPath, variable, id, cache, destroy = false }) { - try { - const { data } = await axios.patch(endpoint, { - variables_attributes: [prepareVariableForApi({ variable, destroy })], - }); - - const graphqlData = prepareProjectGraphQLResponse({ data, id }); - - cache.writeQuery({ - query: getProjectVariables, - variables: { - fullPath, - after: null, - }, - data: graphqlData, - }); - return graphqlData; - } catch (e) { - return prepareProjectGraphQLResponse({ - data: cache.readQuery({ query: getProjectVariables, variables: { fullPath } }), - id, - errors: [...e.response.data], - }); - } -} - -const callGroupEndpoint = async ({ endpoint, fullPath, variable, id, cache, destroy = false }) => { - try { - const { data } = await axios.patch(endpoint, { - variables_attributes: [prepareVariableForApi({ variable, destroy })], - }); - - const graphqlData = prepareGroupGraphQLResponse({ data, id }); - - cache.writeQuery({ - query: getGroupVariables, - data: graphqlData, - }); - - return graphqlData; - } catch (e) { - return prepareGroupGraphQLResponse({ - data: cache.readQuery({ query: getGroupVariables, variables: { fullPath } }), - id, - errors: [...e.response.data], - }); - } -}; - -const callAdminEndpoint = async ({ endpoint, variable, cache, destroy = false }) => { - try { - const { data } = await axios.patch(endpoint, { - variables_attributes: [prepareVariableForApi({ variable, destroy })], - }); - - const graphqlData = prepareAdminGraphQLResponse({ data }); - - cache.writeQuery({ - query: getAdminVariables, - data: graphqlData, - }); - - return graphqlData; - } catch (e) { - return prepareAdminGraphQLResponse({ - data: cache.readQuery({ query: getAdminVariables }), - errors: [...e.response.data], - }); - } -}; - -export const resolvers = { - Mutation: { - addProjectVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callProjectEndpoint({ endpoint, fullPath, variable, id, cache }); - }, - updateProjectVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callProjectEndpoint({ endpoint, fullPath, variable, id, cache }); - }, - deleteProjectVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callProjectEndpoint({ endpoint, fullPath, variable, id, cache, destroy: true }); - }, - addGroupVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callGroupEndpoint({ endpoint, fullPath, variable, id, cache }); - }, - updateGroupVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callGroupEndpoint({ endpoint, fullPath, variable, id, cache }); - }, - deleteGroupVariable: async (_, { endpoint, fullPath, variable, id }, { cache }) => { - return callGroupEndpoint({ endpoint, fullPath, variable, id, cache, destroy: true }); - }, - addAdminVariable: async (_, { endpoint, variable }, { cache }) => { - return callAdminEndpoint({ endpoint, variable, cache }); - }, - updateAdminVariable: async (_, { endpoint, variable }, { cache }) => { - return callAdminEndpoint({ endpoint, variable, cache }); - }, - deleteAdminVariable: async (_, { endpoint, variable }, { cache }) => { - return callAdminEndpoint({ endpoint, variable, cache, destroy: true }); - }, - }, -}; - -export const mergeVariables = (existing, incoming, { args }) => { - if (!existing || !args?.after) { - return incoming; - } - - const { nodes, ...rest } = incoming; - const result = rest; - result.nodes = [...existing.nodes, ...nodes]; - - return result; -}; - -export const cacheConfig = { - cacheConfig: { - typePolicies: { - Query: { - fields: { - ciVariables: { - keyArgs: false, - merge: mergeVariables, - }, - }, - }, - Project: { - fields: { - ciVariables: { - keyArgs: ['fullPath', 'endpoint', 'id'], - merge: mergeVariables, - }, - }, - }, - Group: { - fields: { - ciVariables: { - keyArgs: ['fullPath'], - merge: mergeVariables, - }, - }, - }, - }, - }, -}; diff --git a/app/assets/javascripts/ci_variable_list/index.js b/app/assets/javascripts/ci_variable_list/index.js deleted file mode 100644 index 174a59aba42..00000000000 --- a/app/assets/javascripts/ci_variable_list/index.js +++ /dev/null @@ -1,83 +0,0 @@ -import Vue from 'vue'; -import VueApollo from 'vue-apollo'; -import createDefaultClient from '~/lib/graphql'; -import { parseBoolean } from '~/lib/utils/common_utils'; -import CiAdminVariables from './components/ci_admin_variables.vue'; -import CiGroupVariables from './components/ci_group_variables.vue'; -import CiProjectVariables from './components/ci_project_variables.vue'; -import { cacheConfig, resolvers } from './graphql/settings'; - -const mountCiVariableListApp = (containerEl) => { - const { - awsLogoSvgPath, - awsTipCommandsLink, - awsTipDeployLink, - awsTipLearnLink, - containsVariableReferenceLink, - endpoint, - environmentScopeLink, - groupId, - groupPath, - isGroup, - isProject, - maskedEnvironmentVariablesLink, - maskableRegex, - projectFullPath, - projectId, - protectedByDefault, - protectedEnvironmentVariablesLink, - } = containerEl.dataset; - - const parsedIsProject = parseBoolean(isProject); - const parsedIsGroup = parseBoolean(isGroup); - const isProtectedByDefault = parseBoolean(protectedByDefault); - - let component = CiAdminVariables; - - if (parsedIsGroup) { - component = CiGroupVariables; - } else if (parsedIsProject) { - component = CiProjectVariables; - } - - Vue.use(VueApollo); - - const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(resolvers, cacheConfig), - }); - - return new Vue({ - el: containerEl, - apolloProvider, - provide: { - awsLogoSvgPath, - awsTipCommandsLink, - awsTipDeployLink, - awsTipLearnLink, - containsVariableReferenceLink, - endpoint, - environmentScopeLink, - groupId, - groupPath, - isGroup: parsedIsGroup, - isProject: parsedIsProject, - isProtectedByDefault, - maskedEnvironmentVariablesLink, - maskableRegex, - projectFullPath, - projectId, - protectedEnvironmentVariablesLink, - }, - render(createElement) { - return createElement(component); - }, - }); -}; - -export default (containerId = 'js-ci-variables') => { - const el = document.getElementById(containerId); - - if (!el) return; - - mountCiVariableListApp(el); -}; diff --git a/app/assets/javascripts/ci_variable_list/native_form_variable_list.js b/app/assets/javascripts/ci_variable_list/native_form_variable_list.js deleted file mode 100644 index fdbefd8c313..00000000000 --- a/app/assets/javascripts/ci_variable_list/native_form_variable_list.js +++ /dev/null @@ -1,25 +0,0 @@ -import $ from 'jquery'; -import VariableList from './ci_variable_list'; - -// Used for the variable list on scheduled pipeline edit page -export default function setupNativeFormVariableList({ container, formField = 'variables' }) { - const $container = $(container); - - const variableList = new VariableList({ - container: $container, - formField, - }); - variableList.init(); - - // Clear out the names in the empty last row so it - // doesn't get submitted and throw validation errors - $container.closest('form').on('submit trigger-submit', () => { - const $lastRow = $container.find('.js-row').last(); - - const isTouched = variableList.checkIfRowTouched($lastRow); - if (!isTouched) { - $lastRow.find('input, textarea').attr('name', ''); - $lastRow.find('select').attr('name', ''); - } - }); -} diff --git a/app/assets/javascripts/ci_variable_list/utils.js b/app/assets/javascripts/ci_variable_list/utils.js deleted file mode 100644 index eeca69274ce..00000000000 --- a/app/assets/javascripts/ci_variable_list/utils.js +++ /dev/null @@ -1,60 +0,0 @@ -import * as Sentry from '@sentry/browser'; -import { uniq } from 'lodash'; -import { allEnvironments } from './constants'; - -/** - * This function takes a list of variable, environments and - * new environments added through the scope dropdown - * and create a new Array that concatenate the environment list - * with the environment scopes find in the variable list. This is - * useful for variable settings so that we can render a list of all - * environment scopes available based on the list of envs, the ones the user - * added explictly and what is found under each variable. - * @param {Array} variables - * @param {Array} environments - * @returns {Array} - Array of environments - */ - -export const createJoinedEnvironments = ( - variables = [], - environments = [], - newEnvironments = [], -) => { - const scopesFromVariables = variables.map((variable) => variable.environmentScope); - return uniq([...environments, ...newEnvironments, ...scopesFromVariables]).sort(); -}; - -/** - * This function job is to convert the * wildcard to text when applicable - * in the UI. It uses a constants to compare the incoming value to that - * of the * and then apply the corresponding label if applicable. If there - * is no scope, then we return the default value as well. - * @param {String} scope - * @returns {String} - Converted value if applicable - */ - -export const convertEnvironmentScope = (environmentScope = '') => { - if (environmentScope === allEnvironments.type || !environmentScope) { - return allEnvironments.text; - } - - return environmentScope; -}; - -/** - * Gives us an array of all the environments by name - * @param {Array} nodes - * @return {Array<String>} - Array of environments strings - */ -export const mapEnvironmentNames = (nodes = []) => { - return nodes.map((env) => env.name); -}; - -export const reportMessageToSentry = (component, message, context) => { - Sentry.withScope((scope) => { - // eslint-disable-next-line @gitlab/require-i18n-strings - scope.setContext('Vue data', context); - scope.setTag('component', component); - Sentry.captureMessage(message); - }); -}; |