summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue')
-rw-r--r--app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue192
1 files changed, 192 insertions, 0 deletions
diff --git a/app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue b/app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue
new file mode 100644
index 00000000000..1898e02c94e
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/job/legacy_manual_variables_form.vue
@@ -0,0 +1,192 @@
+<script>
+import {
+ GlFormInputGroup,
+ GlInputGroupText,
+ GlFormInput,
+ GlButton,
+ GlLink,
+ GlSprintf,
+} from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+import { mapActions } from 'vuex';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { s__ } from '~/locale';
+
+export default {
+ name: 'ManualVariablesForm',
+ components: {
+ GlFormInputGroup,
+ GlInputGroupText,
+ GlFormInput,
+ GlButton,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ action: {
+ type: Object,
+ required: false,
+ default: null,
+ validator(value) {
+ return (
+ value === null ||
+ (Object.prototype.hasOwnProperty.call(value, 'path') &&
+ Object.prototype.hasOwnProperty.call(value, 'method') &&
+ Object.prototype.hasOwnProperty.call(value, 'button_title'))
+ );
+ },
+ },
+ },
+ inputTypes: {
+ key: 'key',
+ value: 'value',
+ },
+ i18n: {
+ header: s__('CiVariables|Variables'),
+ keyLabel: s__('CiVariables|Key'),
+ valueLabel: s__('CiVariables|Value'),
+ keyPlaceholder: s__('CiVariables|Input variable key'),
+ valuePlaceholder: s__('CiVariables|Input variable value'),
+ formHelpText: s__(
+ 'CiVariables|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used as default',
+ ),
+ },
+ data() {
+ return {
+ variables: [
+ {
+ key: '',
+ secretValue: '',
+ id: uniqueId(),
+ },
+ ],
+ triggerBtnDisabled: false,
+ };
+ },
+ computed: {
+ variableSettings() {
+ return helpPagePath('ci/variables/index', { anchor: 'add-a-cicd-variable-to-a-project' });
+ },
+ preparedVariables() {
+ // we need to ensure no empty variables are passed to the API
+ // and secretValue should be snake_case when passed to the API
+ return this.variables
+ .filter((variable) => variable.key !== '')
+ .map(({ key, secretValue }) => ({ key, secret_value: secretValue }));
+ },
+ },
+ methods: {
+ ...mapActions(['triggerManualJob']),
+ addEmptyVariable() {
+ const lastVar = this.variables[this.variables.length - 1];
+
+ if (lastVar.key === '') {
+ return;
+ }
+
+ this.variables.push({
+ key: '',
+ secret_value: '',
+ id: uniqueId(),
+ });
+ },
+ canRemove(index) {
+ return index < this.variables.length - 1;
+ },
+ deleteVariable(id) {
+ this.variables.splice(
+ this.variables.findIndex((el) => el.id === id),
+ 1,
+ );
+ },
+ inputRef(type, id) {
+ return `${this.$options.inputTypes[type]}-${id}`;
+ },
+ trigger() {
+ this.triggerBtnDisabled = true;
+
+ this.triggerManualJob(this.preparedVariables);
+ },
+ },
+};
+</script>
+<template>
+ <div class="row gl-justify-content-center">
+ <div class="col-10" data-testid="manual-vars-form">
+ <label>{{ $options.i18n.header }}</label>
+
+ <div
+ v-for="(variable, index) in variables"
+ :key="variable.id"
+ class="gl-display-flex gl-align-items-center gl-mb-4"
+ data-testid="ci-variable-row"
+ >
+ <gl-form-input-group class="gl-mr-4 gl-flex-grow-1">
+ <template #prepend>
+ <gl-input-group-text>
+ {{ $options.i18n.keyLabel }}
+ </gl-input-group-text>
+ </template>
+ <gl-form-input
+ :ref="inputRef('key', variable.id)"
+ v-model="variable.key"
+ :placeholder="$options.i18n.keyPlaceholder"
+ data-testid="ci-variable-key"
+ @change="addEmptyVariable"
+ />
+ </gl-form-input-group>
+
+ <gl-form-input-group class="gl-flex-grow-2">
+ <template #prepend>
+ <gl-input-group-text>
+ {{ $options.i18n.valueLabel }}
+ </gl-input-group-text>
+ </template>
+ <gl-form-input
+ :ref="inputRef('value', variable.id)"
+ v-model="variable.secretValue"
+ :placeholder="$options.i18n.valuePlaceholder"
+ data-testid="ci-variable-value"
+ />
+ </gl-form-input-group>
+
+ <gl-button
+ v-if="canRemove(index)"
+ class="gl-flex-grow-0 gl-flex-basis-0"
+ category="tertiary"
+ variant="danger"
+ icon="clear"
+ :aria-label="__('Delete variable')"
+ data-testid="delete-variable-btn"
+ @click="deleteVariable(variable.id)"
+ />
+
+ <!-- delete variable button placeholder to not break flex layout -->
+ <div v-else class="gl-w-7 gl-mr-3" data-testid="delete-variable-btn-placeholder"></div>
+ </div>
+
+ <div class="gl-text-center gl-mt-5">
+ <gl-sprintf :message="$options.i18n.formHelpText">
+ <template #link="{ content }">
+ <gl-link :href="variableSettings" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ <div class="gl-display-flex gl-justify-content-center gl-mt-5">
+ <gl-button
+ class="gl-mt-5"
+ variant="confirm"
+ category="primary"
+ :aria-label="__('Trigger manual job')"
+ :disabled="triggerBtnDisabled"
+ data-testid="trigger-manual-job-btn"
+ @click="trigger"
+ >
+ {{ action.button_title }}
+ </gl-button>
+ </div>
+ </div>
+ </div>
+</template>