summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue')
-rw-r--r--app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue247
1 files changed, 247 insertions, 0 deletions
diff --git a/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
new file mode 100644
index 00000000000..e079603a5d4
--- /dev/null
+++ b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
@@ -0,0 +1,247 @@
+<script>
+import Vue from 'vue';
+import { uniqueId } from 'lodash';
+import {
+ GlAlert,
+ GlButton,
+ GlForm,
+ GlFormGroup,
+ GlFormInput,
+ GlFormSelect,
+ GlLink,
+ GlNewDropdown,
+ GlNewDropdownItem,
+ GlSearchBoxByType,
+ GlSprintf,
+} from '@gitlab/ui';
+import { s__, __ } from '~/locale';
+import Api from '~/api';
+import { redirectTo } from '~/lib/utils/url_utility';
+import { VARIABLE_TYPE, FILE_TYPE } from '../constants';
+
+export default {
+ typeOptions: [
+ { value: VARIABLE_TYPE, text: __('Variable') },
+ { value: FILE_TYPE, text: __('File') },
+ ],
+ variablesDescription: s__(
+ 'Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default.',
+ ),
+ formElementClasses: 'gl-mr-3 gl-mb-3 table-section section-15',
+ errorTitle: __('The form contains the following error:'),
+ components: {
+ GlAlert,
+ GlButton,
+ GlForm,
+ GlFormGroup,
+ GlFormInput,
+ GlFormSelect,
+ GlLink,
+ GlNewDropdown,
+ GlNewDropdownItem,
+ GlSearchBoxByType,
+ GlSprintf,
+ },
+ props: {
+ pipelinesPath: {
+ type: String,
+ required: true,
+ },
+ projectId: {
+ type: String,
+ required: true,
+ },
+ refs: {
+ type: Array,
+ required: true,
+ },
+ settingsLink: {
+ type: String,
+ required: true,
+ },
+ fileParams: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ refParam: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ variableParams: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ },
+ data() {
+ return {
+ searchTerm: '',
+ refValue: this.refParam,
+ variables: {},
+ error: false,
+ };
+ },
+ computed: {
+ filteredRefs() {
+ const lowerCasedSearchTerm = this.searchTerm.toLowerCase();
+ return this.refs.filter(ref => ref.toLowerCase().includes(lowerCasedSearchTerm));
+ },
+ variablesLength() {
+ return Object.keys(this.variables).length;
+ },
+ },
+ created() {
+ if (this.variableParams) {
+ this.setVariableParams(VARIABLE_TYPE, this.variableParams);
+ }
+
+ if (this.fileParams) {
+ this.setVariableParams(FILE_TYPE, this.fileParams);
+ }
+
+ this.addEmptyVariable();
+ },
+ methods: {
+ addEmptyVariable() {
+ this.variables[uniqueId('var')] = {
+ variable_type: VARIABLE_TYPE,
+ key: '',
+ value: '',
+ };
+ },
+ setVariableParams(type, paramsObj) {
+ Object.entries(paramsObj).forEach(([key, value]) => {
+ this.variables[uniqueId('var')] = {
+ key,
+ value,
+ variable_type: type,
+ };
+ });
+ },
+ setRefSelected(ref) {
+ this.refValue = ref;
+ },
+ isSelected(ref) {
+ return ref === this.refValue;
+ },
+ insertNewVariable() {
+ Vue.set(this.variables, uniqueId('var'), {
+ variable_type: VARIABLE_TYPE,
+ key: '',
+ value: '',
+ });
+ },
+ removeVariable(key) {
+ Vue.delete(this.variables, key);
+ },
+
+ canRemove(index) {
+ return index < this.variablesLength - 1;
+ },
+ createPipeline() {
+ const filteredVariables = Object.values(this.variables).filter(
+ ({ key, value }) => key !== '' && value !== '',
+ );
+
+ return Api.createPipeline(this.projectId, {
+ ref: this.refValue,
+ variables: filteredVariables,
+ })
+ .then(({ data }) => redirectTo(data.web_url))
+ .catch(err => {
+ this.error = err.response.data.message.base;
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-form @submit.prevent="createPipeline">
+ <gl-alert
+ v-if="error"
+ :title="$options.errorTitle"
+ :dismissible="false"
+ variant="danger"
+ class="gl-mb-4"
+ >{{ error }}</gl-alert
+ >
+ <gl-form-group :label="s__('Pipeline|Run for')">
+ <gl-new-dropdown :text="refValue" block>
+ <gl-search-box-by-type
+ v-model.trim="searchTerm"
+ :placeholder="__('Search branches and tags')"
+ class="gl-p-2"
+ />
+ <gl-new-dropdown-item
+ v-for="(ref, index) in filteredRefs"
+ :key="index"
+ class="gl-font-monospace"
+ is-check-item
+ :is-checked="isSelected(ref)"
+ @click="setRefSelected(ref)"
+ >
+ {{ ref }}
+ </gl-new-dropdown-item>
+ </gl-new-dropdown>
+
+ <template #description>
+ <div>
+ {{ s__('Pipeline|Existing branch name or tag') }}
+ </div></template
+ >
+ </gl-form-group>
+
+ <gl-form-group :label="s__('Pipeline|Variables')">
+ <div
+ v-for="(value, key, index) in variables"
+ :key="key"
+ class="gl-display-flex gl-align-items-center gl-mb-4 gl-pb-2 gl-border-b-solid gl-border-gray-200 gl-border-b-1 gl-flex-direction-column gl-md-flex-direction-row"
+ data-testid="ci-variable-row"
+ >
+ <gl-form-select
+ v-model="variables[key].variable_type"
+ :class="$options.formElementClasses"
+ :options="$options.typeOptions"
+ />
+ <gl-form-input
+ v-model="variables[key].key"
+ :placeholder="s__('CiVariables|Input variable key')"
+ :class="$options.formElementClasses"
+ data-testid="pipeline-form-ci-variable-key"
+ @change.once="insertNewVariable()"
+ />
+ <gl-form-input
+ v-model="variables[key].value"
+ :placeholder="s__('CiVariables|Input variable value')"
+ class="gl-mr-5 gl-mb-3 table-section section-15"
+ />
+ <gl-button
+ v-if="canRemove(index)"
+ icon="issue-close"
+ class="gl-mb-3"
+ data-testid="remove-ci-variable-row"
+ @click="removeVariable(key)"
+ />
+ </div>
+
+ <template #description
+ ><gl-sprintf :message="$options.variablesDescription">
+ <template #link="{ content }">
+ <gl-link :href="settingsLink">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf></template
+ >
+ </gl-form-group>
+ <div
+ class="gl-border-t-solid gl-border-gray-100 gl-border-t-1 gl-p-5 gl-bg-gray-10 gl-display-flex gl-justify-content-space-between"
+ >
+ <gl-button type="submit" category="primary" variant="success">{{
+ s__('Pipeline|Run Pipeline')
+ }}</gl-button>
+ <gl-button :href="pipelinesPath">{{ __('Cancel') }}</gl-button>
+ </div>
+ </gl-form>
+</template>