Commit ef82859d authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'ce-4681-autosave' into 'master'

Autosave description in epics

See merge request gitlab-org/gitlab-ce!27296
parents 224916f8 c23c141e
Pipeline #56998626 passed with stages
in 47 minutes and 18 seconds
......@@ -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"
......
<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"
......
---
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();
});
});
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);
});
});
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