IssueDiscussionsRefactor: Implement polling mechanism.
This commit is contained in:
parent
17d67a989b
commit
15f3362d34
5 changed files with 71 additions and 8 deletions
|
@ -133,13 +133,13 @@ export default {
|
|||
ref="textarea"
|
||||
slot="textarea"
|
||||
placeholder="Write a comment or drag your files here..."
|
||||
@keydown.meta.enter="handleSave">
|
||||
@keydown.meta.enter="handleSave()">
|
||||
</textarea>
|
||||
</markdown-field>
|
||||
<div class="note-form-actions clearfix">
|
||||
<div class="pull-left btn-group append-right-10 comment-type-dropdown js-comment-type-dropdown">
|
||||
<input
|
||||
@click="handleSave"
|
||||
@click="handleSave()"
|
||||
:disabled="!note.length"
|
||||
:value="commentButtonTitle"
|
||||
class="btn btn-nr btn-create comment-btn js-comment-button js-comment-submit-button"
|
||||
|
|
|
@ -39,14 +39,27 @@ export default {
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
const path = this.$el.parentNode.dataset.discussionsPath;
|
||||
this.$store.dispatch('fetchNotes', path)
|
||||
const { discussionsPath, notesPath, lastFetchedAt } = this.$el.parentNode.dataset;
|
||||
this.$store.dispatch('fetchNotes', discussionsPath)
|
||||
.then(() => {
|
||||
this.isLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
new Flash('Something went wrong while fetching issue comments. Please try again.'); // eslint-disable-line
|
||||
});
|
||||
|
||||
const options = {
|
||||
endpoint: `${notesPath}?full_data=1`,
|
||||
lastFetchedAt,
|
||||
};
|
||||
|
||||
// FIXME: @fatihacet Implement real polling mechanism
|
||||
setInterval(() => {
|
||||
this.$store.dispatch('poll', options)
|
||||
.then((res) => {
|
||||
options.lastFetchedAt = res.last_fetched_at;
|
||||
});
|
||||
}, 6000);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -19,4 +19,13 @@ export default {
|
|||
createNewNote(endpoint, data) {
|
||||
return Vue.http.post(endpoint, data, { emulateJSON: true });
|
||||
},
|
||||
poll(endpoint, lastFetchedAt) {
|
||||
const options = {
|
||||
headers: {
|
||||
'X-Last-Fetched-At': lastFetchedAt,
|
||||
}
|
||||
};
|
||||
|
||||
return Vue.http.get(endpoint, options);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ const getters = {
|
|||
};
|
||||
|
||||
const mutations = {
|
||||
setNotes(storeState, notes) {
|
||||
setInitialNotes(storeState, notes) {
|
||||
storeState.notes = notes;
|
||||
},
|
||||
toggleDiscussion(storeState, { discussionId }) {
|
||||
|
@ -40,7 +40,9 @@ const mutations = {
|
|||
addNewReplyToDiscussion(storeState, note) {
|
||||
const noteObj = findNoteObjectById(storeState.notes, note.discussion_id);
|
||||
|
||||
noteObj.notes.push(note);
|
||||
if (noteObj) {
|
||||
noteObj.notes.push(note);
|
||||
}
|
||||
},
|
||||
updateNote(storeState, note) {
|
||||
const noteObj = findNoteObjectById(storeState.notes, note.discussion_id);
|
||||
|
@ -72,7 +74,7 @@ const actions = {
|
|||
.fetchNotes(path)
|
||||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
context.commit('setNotes', res);
|
||||
context.commit('setInitialNotes', res);
|
||||
});
|
||||
},
|
||||
deleteNote(context, note) {
|
||||
|
@ -114,6 +116,45 @@ const actions = {
|
|||
return res;
|
||||
});
|
||||
},
|
||||
poll(context, data) {
|
||||
const { endpoint, lastFetchedAt } = data;
|
||||
|
||||
return service
|
||||
.poll(endpoint, lastFetchedAt)
|
||||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
if (res.notes.length) {
|
||||
const notesById = {};
|
||||
|
||||
// Simple lookup object to check whether we have a discussion id already in our store
|
||||
context.state.notes.forEach((note) => {
|
||||
note.notes.forEach((n) => {
|
||||
notesById[n.id] = true;
|
||||
});
|
||||
});
|
||||
|
||||
res.notes.forEach((note) => {
|
||||
if (notesById[note.id]) {
|
||||
context.commit('updateNote', note);
|
||||
} else {
|
||||
if (note.type === 'DiscussionNote') {
|
||||
const discussion = findNoteObjectById(context.state.notes, note.discussion_id);
|
||||
|
||||
if (discussion) {
|
||||
context.commit('addNewReplyToDiscussion', note);
|
||||
} else {
|
||||
context.commit('addNewNote', note);
|
||||
}
|
||||
} else {
|
||||
context.commit('addNewNote', note);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
= link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, format: 'json'), data: {original_text: "Reopen issue", alternative_text: "Comment & reopen issue"}, class: "btn btn-nr btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
|
||||
= link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, format: 'json'), data: {original_text: "Close issue", alternative_text: "Comment & close issue"}, class: "btn btn-nr btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
|
||||
|
||||
%section{ data: { discussions_path: discussions_namespace_project_issue_path(@project.namespace, @project, @issue, format: :json), new_session_path: new_session_path(:user, redirect_to_referer: 'yes') } }
|
||||
%section{ data: { discussions_path: discussions_namespace_project_issue_path(@project.namespace, @project, @issue, format: :json), new_session_path: new_session_path(:user, redirect_to_referer: 'yes'), notes_path: notes_url, last_fetched_at: Time.now.to_i } }
|
||||
#js-notes
|
||||
- content_for :page_specific_javascripts do
|
||||
= webpack_bundle_tag 'common_vue'
|
||||
|
|
Loading…
Reference in a new issue