debian-mirror-gitlab/app/assets/javascripts/boards/components/sidebar/board_sidebar_title.vue

169 lines
4.7 KiB
Vue
Raw Normal View History

2021-03-08 18:12:59 +05:30
<script>
import { GlAlert, GlButton, GlForm, GlFormGroup, GlFormInput } from '@gitlab/ui';
2021-03-11 19:13:27 +05:30
import { mapGetters, mapActions } from 'vuex';
2021-03-08 18:12:59 +05:30
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
2021-03-11 19:13:27 +05:30
import { joinPaths } from '~/lib/utils/url_utility';
2021-03-08 18:12:59 +05:30
import { __ } from '~/locale';
2021-03-11 19:13:27 +05:30
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
2021-03-08 18:12:59 +05:30
export default {
components: {
GlForm,
GlAlert,
GlButton,
GlFormGroup,
GlFormInput,
BoardEditableItem,
},
directives: {
autofocusonshow,
},
data() {
return {
title: '',
loading: false,
showChangesAlert: false,
};
},
computed: {
2021-04-29 21:17:54 +05:30
...mapGetters({ item: 'activeBoardItem' }),
2021-03-08 18:12:59 +05:30
pendingChangesStorageKey() {
2021-04-29 21:17:54 +05:30
return this.getPendingChangesKey(this.item);
2021-03-08 18:12:59 +05:30
},
projectPath() {
2021-04-29 21:17:54 +05:30
const referencePath = this.item.referencePath || '';
2021-03-08 18:12:59 +05:30
return referencePath.slice(0, referencePath.indexOf('#'));
},
validationState() {
return Boolean(this.title);
},
},
watch: {
2021-04-29 21:17:54 +05:30
item: {
handler(updatedItem, formerItem) {
if (formerItem?.title !== this.title) {
localStorage.setItem(this.getPendingChangesKey(formerItem), this.title);
2021-03-08 18:12:59 +05:30
}
2021-04-29 21:17:54 +05:30
this.title = updatedItem.title;
2021-03-08 18:12:59 +05:30
this.setPendingState();
},
immediate: true,
},
},
methods: {
2021-09-04 01:27:46 +05:30
...mapActions(['setActiveItemTitle', 'setError']),
2021-04-29 21:17:54 +05:30
getPendingChangesKey(item) {
if (!item) {
2021-03-08 18:12:59 +05:30
return '';
}
return joinPaths(
window.location.pathname.slice(1),
2021-04-29 21:17:54 +05:30
String(item.id),
'item-title-pending-changes',
2021-03-08 18:12:59 +05:30
);
},
async setPendingState() {
const pendingChanges = localStorage.getItem(this.pendingChangesStorageKey);
if (pendingChanges) {
this.title = pendingChanges;
this.showChangesAlert = true;
await this.$nextTick();
this.$refs.sidebarItem.expand();
} else {
this.showChangesAlert = false;
}
},
cancel() {
2021-04-29 21:17:54 +05:30
this.title = this.item.title;
2021-03-08 18:12:59 +05:30
this.$refs.sidebarItem.collapse();
this.showChangesAlert = false;
localStorage.removeItem(this.pendingChangesStorageKey);
},
async setTitle() {
this.$refs.sidebarItem.collapse();
2021-04-29 21:17:54 +05:30
if (!this.title || this.title === this.item.title) {
2021-03-08 18:12:59 +05:30
return;
}
try {
this.loading = true;
2021-04-29 21:17:54 +05:30
await this.setActiveItemTitle({ title: this.title, projectPath: this.projectPath });
2021-03-08 18:12:59 +05:30
localStorage.removeItem(this.pendingChangesStorageKey);
this.showChangesAlert = false;
} catch (e) {
2021-04-29 21:17:54 +05:30
this.title = this.item.title;
2021-09-04 01:27:46 +05:30
this.setError({ error: e, message: this.$options.i18n.updateTitleError });
2021-03-08 18:12:59 +05:30
} finally {
this.loading = false;
}
},
handleOffClick() {
2021-04-29 21:17:54 +05:30
if (this.title !== this.item.title) {
2021-03-08 18:12:59 +05:30
this.showChangesAlert = true;
localStorage.setItem(this.pendingChangesStorageKey, this.title);
} else {
this.$refs.sidebarItem.collapse();
}
},
},
i18n: {
2021-04-29 21:17:54 +05:30
titlePlaceholder: __('Title'),
2021-03-08 18:12:59 +05:30
submitButton: __('Save changes'),
cancelButton: __('Cancel'),
2021-04-29 21:17:54 +05:30
updateTitleError: __('An error occurred when updating the title'),
invalidFeedback: __('A title is required'),
2021-03-08 18:12:59 +05:30
reviewYourChanges: __('Changes to the title have not been saved'),
},
};
</script>
<template>
<board-editable-item
ref="sidebarItem"
toggle-header
:loading="loading"
:handle-off-click="false"
@off-click="handleOffClick"
>
<template #title>
2021-04-29 21:17:54 +05:30
<span class="gl-font-weight-bold" data-testid="item-title">{{ item.title }}</span>
2021-03-08 18:12:59 +05:30
</template>
<template #collapsed>
2021-04-29 21:17:54 +05:30
<span class="gl-text-gray-800">{{ item.referencePath }}</span>
2021-03-08 18:12:59 +05:30
</template>
2021-03-11 19:13:27 +05:30
<gl-alert v-if="showChangesAlert" variant="warning" class="gl-mb-5" :dismissible="false">
{{ $options.i18n.reviewYourChanges }}
</gl-alert>
<gl-form @submit.prevent="setTitle">
<gl-form-group :invalid-feedback="$options.i18n.invalidFeedback" :state="validationState">
<gl-form-input
v-model="title"
v-autofocusonshow
2021-04-29 21:17:54 +05:30
:placeholder="$options.i18n.titlePlaceholder"
2021-03-11 19:13:27 +05:30
:state="validationState"
/>
</gl-form-group>
2021-03-08 18:12:59 +05:30
2021-03-11 19:13:27 +05:30
<div class="gl-display-flex gl-w-full gl-justify-content-space-between gl-mt-5">
<gl-button
2022-03-02 08:16:31 +05:30
variant="confirm"
2021-03-11 19:13:27 +05:30
size="small"
data-testid="submit-button"
:disabled="!title"
@click="setTitle"
>
{{ $options.i18n.submitButton }}
</gl-button>
2021-03-08 18:12:59 +05:30
2021-03-11 19:13:27 +05:30
<gl-button size="small" data-testid="cancel-button" @click="cancel">
{{ $options.i18n.cancelButton }}
</gl-button>
</div>
</gl-form>
2021-03-08 18:12:59 +05:30
</board-editable-item>
</template>