Merge branch 'issue-edit-inline' into issue-edit-inline-description-template
[ci skip]
This commit is contained in:
commit
21205d1e85
8 changed files with 99 additions and 4 deletions
|
@ -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 {
|
||||||
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 @@
|
||||||
},
|
},
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<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 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
lockedWarning,
|
||||||
titleField,
|
titleField,
|
||||||
descriptionField,
|
descriptionField,
|
||||||
descriptionTemplate,
|
descriptionTemplate,
|
||||||
|
@ -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"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<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 {
|
||||||
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 {
|
||||||
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', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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', () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
formState,
|
formState,
|
||||||
issuableTemplates: [{ name: 'test' }],
|
issuableTemplates: [{ name: 'test' }],
|
||||||
|
projectPath: '/',
|
||||||
|
projectNamespace: '/',
|
||||||
},
|
},
|
||||||
}).$mount();
|
}).$mount();
|
||||||
|
|
||||||
|
|
|
@ -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', () => {
|
||||||
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue