From 9092bed94c43defb8579472df86e3f5d73204be7 Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Mon, 27 Aug 2018 15:56:15 +0200 Subject: Adds the functionality to convert a non-discussion into a discussion --- .../javascripts/notes/components/note_actions.vue | 24 ++++++++++++++++++ .../javascripts/notes/components/noteable_note.vue | 29 +++++++++++++++++++++- .../javascripts/notes/services/notes_service.js | 3 +++ app/assets/javascripts/notes/stores/actions.js | 8 ++++++ .../javascripts/notes/stores/mutation_types.js | 1 + app/controllers/projects/notes_controller.rb | 17 +++++++++++++ app/services/notes/convert_service.rb | 7 ++++++ config/routes/project.rb | 1 + 8 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 app/services/notes/convert_service.rb 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'); }, @@ -186,6 +193,23 @@ export default { +
+ +
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" />
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 -- cgit v1.2.3