diff options
author | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-08-27 16:56:15 +0300 |
---|---|---|
committer | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-08-27 17:55:18 +0300 |
commit | 9092bed94c43defb8579472df86e3f5d73204be7 (patch) | |
tree | e9b5075987cc31aa1ada82775ecba3fe3483e9a9 | |
parent | 452fd703f322370e6bf12a4f243e258db7e278f5 (diff) |
Adds the functionality to convert a non-discussion into a discussion30299-convert-non-discussion-into-discussion
-rw-r--r-- | app/assets/javascripts/notes/components/note_actions.vue | 24 | ||||
-rw-r--r-- | app/assets/javascripts/notes/components/noteable_note.vue | 29 | ||||
-rw-r--r-- | app/assets/javascripts/notes/services/notes_service.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/notes/stores/actions.js | 8 | ||||
-rw-r--r-- | app/assets/javascripts/notes/stores/mutation_types.js | 1 | ||||
-rw-r--r-- | app/controllers/projects/notes_controller.rb | 17 | ||||
-rw-r--r-- | app/services/notes/convert_service.rb | 7 | ||||
-rw-r--r-- | config/routes/project.rb | 1 |
8 files changed, 89 insertions, 1 deletions
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue index cdbbb342331..452f406e48d 100644 --- a/app/assets/javascripts/notes/components/note_actions.vue +++ b/app/assets/javascripts/notes/components/note_actions.vue @@ -44,6 +44,10 @@ export default { type: Boolean, required: true, }, + canConvertToDiscussion: { + type: Boolean, + required: true, + }, canAwardEmoji: { type: Boolean, required: true, @@ -113,6 +117,9 @@ export default { this.resolvedDiscussionSvg = resolvedDiscussionSvg; }, methods: { + onConvertToDiscussion() { + this.$emit('handleConvertToDiscussion'); + }, onEdit() { this.$emit('handleEdit'); }, @@ -187,6 +194,23 @@ export default { </a> </div> <div + v-if="canConvertToDiscussion" + class="note-actions-item"> + <button + v-tooltip + type="button" + title="Start a discussion" + class="note-action-button js-note-edit btn btn-transparent" + data-container="body" + data-placement="bottom" + @click="onConvertToDiscussion"> + <span + class="link-highlight" + v-html="editSvg"> + </span> + </button> + </div> + <div v-if="canEdit" class="note-actions-item"> <button diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index 4ebeb5599f2..b7c59d75155 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -28,6 +28,7 @@ export default { }, data() { return { + isConverting: false, isEditing: false, isDeleting: false, isRequesting: false, @@ -42,12 +43,16 @@ export default { classNameBindings() { return { [`note-row-${this.note.id}`]: true, + 'is-converting': this.isConverting && !this.isRequesting, 'is-editing': this.isEditing && !this.isRequesting, 'is-requesting being-posted': this.isRequesting, 'disabled-content': this.isDeleting, target: this.isTarget, }; }, + canConvertToDiscussion() { + return !this.note.resolvable && !!this.getUserData.id; + }, canResolve() { return this.note.resolvable && !!this.getUserData.id; }, @@ -78,10 +83,30 @@ export default { }, methods: { - ...mapActions(['deleteNote', 'updateNote', 'toggleResolveNote', 'scrollToNoteIfNeeded']), + ...mapActions(['convertToDiscussion', 'deleteNote', 'updateNote', 'toggleResolveNote', 'scrollToNoteIfNeeded']), editHandler() { this.isEditing = true; }, + convertToDiscussionHandler() { + const data = { + endpoint: `${this.note.path}/convert`, + note: { + target_type: this.getNoteableData.targetType, + target_id: this.note.noteable_id, + }, + }; + + this.isConverting = true; + + this.convertToDiscussion(data) + .then(() => { + this.isConverting = false; + }) + .catch(() => { + Flash('Something went wrong while converting to a discussion. Please try again.'); + this.isConverting = false; + }) + }, deleteHandler() { // eslint-disable-next-line no-alert if (window.confirm('Are you sure you want to delete this comment?')) { @@ -183,6 +208,7 @@ export default { :access-level="note.human_access" :can-edit="note.current_user.can_edit" :can-award-emoji="note.current_user.can_award_emoji" + :can-convert-to-discussion="canConvertToDiscussion" :can-delete="note.current_user.can_edit" :can-report-as-abuse="canReportAsAbuse" :can-resolve="note.current_user.can_resolve" @@ -194,6 +220,7 @@ export default { @handleEdit="editHandler" @handleDelete="deleteHandler" @handleResolve="resolveHandler" + @handleConvertToDiscussion="convertToDiscussionHandler" /> </div> <note-body diff --git a/app/assets/javascripts/notes/services/notes_service.js b/app/assets/javascripts/notes/services/notes_service.js index f5dce94caad..efcf756ba8d 100644 --- a/app/assets/javascripts/notes/services/notes_service.js +++ b/app/assets/javascripts/notes/services/notes_service.js @@ -8,6 +8,9 @@ export default { fetchDiscussions(endpoint) { return Vue.http.get(endpoint); }, + convertToDiscussion(endpoint, data) { + return Vue.http.post(endpoint, data, { emulateJSON: true }); + }, deleteNote(endpoint) { return Vue.http.delete(endpoint); }, diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js index 3eefbe11c37..0b7799fdedd 100644 --- a/app/assets/javascripts/notes/stores/actions.js +++ b/app/assets/javascripts/notes/stores/actions.js @@ -52,6 +52,14 @@ export const refetchDiscussionById = ({ commit }, { path, discussionId }) => if (selectedDiscussion) commit(types.UPDATE_DISCUSSION, selectedDiscussion); }); +export const convertToDiscussion = ({ commit }, { endpoint, note }) => + service + .convertToDiscussion(endpoint) + .then(res => res.json()) + .then(res => { + commit(types.CONVERT_TO_DISCUSSION, res) + }); + export const deleteNote = ({ commit }, note) => service.deleteNote(note.path).then(() => { commit(types.DELETE_NOTE, note); diff --git a/app/assets/javascripts/notes/stores/mutation_types.js b/app/assets/javascripts/notes/stores/mutation_types.js index 6f374f78691..417ce6402e0 100644 --- a/app/assets/javascripts/notes/stores/mutation_types.js +++ b/app/assets/javascripts/notes/stores/mutation_types.js @@ -1,5 +1,6 @@ export const ADD_NEW_NOTE = 'ADD_NEW_NOTE'; export const ADD_NEW_REPLY_TO_DISCUSSION = 'ADD_NEW_REPLY_TO_DISCUSSION'; +export const CONVERT_TO_DISCUSSION = 'CONVERT_TO_DISCUSSION'; export const DELETE_NOTE = 'DELETE_NOTE'; export const REMOVE_PLACEHOLDER_NOTES = 'REMOVE_PLACEHOLDER_NOTES'; export const SET_NOTES_DATA = 'SET_NOTES_DATA'; diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 21e2145b73b..f6f6f6cfb19 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -18,6 +18,23 @@ class Projects::NotesController < Projects::ApplicationController end end + def convert + return render_404 if note.resolvable? + + Notes::ConvertService.new(project, current_user).execute(note) + + discussion = note.discussion + + if serialize_notes? + render_json_with_notes_serializer + else + render json: { + resolved_by: note.resolved_by.try(:name), + discussion_headline_html: (view_to_html_string('discussions/_headline', discussion: discussion) if discussion) + } + end + end + def resolve return render_404 unless note.resolvable? diff --git a/app/services/notes/convert_service.rb b/app/services/notes/convert_service.rb new file mode 100644 index 00000000000..e42ef86cc98 --- /dev/null +++ b/app/services/notes/convert_service.rb @@ -0,0 +1,7 @@ +module Notes + class ConvertService < ::BaseService + def execute(note) + note.update!(type: DiscussionNote.to_s) + end + end +end diff --git a/config/routes/project.rb b/config/routes/project.rb index 0220e88c819..dd63c2e8f3e 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -390,6 +390,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do member do delete :delete_attachment post :resolve + post :convert delete :resolve, action: :unresolve end end |