IssueNotesRefactor: Implement close/reopen issue actions.

This commit is contained in:
Fatih Acet 2017-06-29 14:47:59 +03:00
parent d24e47a983
commit 17d67a989b
6 changed files with 52 additions and 30 deletions

View file

@ -28,43 +28,63 @@ export default {
commentButtonTitle() { commentButtonTitle() {
return this.noteType === 'comment' ? 'Comment' : 'Start discussion'; return this.noteType === 'comment' ? 'Comment' : 'Start discussion';
}, },
isIssueOpen() {
return this.issueState === 'opened' || this.issueState === 'reopened';
},
issueActionButtonTitle() { issueActionButtonTitle() {
if (this.note.length) { if (this.note.length) {
const actionText = this.issueState === 'open' ? 'close' : 'reopen'; const actionText = this.isIssueOpen ? 'close' : 'reopen';
return this.noteType === 'comment' ? `Comment & ${actionText} issue` : `Start discussion & ${actionText} issue`; return this.noteType === 'comment' ? `Comment & ${actionText} issue` : `Start discussion & ${actionText} issue`;
} }
return this.issueState === 'open' ? 'Close issue' : 'Reopen issue'; return this.isIssueOpen ? 'Close issue' : 'Reopen issue';
}, },
}, },
methods: { methods: {
handleSave() { handleSave(withIssueAction) {
const data = { if (this.note.length) {
endpoint: this.endpoint, const data = {
noteData: { endpoint: this.endpoint,
full_data: true, noteData: {
note: { full_data: true,
noteable_type: 'Issue', note: {
noteable_id: window.gl.issueData.id, noteable_type: 'Issue',
note: this.note, noteable_id: window.gl.issueData.id,
} note: this.note,
}, },
}; },
};
if (this.noteType === 'discussion') { if (this.noteType === 'discussion') {
data.noteData.note.type = 'DiscussionNote'; data.noteData.note.type = 'DiscussionNote';
}
this.$store.dispatch('createNewNote', data)
.then((res) => {
if (res.errors) {
this.handleError();
} else {
this.discard();
}
})
.catch(this.handleError);
} }
this.$store.dispatch('createNewNote', data) if (withIssueAction) {
.then((res) => { if (this.isIssueOpen) {
if (res.errors) { gl.issueData.state = 'closed';
return this.handleError(); this.issueState = 'closed';
} } else {
gl.issueData.state = 'reopened';
this.issueState = 'reopened';
}
this.isIssueOpen = !this.isIssueOpen;
this.discard(); // This is out of scope for the Notes Vue component.
}) // It was the shortest path to update the issue state and relevant places.
.catch(this.handleError); $('.js-btn-issue-action:visible').trigger('click');
}
}, },
discard() { discard() {
this.note = ''; this.note = '';
@ -171,6 +191,7 @@ export default {
</ul> </ul>
</div> </div>
<a <a
@click="handleSave(true)"
:class="{'btn-reopen': issueState === 'closed', 'btn-close': issueState === 'open'}" :class="{'btn-reopen': issueState === 'closed', 'btn-close': issueState === 'open'}"
class="btn btn-nr btn-comment"> class="btn btn-nr btn-comment">
{{issueActionButtonTitle}} {{issueActionButtonTitle}}

View file

@ -59,8 +59,9 @@ export default {
}, },
formUpdateHandler(note) { formUpdateHandler(note) {
const data = { const data = {
endpoint: `${this.note.path}?full_data=1`, endpoint: this.note.path,
note: { note: {
full_data: true,
target_type: 'issue', target_type: 'issue',
target_id: this.note.noteable_id, target_id: this.note.noteable_id,
note, note,

View file

@ -1,8 +1,8 @@
<script> <script>
import * as Emoji from '../../emoji';
import emojiSmiling from 'icons/_emoji_slightly_smiling_face.svg'; import emojiSmiling from 'icons/_emoji_slightly_smiling_face.svg';
import emojiSmile from 'icons/_emoji_smile.svg'; import emojiSmile from 'icons/_emoji_smile.svg';
import emojiSmiley from 'icons/_emoji_smiley.svg'; import emojiSmiley from 'icons/_emoji_smiley.svg';
import * as Emoji from '../../emoji';
export default { export default {
props: { props: {

View file

@ -18,5 +18,5 @@ export default {
}, },
createNewNote(endpoint, data) { createNewNote(endpoint, data) {
return Vue.http.post(endpoint, data, { emulateJSON: true }); return Vue.http.post(endpoint, data, { emulateJSON: true });
} },
}; };

View file

@ -58,7 +58,7 @@ const mutations = {
expanded: true, expanded: true,
id: discussion_id, id: discussion_id,
individual_note: !(type === 'DiscussionNote'), individual_note: !(type === 'DiscussionNote'),
notes: [ note ], notes: [note],
reply_id: discussion_id, reply_id: discussion_id,
}; };

View file

@ -34,8 +34,8 @@
- unless current_user == @issue.author - unless current_user == @issue.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue)) %li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
- if can_update_issue - if can_update_issue
%li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' %li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue'
%li= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' %li= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen js-btn-issue-action #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
- if can_report_spam - if can_report_spam
%li= link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam' %li= link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam'
- if can_update_issue || can_report_spam - if can_update_issue || can_report_spam