diff options
Diffstat (limited to 'app/assets/javascripts/notes')
5 files changed, 44 insertions, 54 deletions
diff --git a/app/assets/javascripts/notes/components/issue_comment_form.vue b/app/assets/javascripts/notes/components/issue_comment_form.vue index 16f4e22aa9b..fa7ac994058 100644 --- a/app/assets/javascripts/notes/components/issue_comment_form.vue +++ b/app/assets/javascripts/notes/components/issue_comment_form.vue @@ -2,6 +2,7 @@ /* global Flash, Autosave */ import { mapActions, mapGetters } from 'vuex'; import _ from 'underscore'; + import autosize from 'vendor/autosize'; import '../../autosave'; import TaskList from '../../task_list'; import * as constants from '../constants'; @@ -96,6 +97,8 @@ methods: { ...mapActions([ 'saveNote', + 'stopPolling', + 'restartPolling', 'removePlaceholderNotes', ]), setIsSubmitButtonDisabled(note, isSubmitting) { @@ -124,10 +127,14 @@ } this.isSubmitting = true; this.note = ''; // Empty textarea while being requested. Repopulate in catch + this.resizeTextarea(); + this.stopPolling(); this.saveNote(noteData) .then((res) => { this.isSubmitting = false; + this.restartPolling(); + if (res.errors) { if (res.errors.commands_only) { this.discard(); @@ -174,6 +181,8 @@ if (shouldClear) { this.note = ''; + this.resizeTextarea(); + this.$refs.markdownField.previewMarkdown = false; } // reset autostave @@ -205,6 +214,11 @@ selector: '.notes', }); }, + resizeTextarea() { + this.$nextTick(() => { + autosize.update(this.$refs.textarea); + }); + }, }, mounted() { // jQuery is needed here because it is a custom event being dispatched with jQuery. @@ -247,7 +261,8 @@ :markdown-docs-path="markdownDocsPath" :quick-actions-docs-path="quickActionsDocsPath" :add-spacing-classes="false" - :is-confidential-issue="isConfidentialIssue"> + :is-confidential-issue="isConfidentialIssue" + ref="markdownField"> <textarea id="note-body" name="note[note]" diff --git a/app/assets/javascripts/notes/components/issue_note_icons.js b/app/assets/javascripts/notes/components/issue_note_icons.js deleted file mode 100644 index d8e3cb4bc01..00000000000 --- a/app/assets/javascripts/notes/components/issue_note_icons.js +++ /dev/null @@ -1,37 +0,0 @@ -import iconArrowCircle from 'icons/_icon_arrow_circle_o_right.svg'; -import iconCheck from 'icons/_icon_check_square_o.svg'; -import iconClock from 'icons/_icon_clock_o.svg'; -import iconCodeFork from 'icons/_icon_code_fork.svg'; -import iconComment from 'icons/_icon_comment_o.svg'; -import iconCommit from 'icons/_icon_commit.svg'; -import iconEdit from 'icons/_icon_edit.svg'; -import iconEye from 'icons/_icon_eye.svg'; -import iconEyeSlash from 'icons/_icon_eye_slash.svg'; -import iconMerge from 'icons/_icon_merge.svg'; -import iconMerged from 'icons/_icon_merged.svg'; -import iconRandom from 'icons/_icon_random.svg'; -import iconClosed from 'icons/_icon_status_closed.svg'; -import iconStatusOpen from 'icons/_icon_status_open.svg'; -import iconStopwatch from 'icons/_icon_stopwatch.svg'; -import iconTags from 'icons/_icon_tags.svg'; -import iconUser from 'icons/_icon_user.svg'; - -export default { - icon_arrow_circle_o_right: iconArrowCircle, - icon_check_square_o: iconCheck, - icon_clock_o: iconClock, - icon_code_fork: iconCodeFork, - icon_comment_o: iconComment, - icon_commit: iconCommit, - icon_edit: iconEdit, - icon_eye: iconEye, - icon_eye_slash: iconEyeSlash, - icon_merge: iconMerge, - icon_merged: iconMerged, - icon_random: iconRandom, - icon_status_closed: iconClosed, - icon_status_open: iconStatusOpen, - icon_stopwatch: iconStopwatch, - icon_tags: iconTags, - icon_user: iconUser, -}; diff --git a/app/assets/javascripts/notes/components/issue_system_note.vue b/app/assets/javascripts/notes/components/issue_system_note.vue index 5bb8f871b9d..0cfb6522e77 100644 --- a/app/assets/javascripts/notes/components/issue_system_note.vue +++ b/app/assets/javascripts/notes/components/issue_system_note.vue @@ -1,6 +1,5 @@ <script> import { mapGetters } from 'vuex'; - import iconsMap from './issue_note_icons'; import issueNoteHeader from './issue_note_header.vue'; export default { @@ -24,9 +23,9 @@ isTargetNote() { return this.targetNoteHash === this.noteAnchorId; }, - }, - created() { - this.svg = iconsMap[this.note.system_note_icon_name]; + iconHtml() { + return gl.utils.spriteIcon(this.note.system_note_icon_name); + }, }, }; </script> @@ -39,7 +38,7 @@ <div class="timeline-entry-inner"> <div class="timeline-icon" - v-html="svg"> + v-html="iconHtml"> </div> <div class="timeline-content"> <div class="note-header"> diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js index 13cd74bfa1c..1a791039909 100644 --- a/app/assets/javascripts/notes/stores/actions.js +++ b/app/assets/javascripts/notes/stores/actions.js @@ -7,6 +7,7 @@ import * as constants from '../constants'; import service from '../services/issue_notes_service'; import loadAwardsHandler from '../../awards_handler'; import sidebarTimeTrackingEventHub from '../../sidebar/event_hub'; +import { isInViewport, scrollToElement } from '../../lib/utils/common_utils'; let eTagPoll; @@ -186,6 +187,14 @@ export const poll = ({ commit, state, getters }) => { }); }; +export const stopPolling = () => { + eTagPoll.stop(); +}; + +export const restartPolling = () => { + eTagPoll.restart(); +}; + export const fetchData = ({ commit, state, getters }) => { const requestData = { endpoint: state.notesData.notesPath, lastFetchedAt: state.lastFetchedAt }; @@ -211,7 +220,7 @@ export const toggleAwardRequest = ({ commit, getters, dispatch }, data) => { }; export const scrollToNoteIfNeeded = (context, el) => { - if (!gl.utils.isInViewport(el[0])) { - gl.utils.scrollToElement(el); + if (!isInViewport(el[0])) { + scrollToElement(el); } }; diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js index 3b2b2089d6e..c2a08f3d6fe 100644 --- a/app/assets/javascripts/notes/stores/mutations.js +++ b/app/assets/javascripts/notes/stores/mutations.js @@ -5,15 +5,19 @@ import * as constants from '../constants'; export default { [types.ADD_NEW_NOTE](state, note) { const { discussion_id, type } = note; - const noteData = { - expanded: true, - id: discussion_id, - individual_note: !(type === constants.DISCUSSION_NOTE), - notes: [note], - reply_id: discussion_id, - }; - - state.notes.push(noteData); + const [exists] = state.notes.filter(n => n.id === note.discussion_id); + + if (!exists) { + const noteData = { + expanded: true, + id: discussion_id, + individual_note: !(type === constants.DISCUSSION_NOTE), + notes: [note], + reply_id: discussion_id, + }; + + state.notes.push(noteData); + } }, [types.ADD_NEW_REPLY_TO_DISCUSSION](state, note) { |