gitlab-org--gitlab-foss/app/assets/javascripts/pipeline_wizard/components/commit.vue

224 lines
6 KiB
Vue

<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" :project-id="projectPath" data-testid="branch" />
</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('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>