Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
commitdb384e6b19af03b4c3c82a5760d83a3fd79f7982 (patch)
tree34beaef37df5f47ccbcf5729d7583aae093cffa0 /app/assets/javascripts/ci
parent54fd7b1bad233e3944434da91d257fa7f63c3996 (diff)
Add latest changes from gitlab-org/gitlab@16-3-stable-eev16.3.0-rc42
Diffstat (limited to 'app/assets/javascripts/ci')
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_group_variables.vue11
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue233
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_modal.vue68
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue32
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue397
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/constants.js17
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/index.js8
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue6
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue6
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue2
-rw-r--r--app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue16
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue66
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue13
-rw-r--r--app/assets/javascripts/ci/reports/codequality_report/store/index.js1
-rw-r--r--app/assets/javascripts/ci/reports/components/report_item.vue2
-rw-r--r--app/assets/javascripts/ci/reports/components/report_section.vue5
-rw-r--r--app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue6
-rw-r--r--app/assets/javascripts/ci/runner/admin_runners/index.js16
-rw-r--r--app/assets/javascripts/ci/runner/admin_runners/provide.js22
-rw-r--r--app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue2
-rw-r--r--app/assets/javascripts/ci/runner/components/registration/registration_token.vue1
-rw-r--r--app/assets/javascripts/ci/runner/components/runner_details.vue5
-rw-r--r--app/assets/javascripts/ci/runner/components/runner_filtered_search_bar.vue2
-rw-r--r--app/assets/javascripts/ci/runner/components/search_tokens/paused_token_config.js19
-rw-r--r--app/assets/javascripts/ci/runner/components/search_tokens/status_token_config.js23
-rw-r--r--app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue11
30 files changed, 662 insertions, 332 deletions
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_group_variables.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_group_variables.vue
index 2045b127a82..842d88e1267 100644
--- a/app/assets/javascripts/ci/ci_variable_list/components/ci_group_variables.vue
+++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_group_variables.vue
@@ -23,15 +23,6 @@ export default {
graphqlId() {
return convertToGraphQLId(TYPENAME_GROUP, this.groupId);
},
- queriesAvailable() {
- if (this.glFeatures.ciGroupEnvScopeGraphql) {
- return this.$options.queryData;
- }
-
- return {
- ciVariables: this.$options.queryData.ciVariables,
- };
- },
},
mutationData: {
[ADD_MUTATION_ACTION]: addGroupVariable,
@@ -59,6 +50,6 @@ export default {
entity="group"
:full-path="groupPath"
:mutation-data="$options.mutationData"
- :query-data="queriesAvailable"
+ :query-data="$options.queryData"
/>
</template>
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue
new file mode 100644
index 00000000000..0ce11da658c
--- /dev/null
+++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue
@@ -0,0 +1,233 @@
+<script>
+import {
+ GlButton,
+ GlDrawer,
+ GlFormCheckbox,
+ GlFormCombobox,
+ GlFormGroup,
+ GlFormSelect,
+ GlFormTextarea,
+ GlIcon,
+ GlLink,
+ GlSprintf,
+} from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
+import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import {
+ defaultVariableState,
+ ENVIRONMENT_SCOPE_LINK_TITLE,
+ EXPANDED_VARIABLES_NOTE,
+ FLAG_LINK_TITLE,
+ VARIABLE_ACTIONS,
+ variableOptions,
+} from '../constants';
+import CiEnvironmentsDropdown from './ci_environments_dropdown.vue';
+import { awsTokenList } from './ci_variable_autocomplete_tokens';
+
+const i18n = {
+ addVariable: s__('CiVariables|Add Variable'),
+ cancel: __('Cancel'),
+ environments: __('Environments'),
+ environmentScopeLinkTitle: ENVIRONMENT_SCOPE_LINK_TITLE,
+ expandedField: s__('CiVariables|Expand variable reference'),
+ expandedDescription: EXPANDED_VARIABLES_NOTE,
+ flags: __('Flags'),
+ flagsLinkTitle: FLAG_LINK_TITLE,
+ key: __('Key'),
+ maskedField: s__('CiVariables|Mask variable'),
+ maskedDescription: s__(
+ 'CiVariables|Variable will be masked in job logs. Requires values to meet regular expression requirements.',
+ ),
+ protectedField: s__('CiVariables|Protect variable'),
+ protectedDescription: s__(
+ 'CiVariables|Export variable to pipelines running on protected branches and tags only.',
+ ),
+ type: __('Type'),
+ value: __('Value'),
+};
+
+export default {
+ DRAWER_Z_INDEX,
+ components: {
+ CiEnvironmentsDropdown,
+ GlButton,
+ GlDrawer,
+ GlFormCheckbox,
+ GlFormCombobox,
+ GlFormGroup,
+ GlFormSelect,
+ GlFormTextarea,
+ GlIcon,
+ GlLink,
+ GlSprintf,
+ },
+ inject: ['environmentScopeLink'],
+ props: {
+ areEnvironmentsLoading: {
+ type: Boolean,
+ required: true,
+ },
+ environments: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ hasEnvScopeQuery: {
+ type: Boolean,
+ required: true,
+ },
+ mode: {
+ type: String,
+ required: true,
+ validator(val) {
+ return VARIABLE_ACTIONS.includes(val);
+ },
+ },
+ },
+ data() {
+ return {
+ key: defaultVariableState.key,
+ variableType: defaultVariableState.variableType,
+ };
+ },
+ computed: {
+ getDrawerHeaderHeight() {
+ return getContentWrapperHeight();
+ },
+ },
+ methods: {
+ close() {
+ this.$emit('close-form');
+ },
+ },
+ awsTokenList,
+ flagLink: helpPagePath('ci/variables/index', {
+ anchor: 'define-a-cicd-variable-in-the-ui',
+ }),
+ i18n,
+ variableOptions,
+};
+</script>
+<template>
+ <gl-drawer
+ open
+ data-testid="ci-variable-drawer"
+ :header-height="getDrawerHeaderHeight"
+ :z-index="$options.DRAWER_Z_INDEX"
+ @close="close"
+ >
+ <template #title>
+ <h2 class="gl-m-0">{{ $options.i18n.addVariable }}</h2>
+ </template>
+ <gl-form-group
+ :label="$options.i18n.type"
+ label-for="ci-variable-type"
+ class="gl-border-none gl-mb-n5"
+ >
+ <gl-form-select
+ id="ci-variable-type"
+ v-model="variableType"
+ :options="$options.variableOptions"
+ />
+ </gl-form-group>
+ <gl-form-group
+ class="gl-border-none gl-mb-n5"
+ label-for="ci-variable-env"
+ data-testid="environment-scope"
+ >
+ <template #label>
+ <div class="gl-display-flex gl-align-items-center">
+ <span class="gl-mr-2">
+ {{ $options.i18n.environments }}
+ </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
+ class="gl-mb-5"
+ :are-environments-loading="areEnvironmentsLoading"
+ :environments="environments"
+ :has-env-scope-query="hasEnvScopeQuery"
+ selected-environment-scope=""
+ />
+ </gl-form-group>
+ <gl-form-group class="gl-border-none gl-mb-n8">
+ <template #label>
+ <div class="gl-display-flex gl-align-items-center gl-mb-n3">
+ <span class="gl-mr-2">
+ {{ $options.i18n.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 data-testid="ci-variable-protected-checkbox">
+ {{ $options.i18n.protectedField }}
+ <p class="gl-text-secondary">
+ {{ $options.i18n.protectedDescription }}
+ </p>
+ </gl-form-checkbox>
+ <gl-form-checkbox data-testid="ci-variable-masked-checkbox">
+ {{ $options.i18n.maskedField }}
+ <p class="gl-text-secondary">{{ $options.i18n.maskedDescription }}</p>
+ </gl-form-checkbox>
+ <gl-form-checkbox data-testid="ci-variable-expanded-checkbox">
+ {{ $options.i18n.expandedField }}
+ <p class="gl-text-secondary">
+ <gl-sprintf :message="$options.i18n.expandedDescription" class="gl-text-secondary">
+ <template #code="{ content }">
+ <code>{{ content }}</code>
+ </template>
+ </gl-sprintf>
+ </p>
+ </gl-form-checkbox>
+ </gl-form-group>
+ <gl-form-combobox
+ v-model="key"
+ :token-list="$options.awsTokenList"
+ :label-text="$options.i18n.key"
+ class="gl-border-none gl-pb-0! gl-mb-n5"
+ data-testid="pipeline-form-ci-variable-key"
+ data-qa-selector="ci_variable_key_field"
+ />
+ <gl-form-group
+ :label="$options.i18n.value"
+ label-for="ci-variable-value"
+ class="gl-border-none gl-mb-n2"
+ >
+ <gl-form-textarea
+ id="ci-variable-value"
+ class="gl-border-none gl-font-monospace!"
+ rows="3"
+ max-rows="10"
+ data-testid="pipeline-form-ci-variable-value"
+ data-qa-selector="ci_variable_value_field"
+ spellcheck="false"
+ />
+ </gl-form-group>
+ <div class="gl-display-flex gl-justify-content-end">
+ <gl-button category="primary" class="gl-mr-3" data-testid="cancel-button" @click="close"
+ >{{ $options.i18n.cancel }}
+ </gl-button>
+ <gl-button category="primary" variant="confirm" data-testid="confirm-button"
+ >{{ $options.i18n.addVariable }}
+ </gl-button>
+ </div>
+ </gl-drawer>
+</template>
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
index 3af48635f3f..86c0f34215e 100644
--- 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
@@ -25,6 +25,7 @@ import {
AWS_TOKEN_CONSTANTS,
ADD_CI_VARIABLE_MODAL_ID,
AWS_TIP_DISMISSED_COOKIE_NAME,
+ AWS_TIP_TITLE,
AWS_TIP_MESSAGE,
CONTAINS_VARIABLE_REFERENCE_MESSAGE,
defaultVariableState,
@@ -62,10 +63,6 @@ export default {
},
mixins: [glFeatureFlagsMixin(), trackingMixin],
inject: [
- 'awsLogoSvgPath',
- 'awsTipCommandsLink',
- 'awsTipDeployLink',
- 'awsTipLearnLink',
'containsVariableReferenceLink',
'environmentScopeLink',
'isProtectedByDefault',
@@ -241,7 +238,7 @@ export default {
this.resetVariableData();
this.resetValidationErrorEvents();
- this.$emit('hideModal');
+ this.$emit('close-form');
},
resetVariableData() {
this.variable = { ...defaultVariableState };
@@ -295,6 +292,7 @@ export default {
},
},
i18n: {
+ awsTipTitle: AWS_TIP_TITLE,
awsTipMessage: AWS_TIP_MESSAGE,
containsVariableReferenceMessage: CONTAINS_VARIABLE_REFERENCE_MESSAGE,
defaultScope: allEnvironments.text,
@@ -305,6 +303,9 @@ export default {
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,
@@ -322,6 +323,23 @@ export default {
@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"
@@ -468,45 +486,7 @@ export default {
</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 gl-md-flex-nowrap gl-gap-3">
- <div>
- <p>
- <gl-sprintf :message="$options.i18n.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')"
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 b8a95f9081a..f4e1da9b34f 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
@@ -1,13 +1,17 @@
<script>
+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: {
areEnvironmentsLoading: {
type: Boolean,
@@ -62,23 +66,32 @@ export default {
};
},
computed: {
- showModal() {
+ 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) {
this.$emit('add-variable', variable);
},
+ closeForm() {
+ this.mode = null;
+ },
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 = {};
@@ -104,6 +117,7 @@ export default {
@handle-prev-page="$emit('handle-prev-page')"
@handle-next-page="$emit('handle-next-page')"
@set-selected-variable="setSelectedVariable"
+ @delete-variable="deleteVariable"
@sort-changed="(val) => $emit('sort-changed', val)"
/>
<ci-variable-modal
@@ -118,10 +132,18 @@ export default {
:selected-variable="selectedVariable"
@add-variable="addVariable"
@delete-variable="deleteVariable"
- @hideModal="hideModal"
+ @close-form="closeForm"
@update-variable="updateVariable"
@search-environment-scope="$emit('search-environment-scope', $event)"
/>
+ <ci-variable-drawer
+ v-if="showDrawer"
+ :are-environments-loading="areEnvironmentsLoading"
+ :has-env-scope-query="hasEnvScopeQuery"
+ :mode="mode"
+ v-on="$listeners"
+ @close-form="closeForm"
+ />
</div>
</div>
</template>
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 ec7a921664f..a14cd1e387a 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
@@ -3,11 +3,14 @@ import {
GlAlert,
GlBadge,
GlButton,
+ GlCard,
+ GlIcon,
GlLoadingIcon,
GlModalDirective,
GlKeysetPagination,
GlLink,
GlTable,
+ GlModal,
GlTooltipDirective,
} from '@gitlab/ui';
import { __, s__, sprintf } from '~/locale';
@@ -45,9 +48,8 @@ export default {
},
{
key: 'actions',
- label: '',
- tdClass: 'text-right',
- thClass: 'gl-w-5p',
+ label: __('Actions'),
+ thClass: 'gl-text-right',
},
],
inheritedVarsFields: [
@@ -73,10 +75,13 @@ export default {
GlAlert,
GlBadge,
GlButton,
+ GlCard,
GlKeysetPagination,
GlLink,
+ GlIcon,
GlLoadingIcon,
GlTable,
+ GlModal,
},
directives: {
GlModalDirective,
@@ -84,6 +89,14 @@ export default {
},
mixins: [glFeatureFlagsMixin()],
inject: ['isInheritedGroupVars'],
+ i18n: {
+ title: s__('CiVariables|CI/CD Variables'),
+ addButton: s__('CiVariables|Add variable'),
+ editButton: __('Edit'),
+ deleteButton: __('Delete'),
+ modalDeleteTitle: s__('CiVariables|Delete variable'),
+ modalDeleteMessage: s__('CiVariables|Do you want to delete the variable %{key}?'),
+ },
props: {
entity: {
type: String,
@@ -107,6 +120,20 @@ export default {
required: true,
},
},
+ deleteModal: {
+ actionPrimary: {
+ text: __('Delete'),
+ attributes: {
+ variant: 'danger',
+ },
+ },
+ actionSecondary: {
+ text: __('Cancel'),
+ attributes: {
+ variant: 'default',
+ },
+ },
+ },
data() {
return {
areValuesHidden: true,
@@ -165,6 +192,9 @@ export default {
setSelectedVariable(index = -1) {
this.$emit('set-selected-variable', this.variables[index] ?? null);
},
+ deleteSelectedVariable(index = -1) {
+ this.$emit('delete-variable', this.variables[index] ?? null);
+ },
getAttributes(item) {
const attributes = [];
if (item.variableType === variableTypes.fileType) {
@@ -181,188 +211,219 @@ export default {
}
return attributes;
},
+ removeVariableMessage(key) {
+ return sprintf(this.$options.i18n.modalDeleteMessage, {
+ key,
+ });
+ },
},
maximumVariableLimitReached: MAXIMUM_VARIABLE_LIMIT_REACHED,
};
</script>
<template>
- <div class="ci-variable-table" :data-testid="tableDataTestId">
- <gl-loading-icon v-if="isLoading" />
- <gl-alert
- v-if="showAlert"
- :dismissible="false"
- :title="$options.maximumVariableLimitReached"
- variant="info"
- >
- {{ exceedsVariableLimitText }}
- </gl-alert>
- <div
- v-if="showPagination && !isInheritedGroupVars"
- class="ci-variable-actions gl-display-flex gl-justify-content-end gl-my-3"
+ <div>
+ <gl-card
+ class="gl-new-card ci-variable-table"
+ header-class="gl-new-card-header"
+ body-class="gl-new-card-body gl-px-0"
+ :data-testid="tableDataTestId"
>
- <gl-button v-if="!isTableEmpty" @click="toggleHiddenState">{{ valuesButtonText }}</gl-button>
- <gl-button
- v-gl-modal-directive="$options.modalId"
- class="gl-mx-3"
- data-qa-selector="add_ci_variable_button"
- variant="confirm"
- category="primary"
- :aria-label="__('Add')"
- :disabled="exceedsVariableLimit"
- @click="setSelectedVariable()"
- >{{ __('Add variable') }}</gl-button
- >
- </div>
- <gl-table
- v-if="!isLoading"
- :fields="fields"
- :items="variablesWithAttributes"
- tbody-tr-class="js-ci-variable-row"
- sort-by="key"
- sort-direction="asc"
- stacked="lg"
- fixed
- show-empty
- sort-icon-left
- no-sort-reset
- no-local-sorting
- @sort-changed="(val) => $emit('sort-changed', val)"
- >
- <template #table-colgroup="scope">
- <col v-for="field in scope.fields" :key="field.key" :style="field.customStyle" />
- </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
- >
+ <template #header>
+ <div class="gl-new-card-title-wrapper">
+ <h5 class="gl-new-card-title">{{ $options.i18n.title }}</h5>
+ <span class="gl-new-card-count">
+ <gl-icon name="code" class="gl-mr-2" />
+ {{ variables.length }}
+ </span>
+ </div>
+ <div v-if="!isInheritedGroupVars" class="gl-new-card-actions gl-font-size-0">
<gl-button
- v-gl-tooltip
+ v-if="!isTableEmpty"
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 v-if="!isInheritedGroupVars" #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
+ size="small"
+ class="gl-mr-3"
+ @click="toggleHiddenState"
+ >{{ valuesButtonText }}</gl-button
>
<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')"
- />
+ v-gl-modal-directive="$options.modalId"
+ size="small"
+ :disabled="exceedsVariableLimit"
+ data-qa-selector="add_ci_variable_button"
+ data-testid="add-ci-variable-button"
+ @click="setSelectedVariable()"
+ >{{ $options.i18n.addButton }}</gl-button
+ >
</div>
</template>
- <template #cell(attributes)="{ item }">
- <span data-testid="ci-variable-table-row-attributes">
- <gl-badge
- v-for="attribute in item.attributes"
- :key="`${item.key}-${attribute}`"
- class="gl-mr-2"
- variant="info"
- size="sm"
+
+ <gl-loading-icon v-if="isLoading" class="gl-p-4" />
+ <gl-alert
+ v-if="showAlert"
+ :dismissible="false"
+ :title="$options.maximumVariableLimitReached"
+ variant="info"
+ >
+ {{ exceedsVariableLimitText }}
+ </gl-alert>
+ <gl-table
+ v-if="!isLoading"
+ :fields="fields"
+ :items="variablesWithAttributes"
+ tbody-tr-class="js-ci-variable-row"
+ sort-by="key"
+ sort-direction="asc"
+ stacked="md"
+ fixed
+ show-empty
+ sort-icon-left
+ no-sort-reset
+ no-local-sorting
+ @sort-changed="(val) => $emit('sort-changed', val)"
+ >
+ <template #table-colgroup="scope">
+ <col v-for="field in scope.fields" :key="field.key" :style="field.customStyle" />
+ </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"
>
- {{ attribute }}
- </gl-badge>
- </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
+ <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 v-if="!isInheritedGroupVars" #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"
>
- <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 v-if="isInheritedGroupVars" #cell(group)="{ item }">
- <div
- class="gl-display-flex gl-align-items-flex-start gl-justify-content-end gl-lg-justify-content-start gl-mr-n3"
- >
- <gl-link
- :id="`ci-variable-group-${item.id}`"
- data-testid="ci-variable-table-row-cicd-path"
- class="gl-display-inline-block gl-max-w-full gl-word-break-word"
- :href="item.groupCiCdSettingsPath"
+ <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(attributes)="{ item }">
+ <span data-testid="ci-variable-table-row-attributes">
+ <gl-badge
+ v-for="attribute in item.attributes"
+ :key="`${item.key}-${attribute}`"
+ class="gl-mr-2"
+ variant="info"
+ size="sm"
+ >
+ {{ attribute }}
+ </gl-badge>
+ </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"
>
- {{ item.groupName }}
- </gl-link>
- </div>
- </template>
- <template v-if="!isInheritedGroupVars" #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>
+ <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 v-if="isInheritedGroupVars" #cell(group)="{ item }">
+ <div
+ class="gl-display-flex gl-align-items-flex-start gl-justify-content-end gl-lg-justify-content-start gl-mr-n3"
+ >
+ <gl-link
+ :id="`ci-variable-group-${item.id}`"
+ data-testid="ci-variable-table-row-cicd-path"
+ class="gl-display-inline-block gl-max-w-full gl-word-break-word"
+ :href="item.groupCiCdSettingsPath"
+ >
+ {{ item.groupName }}
+ </gl-link>
+ </div>
+ </template>
+ <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"
+ :aria-label="$options.i18n.editButton"
+ data-qa-selector="edit_ci_variable_button"
+ @click="setSelectedVariable(item.index)"
+ />
+ <gl-button
+ v-gl-modal-directive="`delete-variable-${item.index}`"
+ variant="danger"
+ category="secondary"
+ icon="remove"
+ size="small"
+ :aria-label="$options.i18n.deleteButton"
+ data-qa-selector="delete_ci_variable_button"
+ />
+ <gl-modal
+ ref="modal"
+ :modal-id="`delete-variable-${item.index}`"
+ :title="$options.i18n.modalDeleteTitle"
+ :action-primary="$options.deleteModal.actionPrimary"
+ :action-secondary="$options.deleteModal.actionSecondary"
+ @primary="deleteSelectedVariable(item.index)"
+ >
+ {{ removeVariableMessage(item.key) }}
+ </gl-modal>
+ </div>
+ </template>
+ <template #empty>
+ <p class="gl-text-secondary gl-text-center gl-py-1 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>
+ </gl-card>
<div v-if="!isInheritedGroupVars">
- <div v-if="!showPagination" 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" @click="toggleHiddenState">{{
- valuesButtonText
- }}</gl-button>
- </div>
- <div v-else class="gl-display-flex gl-justify-content-center gl-mt-6">
+ <div v-if="showPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination
v-bind="pageInfo"
:prev-text="__('Previous')"
diff --git a/app/assets/javascripts/ci/ci_variable_list/constants.js b/app/assets/javascripts/ci/ci_variable_list/constants.js
index d702dd073ec..825b39e0cf9 100644
--- a/app/assets/javascripts/ci/ci_variable_list/constants.js
+++ b/app/assets/javascripts/ci/ci_variable_list/constants.js
@@ -7,14 +7,6 @@ export const SORT_DIRECTIONS = {
ASC: 'KEY_ASC',
DESC: 'KEY_DESC',
};
-
-// 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',
@@ -26,8 +18,8 @@ export const allEnvironments = {
};
export const variableOptions = [
- { value: variableTypes.envType, text: variableTypes.envType },
- { value: variableTypes.fileType, text: variableTypes.fileType },
+ { value: variableTypes.envType, text: __('Variable (default)') },
+ { value: variableTypes.fileType, text: __('File') },
];
export const defaultVariableState = {
@@ -48,8 +40,9 @@ export const instanceString = 'Instance';
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 AWS_TIP_TITLE = s__('CiVariable|Use OIDC to securely connect to cloud services');
+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';
diff --git a/app/assets/javascripts/ci/ci_variable_list/index.js b/app/assets/javascripts/ci/ci_variable_list/index.js
index e47b41ceae5..9342f57f2d8 100644
--- a/app/assets/javascripts/ci/ci_variable_list/index.js
+++ b/app/assets/javascripts/ci/ci_variable_list/index.js
@@ -10,10 +10,6 @@ import { generateCacheConfig, resolvers } from './graphql/settings';
const mountCiVariableListApp = (containerEl) => {
const {
- awsLogoSvgPath,
- awsTipCommandsLink,
- awsTipDeployLink,
- awsTipLearnLink,
containsVariableReferenceLink,
endpoint,
environmentScopeLink,
@@ -57,10 +53,6 @@ const mountCiVariableListApp = (containerEl) => {
el: containerEl,
apolloProvider,
provide: {
- awsLogoSvgPath,
- awsTipCommandsLink,
- awsTipDeployLink,
- awsTipLearnLink,
containsVariableReferenceLink,
endpoint,
environmentScopeLink,
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue
index 6ba8884f9a6..bc0cad75c60 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue
@@ -107,7 +107,6 @@ export default {
v-if="glFeatures.ciJobAssistantDrawer"
icon="bulb"
size="small"
- data-testid="job-assistant-drawer-toggle"
data-qa-selector="job_assistant_drawer_toggle"
@click="toggleJobAssistantDrawer"
>
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
index 656b1a6c347..f1c9770714a 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue
@@ -1,7 +1,7 @@
<script>
import { __ } from '~/locale';
import { keepLatestDownstreamPipelines } from '~/pipelines/components/parsing_utils';
-import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue';
+import LegacyPipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph.vue';
import getLinkedPipelinesQuery from '~/pipelines/graphql/queries/get_linked_pipelines.query.graphql';
import { PIPELINE_FAILURE } from '../../constants';
@@ -10,7 +10,7 @@ export default {
linkedPipelinesFetchError: __('Unable to fetch upstream and downstream pipelines.'),
},
components: {
- PipelineMiniGraph,
+ LegacyPipelineMiniGraph,
},
inject: ['projectFullPath'],
props: {
@@ -84,7 +84,7 @@ export default {
</script>
<template>
- <pipeline-mini-graph
+ <legacy-pipeline-mini-graph
v-if="hasPipelineStages"
:downstream-pipelines="downstreamPipelines"
:pipeline-path="pipelinePath"
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue
index bb79a4d74da..3bce50224d9 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue
@@ -11,7 +11,7 @@ import {
} from '~/pipelines/components/graph/utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
-import GraphqlPipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/graphql_pipeline_mini_graph.vue';
+import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue';
import PipelineEditorMiniGraph from './pipeline_editor_mini_graph.vue';
const POLL_INTERVAL = 10000;
@@ -34,8 +34,8 @@ export default {
GlLink,
GlLoadingIcon,
GlSprintf,
- GraphqlPipelineMiniGraph,
PipelineEditorMiniGraph,
+ PipelineMiniGraph,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -179,7 +179,7 @@ export default {
</span>
</div>
<div class="gl-display-flex gl-flex-wrap-wrap">
- <graphql-pipeline-mini-graph
+ <pipeline-mini-graph
v-if="isUsingPipelineMiniGraphQueries"
:full-path="projectFullPath"
:iid="pipeline.iid"
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
index d7b8e7151d9..25e4e99bf54 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
@@ -61,6 +61,7 @@ export default {
<gl-button
variant="confirm"
class="gl-mt-3"
+ data-testid="create_new_ci_button"
data-qa-selector="create_new_ci_button"
@click="createEmptyConfigFile"
>
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue b/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue
index ba33888e2fb..7583fa7a3b5 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue
@@ -201,7 +201,6 @@ export default {
:title="$options.i18n.pipelineSourceTooltip"
:toggle-text="$options.i18n.pipelineSourceDefault"
disabled
- data-testid="pipeline-source"
/>
<validate-pipeline-popover />
<gl-icon
diff --git a/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue
index 0495546529a..41e5199e204 100644
--- a/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue
@@ -3,9 +3,9 @@ import { GlModal } from '@gitlab/ui';
import { __ } from '~/locale';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import JobAssistantDrawer from 'jh_else_ce/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue';
import CommitSection from './components/commit/commit_section.vue';
import PipelineEditorDrawer from './components/drawer/pipeline_editor_drawer.vue';
-import JobAssistantDrawer from './components/job_assistant_drawer/job_assistant_drawer.vue';
import PipelineEditorFileNav from './components/file_nav/pipeline_editor_file_nav.vue';
import PipelineEditorFileTree from './components/file_tree/container.vue';
import PipelineEditorHeader from './components/header/pipeline_editor_header.vue';
diff --git a/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue b/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue
index 6fd5c8130ad..cc7d9bd2340 100644
--- a/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue
+++ b/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue
@@ -476,7 +476,6 @@ export default {
<gl-dropdown-item
v-for="option in configVariablesWithDescription.options[variable.key]"
:key="option"
- data-testid="pipeline-form-ci-variable-value-dropdown-items"
data-qa-selector="ci_variable_value_dropdown_item"
@click="setVariableAttribute(variable.key, 'value', option)"
>
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue
index 0700d9e5439..c993b65f6c0 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue
@@ -94,6 +94,7 @@ export default {
return {
schedules: {
list: [],
+ currentUser: {},
},
scope,
hasError: false,
@@ -135,6 +136,14 @@ export default {
},
];
},
+ onAllTab() {
+ // scope is undefined on first load, scope is only defined
+ // after tab switching
+ return this.scope === ALL_SCOPE || !this.scope;
+ },
+ showEmptyState() {
+ return !this.isLoading && this.schedulesCount === 0 && this.onAllTab;
+ },
},
watch: {
// this watcher ensures that the count on the all tab
@@ -258,8 +267,10 @@ export default {
</gl-sprintf>
</gl-alert>
+ <pipeline-schedule-empty-state v-if="showEmptyState" />
+
<gl-tabs
- v-if="isLoading || schedulesCount > 0"
+ v-else
sync-active-tab-with-query-params
query-param-name="scope"
nav-class="gl-flex-grow-1 gl-align-items-center gl-mt-2"
@@ -284,6 +295,7 @@ export default {
</template>
<gl-loading-icon v-if="isLoading" size="lg" />
+
<pipeline-schedules-table
v-else
:schedules="schedules.list"
@@ -306,8 +318,6 @@ export default {
</template>
</gl-tabs>
- <pipeline-schedule-empty-state v-else-if="!isLoading && schedulesCount === 0" />
-
<take-ownership-modal
:visible="showTakeOwnershipModal"
@takeOwnership="takeOwnership"
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
index d84a9a4a4b5..396ff9808f2 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
@@ -112,6 +112,7 @@ export default {
cronTimezone: '',
variables: [],
schedule: {},
+ showVarValues: false,
};
},
i18n: {
@@ -140,6 +141,8 @@ export default {
scheduleFetchError: s__(
'PipelineSchedules|An error occurred while trying to fetch the pipeline schedule.',
),
+ revealText: __('Reveal values'),
+ hideText: __('Hide values'),
},
typeOptions: {
[VARIABLE_TYPE]: __('Variable'),
@@ -167,11 +170,24 @@ export default {
getEnabledRefTypes() {
return [REF_TYPE_BRANCHES, REF_TYPE_TAGS];
},
+ filledVariables() {
+ return this.variables.filter((variable) => variable.key !== '' && !variable.empty);
+ },
preparedVariablesUpdate() {
- return this.variables.filter((variable) => variable.key !== '');
+ return this.filledVariables.map((variable) => {
+ return {
+ id: variable.id,
+ key: variable.key,
+ value: variable.value,
+ variableType: variable.variableType,
+ destroy: variable.destroy,
+ };
+ });
},
preparedVariablesCreate() {
- return this.preparedVariablesUpdate.map((variable) => {
+ const vars = this.variables.filter((variable) => variable.key !== '');
+
+ return vars.map((variable) => {
return {
key: variable.key,
value: variable.value,
@@ -187,6 +203,15 @@ export default {
? this.$options.i18n.editScheduleBtnText
: this.$options.i18n.createScheduleBtnText;
},
+ varSecurityBtnText() {
+ return this.showVarValues ? this.$options.i18n.hideText : this.$options.i18n.revealText;
+ },
+ hasExistingScheduleVariables() {
+ return this.schedule?.variables?.nodes.length > 0;
+ },
+ showVarSecurityBtn() {
+ return this.editing && this.hasExistingScheduleVariables;
+ },
},
created() {
this.addEmptyVariable();
@@ -204,6 +229,7 @@ export default {
key: '',
value: '',
destroy: false,
+ empty: true,
});
},
setVariableAttribute(key, attribute, value) {
@@ -289,6 +315,14 @@ export default {
setTimezone(timezone) {
this.cronTimezone = timezone.identifier || '';
},
+ displayHiddenChars(variable) {
+ return (
+ this.editing && this.hasExistingScheduleVariables && !this.showVarValues && !variable.empty
+ );
+ },
+ resetVariable(index) {
+ this.variables[index].empty = false;
+ },
},
};
</script>
@@ -342,7 +376,7 @@ export default {
/>
</gl-form-group>
<!--Variable List-->
- <gl-form-group :label="$options.i18n.variables">
+ <gl-form-group class="gl-mb-2" :label="$options.i18n.variables">
<div
v-for="(variable, index) in variables"
:key="`var-${index}`"
@@ -372,10 +406,21 @@ export default {
:class="$options.formElementClasses"
data-testid="pipeline-form-ci-variable-key"
data-qa-selector="ci_variable_key_field"
- @change="addEmptyVariable()"
+ @change="addEmptyVariable(variable)"
/>
<gl-form-textarea
+ v-if="displayHiddenChars(variable)"
+ value="*****************"
+ disabled
+ class="gl-mb-3 gl-h-7!"
+ :style="$options.textAreaStyle"
+ :no-resize="false"
+ data-testid="pipeline-form-ci-variable-hidden-value"
+ />
+
+ <gl-form-textarea
+ v-else
v-model="variable.value"
:placeholder="s__('CiVariables|Input variable value')"
class="gl-mb-3 gl-h-7!"
@@ -383,6 +428,7 @@ export default {
:no-resize="false"
data-testid="pipeline-form-ci-variable-value"
data-qa-selector="ci_variable_value_field"
+ @change="resetVariable(index)"
/>
<template v-if="variables.length > 1">
@@ -406,6 +452,18 @@ export default {
</div>
</div>
</gl-form-group>
+
+ <gl-button
+ v-if="showVarSecurityBtn"
+ class="gl-mb-5"
+ category="secondary"
+ variant="confirm"
+ data-testid="variable-security-btn"
+ @click="showVarValues = !showVarValues"
+ >
+ {{ varSecurityBtnText }}
+ </gl-button>
+
<!--Activated-->
<gl-form-checkbox id="schedule-active" v-model="activated" class="gl-mb-3">
{{ $options.i18n.activated }}
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue
index b97914f8c26..368cfb9c10d 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue
@@ -1,5 +1,5 @@
<script>
-import { GlTableLite } from '@gitlab/ui';
+import { GlTable } from '@gitlab/ui';
import { s__ } from '~/locale';
import PipelineScheduleActions from './cells/pipeline_schedule_actions.vue';
import PipelineScheduleLastPipeline from './cells/pipeline_schedule_last_pipeline.vue';
@@ -8,6 +8,9 @@ import PipelineScheduleOwner from './cells/pipeline_schedule_owner.vue';
import PipelineScheduleTarget from './cells/pipeline_schedule_target.vue';
export default {
+ i18n: {
+ emptyText: s__('PipelineSchedules|No pipeline schedules'),
+ },
fields: [
{
key: 'description',
@@ -47,7 +50,7 @@ export default {
},
],
components: {
- GlTableLite,
+ GlTable,
PipelineScheduleActions,
PipelineScheduleLastPipeline,
PipelineScheduleNextRun,
@@ -68,10 +71,12 @@ export default {
</script>
<template>
- <gl-table-lite
+ <gl-table
:fields="$options.fields"
:items="schedules"
:tbody-tr-attr="{ 'data-testid': 'pipeline-schedule-table-row' }"
+ :empty-text="$options.i18n.emptyText"
+ show-empty
stacked="md"
>
<template #table-colgroup="{ fields }">
@@ -109,5 +114,5 @@ export default {
@playPipelineSchedule="$emit('playPipelineSchedule', $event)"
/>
</template>
- </gl-table-lite>
+ </gl-table>
</template>
diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/index.js b/app/assets/javascripts/ci/reports/codequality_report/store/index.js
index 5bfcd69edec..c2f706e56e6 100644
--- a/app/assets/javascripts/ci/reports/codequality_report/store/index.js
+++ b/app/assets/javascripts/ci/reports/codequality_report/store/index.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import * as actions from './actions';
import * as getters from './getters';
diff --git a/app/assets/javascripts/ci/reports/components/report_item.vue b/app/assets/javascripts/ci/reports/components/report_item.vue
index ca1f3301691..7342df6da67 100644
--- a/app/assets/javascripts/ci/reports/components/report_item.vue
+++ b/app/assets/javascripts/ci/reports/components/report_item.vue
@@ -53,7 +53,7 @@ export default {
};
</script>
<template>
- <li class="report-block-list-issue gl-p-3!" data-qa-selector="report_item_row">
+ <li class="report-block-list-issue gl-p-3!" data-testid="report-item-row">
<component
:is="iconComponent"
v-if="showReportSectionStatusIcon"
diff --git a/app/assets/javascripts/ci/reports/components/report_section.vue b/app/assets/javascripts/ci/reports/components/report_section.vue
index 468c8916b8d..a4ec7b6a325 100644
--- a/app/assets/javascripts/ci/reports/components/report_section.vue
+++ b/app/assets/javascripts/ci/reports/components/report_section.vue
@@ -185,10 +185,7 @@ export default {
<div class="media">
<status-icon :status="statusIconName" :size="24" class="align-self-center" />
<div class="media-body gl-display-flex gl-align-items-flex-start gl-flex-direction-row!">
- <div
- data-testid="report-section-code-text"
- class="js-code-text code-text gl-align-self-center gl-flex-grow-1"
- >
+ <div class="js-code-text code-text gl-align-self-center gl-flex-grow-1">
<div class="gl-display-flex gl-align-items-center">
<p class="gl-line-height-normal gl-m-0">{{ headerText }}</p>
<slot :name="slotName"></slot>
diff --git a/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue b/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue
index 2168685e703..e6813211fe9 100644
--- a/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue
+++ b/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue
@@ -52,6 +52,8 @@ export default {
RunnerTypeTabs,
RunnerActionsCell,
RunnerJobStatusBadge,
+ RunnerDashboardLink: () =>
+ import('ee_component/ci/runner/components/runner_dashboard_link.vue'),
},
mixins: [glFeatureFlagMixin()],
props: {
@@ -188,12 +190,12 @@ export default {
nav-class="gl-border-none!"
/>
- <div class="gl-w-full gl-md-w-auto gl-display-flex">
+ <div class="gl-w-full gl-md-w-auto gl-display-flex gl-gap-3">
+ <runner-dashboard-link />
<gl-button :href="newRunnerPath" variant="confirm">
{{ s__('Runners|New instance runner') }}
</gl-button>
<registration-dropdown
- class="gl-ml-3"
:registration-token="registrationToken"
:type="$options.INSTANCE_TYPE"
placement="right"
diff --git a/app/assets/javascripts/ci/runner/admin_runners/index.js b/app/assets/javascripts/ci/runner/admin_runners/index.js
index 54eb37f8c90..d4df1393487 100644
--- a/app/assets/javascripts/ci/runner/admin_runners/index.js
+++ b/app/assets/javascripts/ci/runner/admin_runners/index.js
@@ -1,6 +1,9 @@
import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+
+import { provide } from 'ee_else_ce/ci/runner/admin_runners/provide';
+
import { visitUrl } from '~/lib/utils/url_utility';
import { updateOutdatedUrl } from '~/ci/runner/runner_search_utils';
import createDefaultClient from '~/lib/graphql';
@@ -29,14 +32,7 @@ export const initAdminRunners = (selector = '#js-admin-runners') => {
return null;
}
- const {
- runnerInstallHelpPage,
- newRunnerPath,
- registrationToken,
- onlineContactTimeoutSecs,
- staleTimeoutSecs,
- } = el.dataset;
-
+ const { newRunnerPath, registrationToken } = el.dataset;
const { cacheConfig, typeDefs, localMutations } = createLocalState();
const apolloProvider = new VueApollo({
@@ -47,10 +43,8 @@ export const initAdminRunners = (selector = '#js-admin-runners') => {
el,
apolloProvider,
provide: {
- runnerInstallHelpPage,
+ ...provide(el.dataset),
localMutations,
- onlineContactTimeoutSecs,
- staleTimeoutSecs,
},
render(h) {
return h(AdminRunnersApp, {
diff --git a/app/assets/javascripts/ci/runner/admin_runners/provide.js b/app/assets/javascripts/ci/runner/admin_runners/provide.js
new file mode 100644
index 00000000000..81a39801718
--- /dev/null
+++ b/app/assets/javascripts/ci/runner/admin_runners/provide.js
@@ -0,0 +1,22 @@
+/**
+ * Provides global values to the admin runners app.
+ *
+ * @param {Object} `data-` HTML attributes of the mounting point
+ * @returns An object with properties to use provide/inject of the root app.
+ * See EE version
+ */
+export const provide = (elDataset) => {
+ const {
+ runnerInstallHelpPage,
+ onlineContactTimeoutSecs,
+ staleTimeoutSecs,
+ tagSuggestionsPath,
+ } = elDataset;
+
+ return {
+ runnerInstallHelpPage,
+ onlineContactTimeoutSecs,
+ staleTimeoutSecs,
+ tagSuggestionsPath,
+ };
+};
diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue
index 69021dde0e9..771ecb1a0d4 100644
--- a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue
+++ b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue
@@ -163,7 +163,7 @@ export default {
"
>
<template #link="{ content }">
- <gl-link data-testid="runner-install-link" @click="toggleDrawer">{{ content }}</gl-link>
+ <gl-link @click="toggleDrawer">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_token.vue b/app/assets/javascripts/ci/runner/components/registration/registration_token.vue
index 339c92a427f..50d2fcfa961 100644
--- a/app/assets/javascripts/ci/runner/components/registration/registration_token.vue
+++ b/app/assets/javascripts/ci/runner/components/registration/registration_token.vue
@@ -45,6 +45,7 @@ export default {
:label-for="inputId"
:copy-button-title="$options.I18N_COPY_BUTTON_TITLE"
:form-input-group-props="formInputGroupProps"
+ readonly
@copy="onCopy"
>
<template v-for="slot in Object.keys($scopedSlots)" #[slot]>
diff --git a/app/assets/javascripts/ci/runner/components/runner_details.vue b/app/assets/javascripts/ci/runner/components/runner_details.vue
index 8c1280cffb9..fac90fb0370 100644
--- a/app/assets/javascripts/ci/runner/components/runner_details.vue
+++ b/app/assets/javascripts/ci/runner/components/runner_details.vue
@@ -94,10 +94,7 @@ export default {
<div>
<runner-upgrade-status-alert class="gl-my-4" :runner="runner" />
<div class="gl-pt-4">
- <dl
- class="gl-mb-0 gl-display-grid runner-details-grid-template"
- data-testid="runner-details-list"
- >
+ <dl class="gl-mb-0 gl-display-grid runner-details-grid-template">
<runner-detail :label="s__('Runners|Description')" :value="runner.description" />
<runner-detail
:label="s__('Runners|Last contact')"
diff --git a/app/assets/javascripts/ci/runner/components/runner_filtered_search_bar.vue b/app/assets/javascripts/ci/runner/components/runner_filtered_search_bar.vue
index ee56fea8282..3634dcf1c93 100644
--- a/app/assets/javascripts/ci/runner/components/runner_filtered_search_bar.vue
+++ b/app/assets/javascripts/ci/runner/components/runner_filtered_search_bar.vue
@@ -93,6 +93,8 @@ export default {
:tokens="validTokens"
:initial-sort-by="initialSortBy"
:search-input-placeholder="__('Search or filter results...')"
+ :search-text-option-label="s__('Runners|Search description...')"
+ terms-as-tokens
data-testid="runners-filtered-search"
@onFilter="onFilter"
@onSort="onSort"
diff --git a/app/assets/javascripts/ci/runner/components/search_tokens/paused_token_config.js b/app/assets/javascripts/ci/runner/components/search_tokens/paused_token_config.js
index 71a145dd4a3..5bec9804002 100644
--- a/app/assets/javascripts/ci/runner/components/search_tokens/paused_token_config.js
+++ b/app/assets/javascripts/ci/runner/components/search_tokens/paused_token_config.js
@@ -3,26 +3,15 @@ import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/consta
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { PARAM_KEY_PAUSED, I18N_PAUSED } from '../../constants';
-const options = [
- { value: 'true', title: __('Yes') },
- { value: 'false', title: __('No') },
-];
-
export const pausedTokenConfig = {
icon: 'pause',
title: I18N_PAUSED,
type: PARAM_KEY_PAUSED,
token: BaseToken,
unique: true,
- options: options.map(({ value, title }) => ({
- value,
- // Replace whitespace with a special character to avoid
- // splitting this value.
- // Replacing in each option, as translations may also
- // contain spaces!
- // see: https://gitlab.com/gitlab-org/gitlab/-/issues/344142
- // see: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1438
- title: title.replace(/\s/g, '\u00a0'),
- })),
+ options: [
+ { value: 'true', title: __('Yes') },
+ { value: 'false', title: __('No') },
+ ],
operators: OPERATORS_IS,
};
diff --git a/app/assets/javascripts/ci/runner/components/search_tokens/status_token_config.js b/app/assets/javascripts/ci/runner/components/search_tokens/status_token_config.js
index 4bc32909777..1e4774bff72 100644
--- a/app/assets/javascripts/ci/runner/components/search_tokens/status_token_config.js
+++ b/app/assets/javascripts/ci/runner/components/search_tokens/status_token_config.js
@@ -15,28 +15,17 @@ import {
PARAM_KEY_STATUS,
} from '../../constants';
-const options = [
- { value: STATUS_ONLINE, title: I18N_STATUS_ONLINE },
- { value: STATUS_OFFLINE, title: I18N_STATUS_OFFLINE },
- { value: STATUS_NEVER_CONTACTED, title: I18N_STATUS_NEVER_CONTACTED },
- { value: STATUS_STALE, title: I18N_STATUS_STALE },
-];
-
export const statusTokenConfig = {
icon: 'status',
title: TOKEN_TITLE_STATUS,
type: PARAM_KEY_STATUS,
token: BaseToken,
unique: true,
- options: options.map(({ value, title }) => ({
- value,
- // Replace whitespace with a special character to avoid
- // splitting this value.
- // Replacing in each option, as translations may also
- // contain spaces!
- // see: https://gitlab.com/gitlab-org/gitlab/-/issues/344142
- // see: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1438
- title: title.replace(/\s/g, '\u00a0'),
- })),
+ options: [
+ { value: STATUS_ONLINE, title: I18N_STATUS_ONLINE },
+ { value: STATUS_OFFLINE, title: I18N_STATUS_OFFLINE },
+ { value: STATUS_NEVER_CONTACTED, title: I18N_STATUS_NEVER_CONTACTED },
+ { value: STATUS_STALE, title: I18N_STATUS_STALE },
+ ],
operators: OPERATORS_IS,
};
diff --git a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue
index 1de7775090a..dd1cca0a05c 100644
--- a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue
+++ b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue
@@ -7,20 +7,13 @@ import { s__ } from '~/locale';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { RUNNER_TAG_BG_CLASS } from '../../constants';
-// TODO This should be implemented via a GraphQL API
-// The API should
-// 1) scope to the rights of the user
-// 2) stay up to date to the removal of old tags
-// 3) consider the scope of search, like searching within the tags of a group
-// See: https://gitlab.com/gitlab-org/gitlab/-/issues/333796
-export const TAG_SUGGESTIONS_PATH = '/admin/runners/tag_list.json';
-
export default {
components: {
BaseToken,
GlFilteredSearchSuggestion,
GlToken,
},
+ inject: ['tagSuggestionsPath'],
props: {
config: {
type: Object,
@@ -36,7 +29,7 @@ export default {
methods: {
getTagsOptions(search) {
return axios
- .get(TAG_SUGGESTIONS_PATH, {
+ .get(this.tagSuggestionsPath, {
params: {
search,
},