Commit 21205d1e authored by Phil Hughes's avatar Phil Hughes

Merge branch 'issue-edit-inline' into issue-edit-inline-description-template

[ci skip]
parents 745ec1ac 3f996024
...@@ -103,12 +103,12 @@ export default { ...@@ -103,12 +103,12 @@ export default {
openForm() { openForm() {
if (!this.showForm) { if (!this.showForm) {
this.showForm = true; this.showForm = true;
this.store.formState = { this.store.formState = Object.assign(this.store.formState, {
title: this.state.titleText, title: this.state.titleText,
confidential: this.isConfidential, confidential: this.isConfidential,
description: this.state.descriptionText, description: this.state.descriptionText,
move_to_project_id: 0, move_to_project_id: 0,
}; });
} }
}, },
closeForm() { closeForm() {
...@@ -152,7 +152,14 @@ export default { ...@@ -152,7 +152,14 @@ export default {
resource: this.service, resource: this.service,
method: 'getData', method: 'getData',
successCallback: (res) => { successCallback: (res) => {
this.store.updateState(res.json()); const data = res.json();
const shouldUpdate = this.store.stateShouldUpdate(data);
this.store.updateState(data);
if (this.showForm && (shouldUpdate.title || shouldUpdate.description)) {
this.store.formState.lockedWarningVisible = true;
}
}, },
errorCallback(err) { errorCallback(err) {
throw new Error(err); throw new Error(err);
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
}, },
mounted() { mounted() {
// Create the editor for the template // Create the editor for the template
const editor = document.querySelector('.detail-page-description .note-textarea'); const editor = document.querySelector('.detail-page-description .note-textarea') || {};
editor.setValue = (val) => { editor.setValue = (val) => {
this.formState.description = val; this.formState.description = val;
}; };
......
<script> <script>
import lockedWarning from './locked_warning.vue';
import titleField from './fields/title.vue'; import titleField from './fields/title.vue';
import descriptionField from './fields/description.vue'; import descriptionField from './fields/description.vue';
import editActions from './edit_actions.vue'; import editActions from './edit_actions.vue';
...@@ -47,6 +48,7 @@ ...@@ -47,6 +48,7 @@
}, },
}, },
components: { components: {
lockedWarning,
titleField, titleField,
descriptionField, descriptionField,
descriptionTemplate, descriptionTemplate,
...@@ -64,6 +66,7 @@ ...@@ -64,6 +66,7 @@
<template> <template>
<form> <form>
<locked-warning v-if="formState.lockedWarningVisible" />
<div class="row"> <div class="row">
<div <div
class="col-sm-4 col-lg-3" class="col-sm-4 col-lg-3"
......
<script>
export default {
computed: {
currentPath() {
return location.pathname;
},
},
};
</script>
<template>
<div class="alert alert-danger">
Someone edited the issue at the same time you did. Please check out
<a
:href="currentPath"
target="_blank"
rel="nofollow">the issue</a>
and make sure your changes will not unintentionally remove theirs.
</div>
</template>
...@@ -16,6 +16,7 @@ export default class Store { ...@@ -16,6 +16,7 @@ export default class Store {
title: '', title: '',
confidential: false, confidential: false,
description: '', description: '',
lockedWarningVisible: false,
move_to_project_id: 0, move_to_project_id: 0,
}; };
} }
...@@ -28,4 +29,11 @@ export default class Store { ...@@ -28,4 +29,11 @@ export default class Store {
this.state.taskStatus = data.task_status; this.state.taskStatus = data.task_status;
this.state.updatedAt = data.updated_at; this.state.updatedAt = data.updated_at;
} }
stateShouldUpdate(data) {
return {
title: this.state.titleText !== data.title_text,
description: this.state.descriptionText !== data.description_text,
};
}
} }
...@@ -285,4 +285,36 @@ describe('Issuable output', () => { ...@@ -285,4 +285,36 @@ describe('Issuable output', () => {
}); });
}); });
}); });
describe('open form', () => {
it('shows locked warning if form is open & data is different', (done) => {
Vue.http.interceptors.push(issueShowInterceptor(issueShowData.initialRequest));
Vue.nextTick()
.then(() => new Promise((resolve) => {
setTimeout(resolve);
}))
.then(() => {
vm.openForm();
Vue.http.interceptors.push(issueShowInterceptor(issueShowData.secondRequest));
return new Promise((resolve) => {
setTimeout(resolve);
});
})
.then(() => {
expect(
vm.formState.lockedWarningVisible,
).toBeTruthy();
expect(
vm.$el.querySelector('.alert'),
).not.toBeNull();
done();
})
.catch(done.fail);
});
});
}); });
...@@ -17,6 +17,8 @@ describe('Issue description template component', () => { ...@@ -17,6 +17,8 @@ describe('Issue description template component', () => {
propsData: { propsData: {
formState, formState,
issuableTemplates: [{ name: 'test' }], issuableTemplates: [{ name: 'test' }],
projectPath: '/',
projectNamespace: '/',
}, },
}).$mount(); }).$mount();
......
...@@ -12,12 +12,17 @@ describe('Inline edit form component', () => { ...@@ -12,12 +12,17 @@ describe('Inline edit form component', () => {
vm = new Component({ vm = new Component({
propsData: { propsData: {
canDestroy: true, canDestroy: true,
canMove: true,
formState: { formState: {
title: 'b', title: 'b',
description: 'a', description: 'a',
lockedWarningVisible: false,
}, },
markdownPreviewUrl: '/', markdownPreviewUrl: '/',
markdownDocs: '/', markdownDocs: '/',
projectsAutocompleteUrl: '/',
projectPath: '/',
projectNamespace: '/',
}, },
}).$mount(); }).$mount();
...@@ -42,4 +47,22 @@ describe('Inline edit form component', () => { ...@@ -42,4 +47,22 @@ describe('Inline edit form component', () => {
done(); done();
}); });
}); });
it('hides locked warning by default', () => {
expect(
vm.$el.querySelector('.alert'),
).toBeNull();
});
it('shows locked warning if formState is different', (done) => {
vm.formState.lockedWarningVisible = true;
Vue.nextTick(() => {
expect(
vm.$el.querySelector('.alert'),
).not.toBeNull();
done();
});
});
}); });
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