Merge branch 'ce-4681-autosave' into 'master'
Autosave description in epics See merge request gitlab-org/gitlab-ce!27296
This commit is contained in:
commit
ef82859d7d
9 changed files with 150 additions and 4 deletions
|
@ -159,9 +159,23 @@ export default {
|
|||
return !!this.state.updatedAt;
|
||||
},
|
||||
issueChanged() {
|
||||
const descriptionChanged = this.initialDescriptionText !== this.store.formState.description;
|
||||
const titleChanged = this.initialTitleText !== this.store.formState.title;
|
||||
return descriptionChanged || titleChanged;
|
||||
const {
|
||||
store: {
|
||||
formState: { description, title },
|
||||
},
|
||||
initialDescriptionText,
|
||||
initialTitleText,
|
||||
} = this;
|
||||
|
||||
if (initialDescriptionText || description) {
|
||||
return initialDescriptionText !== description;
|
||||
}
|
||||
|
||||
if (initialTitleText || title) {
|
||||
return initialTitleText !== title;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
defaultErrorMessage() {
|
||||
return sprintf(s__('Error updating %{issuableType}'), { issuableType: this.issuableType });
|
||||
|
|
|
@ -145,6 +145,7 @@ export default {
|
|||
></div>
|
||||
<textarea
|
||||
v-if="descriptionText"
|
||||
ref="textarea"
|
||||
v-model="descriptionText"
|
||||
:data-update-url="updateUrl"
|
||||
class="hidden js-task-list-field"
|
||||
|
|
|
@ -17,6 +17,7 @@ export default {
|
|||
<label class="sr-only" for="issuable-title"> Title </label>
|
||||
<input
|
||||
id="issuable-title"
|
||||
ref="input"
|
||||
v-model="formState.title"
|
||||
class="form-control qa-title-input"
|
||||
type="text"
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<script>
|
||||
import $ from 'jquery';
|
||||
import lockedWarning from './locked_warning.vue';
|
||||
import titleField from './fields/title.vue';
|
||||
import descriptionField from './fields/description.vue';
|
||||
import editActions from './edit_actions.vue';
|
||||
import descriptionTemplate from './fields/description_template.vue';
|
||||
import Autosave from '~/autosave';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -68,6 +71,47 @@ export default {
|
|||
return this.issuableTemplates.length;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
eventHub.$on('delete.issuable', this.resetAutosave);
|
||||
eventHub.$on('update.issuable', this.resetAutosave);
|
||||
eventHub.$on('close.form', this.resetAutosave);
|
||||
},
|
||||
mounted() {
|
||||
this.initAutosave();
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('delete.issuable', this.resetAutosave);
|
||||
eventHub.$off('update.issuable', this.resetAutosave);
|
||||
eventHub.$off('close.form', this.resetAutosave);
|
||||
},
|
||||
methods: {
|
||||
initAutosave() {
|
||||
const {
|
||||
description: {
|
||||
$refs: { textarea },
|
||||
},
|
||||
title: {
|
||||
$refs: { input },
|
||||
},
|
||||
} = this.$refs;
|
||||
|
||||
this.autosaveDescription = new Autosave($(textarea), [
|
||||
document.location.pathname,
|
||||
document.location.search,
|
||||
'description',
|
||||
]);
|
||||
|
||||
this.autosaveTitle = new Autosave($(input), [
|
||||
document.location.pathname,
|
||||
document.location.search,
|
||||
'title',
|
||||
]);
|
||||
},
|
||||
resetAutosave() {
|
||||
this.autosaveDescription.reset();
|
||||
this.autosaveTitle.reset();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -89,10 +133,11 @@ export default {
|
|||
'col-12': !hasIssuableTemplates,
|
||||
}"
|
||||
>
|
||||
<title-field :form-state="formState" :issuable-templates="issuableTemplates" />
|
||||
<title-field ref="title" :form-state="formState" :issuable-templates="issuableTemplates" />
|
||||
</div>
|
||||
</div>
|
||||
<description-field
|
||||
ref="description"
|
||||
:form-state="formState"
|
||||
:markdown-preview-path="markdownPreviewPath"
|
||||
:markdown-docs-path="markdownDocsPath"
|
||||
|
|
5
changelogs/unreleased/ce-4681-autosave.yml
Normal file
5
changelogs/unreleased/ce-4681-autosave.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Autosave description in epics
|
||||
merge_request: 27296
|
||||
author:
|
||||
type: added
|
|
@ -470,4 +470,51 @@ describe('Issuable output', () => {
|
|||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('issueChanged', () => {
|
||||
beforeEach(() => {
|
||||
vm.store.formState.title = '';
|
||||
vm.store.formState.description = '';
|
||||
vm.initialDescriptionText = '';
|
||||
vm.initialTitleText = '';
|
||||
});
|
||||
|
||||
it('returns true when title is changed', () => {
|
||||
vm.store.formState.title = 'RandomText';
|
||||
|
||||
expect(vm.issueChanged).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when title is empty null', () => {
|
||||
vm.store.formState.title = null;
|
||||
|
||||
expect(vm.issueChanged).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false when `initialTitleText` is null and `formState.title` is empty string', () => {
|
||||
vm.store.formState.title = '';
|
||||
vm.initialTitleText = null;
|
||||
|
||||
expect(vm.issueChanged).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true when description is changed', () => {
|
||||
vm.store.formState.description = 'RandomText';
|
||||
|
||||
expect(vm.issueChanged).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when description is empty null', () => {
|
||||
vm.store.formState.title = null;
|
||||
|
||||
expect(vm.issueChanged).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false when `initialDescriptionText` is null and `formState.description` is empty string', () => {
|
||||
vm.store.formState.description = '';
|
||||
vm.initialDescriptionText = null;
|
||||
|
||||
expect(vm.issueChanged).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -63,4 +63,8 @@ describe('Description field component', () => {
|
|||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('has a ref named `textarea`', () => {
|
||||
expect(vm.$refs.textarea).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -41,4 +41,8 @@ describe('Title field component', () => {
|
|||
|
||||
expect(eventHub.$emit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('has a ref named `input`', () => {
|
||||
expect(vm.$refs.input).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
import Vue from 'vue';
|
||||
import formComponent from '~/issue_show/components/form.vue';
|
||||
import eventHub from '~/issue_show/event_hub';
|
||||
|
||||
describe('Inline edit form component', () => {
|
||||
let vm;
|
||||
let autosave;
|
||||
let autosaveObj;
|
||||
|
||||
beforeEach(done => {
|
||||
autosaveObj = { reset: jasmine.createSpy() };
|
||||
|
||||
autosave = spyOnDependency(formComponent, 'Autosave').and.returnValue(autosaveObj);
|
||||
|
||||
const Component = Vue.extend(formComponent);
|
||||
|
||||
vm = new Component({
|
||||
|
@ -53,4 +60,22 @@ describe('Inline edit form component', () => {
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('initialized Autosave on mount', () => {
|
||||
expect(autosave).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('calls reset on autosave when eventHub emits appropriate events', () => {
|
||||
eventHub.$emit('close.form');
|
||||
|
||||
expect(autosaveObj.reset).toHaveBeenCalledTimes(2);
|
||||
|
||||
eventHub.$emit('delete.issuable');
|
||||
|
||||
expect(autosaveObj.reset).toHaveBeenCalledTimes(4);
|
||||
|
||||
eventHub.$emit('update.issuable');
|
||||
|
||||
expect(autosaveObj.reset).toHaveBeenCalledTimes(6);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue