Commit 9fc81d96 authored by Janis Altherr's avatar Janis Altherr Committed by David O'Regan

Add the commit step component to be used by the Pipeline Wizard

This commit introduces the commit step page, which
is always the last step in the pipeline wizard. It will
allow commiting the updated .gitlab-ci.yml
file to a project
Signed-off-by: default avatarJanis Altherr <jaltherr@gitlab.com>
parent f9a90786
<script>
import { GlAlert, GlButton, GlForm, GlFormGroup, GlFormTextarea } from '@gitlab/ui';
import RefSelector from '~/ref/components/ref_selector.vue';
import { __, s__, sprintf } from '~/locale';
import createCommitMutation from '../queries/create_commit.graphql';
import getFileMetaDataQuery from '../queries/get_file_meta.graphql';
import StepNav from './step_nav.vue';
export const i18n = {
updateFileHeading: s__('PipelineWizard|Commit changes to your file'),
createFileHeading: s__('PipelineWizard|Commit your new file'),
fieldRequiredFeedback: __('This field is required'),
commitMessageLabel: s__('PipelineWizard|Commit Message'),
branchSelectorLabel: s__('PipelineWizard|Commit file to Branch'),
defaultUpdateCommitMessage: s__('PipelineWizardDefaultCommitMessage|Update %{filename}'),
defaultCreateCommitMessage: s__('PipelineWizardDefaultCommitMessage|Add %{filename}'),
commitButtonLabel: s__('PipelineWizard|Commit'),
commitSuccessMessage: s__('PipelineWizard|The file has been committed.'),
errors: {
loadError: s__(
'PipelineWizard|There was a problem while checking whether your file already exists in the specified branch.',
),
commitError: s__('PipelineWizard|There was a problem committing the changes.'),
},
};
const COMMIT_ACTION = {
CREATE: 'CREATE',
UPDATE: 'UPDATE',
};
export default {
i18n,
name: 'PipelineWizardCommitStep',
components: {
RefSelector,
GlAlert,
GlButton,
GlForm,
GlFormGroup,
GlFormTextarea,
StepNav,
},
props: {
prev: {
type: Object,
required: false,
default: null,
},
projectPath: {
type: String,
required: true,
},
defaultBranch: {
type: String,
required: true,
},
fileContent: {
type: String,
required: false,
default: '',
},
filename: {
type: String,
required: true,
},
},
data() {
return {
branch: this.defaultBranch,
loading: false,
loadError: null,
commitError: null,
message: null,
};
},
computed: {
fileExistsInRepo() {
return this.project?.repository?.blobs.nodes.length > 0;
},
commitAction() {
return this.fileExistsInRepo ? COMMIT_ACTION.UPDATE : COMMIT_ACTION.CREATE;
},
defaultMessage() {
return sprintf(
this.fileExistsInRepo
? this.$options.i18n.defaultUpdateCommitMessage
: this.$options.i18n.defaultCreateCommitMessage,
{ filename: this.filename },
);
},
isCommitButtonEnabled() {
return this.fileExistsCheckInProgress;
},
fileExistsCheckInProgress() {
return this.$apollo.queries.project.loading;
},
mutationPayload() {
return {
mutation: createCommitMutation,
variables: {
input: {
projectPath: this.projectPath,
branch: this.branch,
message: this.message || this.defaultMessage,
actions: [
{
action: this.commitAction,
filePath: `/${this.filename}`,
content: this.fileContent,
},
],
},
},
};
},
},
apollo: {
project: {
query: getFileMetaDataQuery,
variables() {
this.loadError = null;
return {
fullPath: this.projectPath,
filePath: this.filename,
ref: this.branch,
};
},
error() {
this.loadError = this.$options.i18n.errors.loadError;
},
},
},
methods: {
async commit() {
this.loading = true;
try {
const { data } = await this.$apollo.mutate(this.mutationPayload);
const hasError = Boolean(data.commitCreate.errors?.length);
if (hasError) {
this.commitError = this.$options.i18n.errors.commitError;
} else {
this.handleCommitSuccess();
}
} catch (e) {
this.commitError = this.$options.i18n.errors.commitError;
} finally {
this.loading = false;
}
},
handleCommitSuccess() {
this.$toast.show(this.$options.i18n.commitSuccessMessage);
this.$emit('done');
},
},
};
</script>
<template>
<div>
<h4 v-if="fileExistsInRepo" key="create-heading">
{{ $options.i18n.updateFileHeading }}
</h4>
<h4 v-else key="update-heading">
{{ $options.i18n.createFileHeading }}
</h4>
<gl-alert
v-if="!!loadError"
:dismissible="false"
class="gl-mb-5"
data-testid="load-error"
variant="danger"
>
{{ loadError }}
</gl-alert>
<gl-form class="gl-max-w-48">
<gl-form-group
:invalid-feedback="$options.i18n.fieldRequiredFeedback"
:label="$options.i18n.commitMessageLabel"
data-testid="commit_message_group"
label-for="commit_message"
>
<gl-form-textarea
id="commit_message"
v-model="message"
:placeholder="defaultMessage"
data-testid="commit_message"
size="md"
@input="(v) => $emit('update:message', v)"
/>
</gl-form-group>
<gl-form-group
:invalid-feedback="$options.i18n.fieldRequiredFeedback"
:label="$options.i18n.branchSelectorLabel"
data-testid="branch_selector_group"
label-for="branch"
>
<ref-selector id="branch" v-model="branch" data-testid="branch" :project-id="projectPath" />
</gl-form-group>
<gl-alert
v-if="!!commitError"
:dismissible="false"
class="gl-mb-5"
data-testid="commit-error"
variant="danger"
>
{{ commitError }}
</gl-alert>
<step-nav show-back-button v-bind="$props" @back="$emit('go-back')">
<template #after>
<gl-button
:disabled="isCommitButtonEnabled"
:loading="fileExistsCheckInProgress || loading"
category="primary"
variant="confirm"
@click="commit"
>
{{ $options.i18n.commitButtonLabel }}
</gl-button>
</template>
</step-nav>
</gl-form>
</div>
</template>
mutation CreateCommit($input: CommitCreateInput!) {
commitCreate(input: $input) {
commit {
id
}
content
errors
}
}
query GetFileMetadata($fullPath: ID!, $filePath: String!, $ref: String) {
project(fullPath: $fullPath) {
id
repository {
blobs(paths: [$filePath], ref: $ref) {
nodes {
id
}
}
}
}
}
...@@ -26643,12 +26643,42 @@ msgstr "" ...@@ -26643,12 +26643,42 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}" msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "" msgstr ""
msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
msgstr ""
msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
msgstr ""
msgid "PipelineWizardInputValidation|This field is required" msgid "PipelineWizardInputValidation|This field is required"
msgstr "" msgstr ""
msgid "PipelineWizardInputValidation|This value is not valid" msgid "PipelineWizardInputValidation|This value is not valid"
msgstr "" msgstr ""
msgid "PipelineWizard|Commit"
msgstr ""
msgid "PipelineWizard|Commit Message"
msgstr ""
msgid "PipelineWizard|Commit changes to your file"
msgstr ""
msgid "PipelineWizard|Commit file to Branch"
msgstr ""
msgid "PipelineWizard|Commit your new file"
msgstr ""
msgid "PipelineWizard|The file has been committed."
msgstr ""
msgid "PipelineWizard|There was a problem committing the changes."
msgstr ""
msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
msgstr ""
msgid "Pipelines" msgid "Pipelines"
msgstr "" msgstr ""
......
This diff is collapsed.
export const createCommitMutationResult = {
data: {
commitCreate: {
commit: {
id: '82a9df1',
},
content: 'foo: bar',
errors: null,
},
},
};
export const createCommitMutationErrorResult = {
data: {
commitCreate: {
commit: null,
content: null,
errors: ['Some Error Message'],
},
},
};
export const fileQueryResult = {
data: {
project: {
id: 'gid://gitlab/Project/1',
repository: {
blobs: {
nodes: [
{
id: 'gid://gitlab/Blob/9ff96777b315cd37188f7194d8382c718cb2933c',
},
],
},
},
},
},
};
export const fileQueryEmptyResult = {
data: {
project: {
id: 'gid://gitlab/Project/2',
repository: {
blobs: {
nodes: [],
},
},
},
},
};
export const fileQueryErrorResult = {
data: {
foo: 'bar',
project: {
id: null,
repository: null,
},
},
errors: [{ message: 'GraphQL Error' }],
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment