diff --git a/app/assets/javascripts/notes/components/issue_comment_form.vue b/app/assets/javascripts/notes/components/issue_comment_form.vue
index 2673b3a32027cad5d47baf6c9628738a666244e4..fbe339bd27391477e5b4eca9cd4b6ee8dc16498b 100644
--- a/app/assets/javascripts/notes/components/issue_comment_form.vue
+++ b/app/assets/javascripts/notes/components/issue_comment_form.vue
@@ -6,8 +6,8 @@ import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_
import MarkdownField from '../../vue_shared/components/markdown/field.vue';
import IssueNoteSignedOutWidget from './issue_note_signed_out_widget.vue';
import eventHub from '../event_hub';
-const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
+const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
export default {
data() {
const { create_note_path, state } = window.gl.issueData;
@@ -67,15 +67,50 @@ export default {
data.noteData.note.type = 'DiscussionNote';
}
- this.$store.dispatch('createNewNote', data)
- .then(this.handleNewNoteCreated)
- .catch(this.handleError);
+ let placeholderText = this.note;
+ const hasQuickActions = this.hasQuickActions();
+
+ if (hasQuickActions) {
+ placeholderText = this.stripQuickActions();
+ }
- if (this.hasQuickActions()) {
- this.$store.commit('showPlaceholderSystemNote', {
+ if (placeholderText.length) {
+ this.$store.commit('showPlaceholderNote', {
+ noteBody: placeholderText,
+ });
+ }
+
+ if (hasQuickActions) {
+ this.$store.commit('showPlaceholderNote', {
+ isSystemNote: true,
noteBody: this.getQuickActionText(),
});
}
+
+ this.$store.dispatch('createNewNote', data)
+ .then((res) => {
+ const { errors } = res;
+
+ if (hasQuickActions) {
+ this.$store.dispatch('poll');
+ $(this.$refs.textarea).trigger('clear-commands-cache.atwho');
+ new Flash('Commands applied', 'notice', $(this.$el)); // eslint-disable-line
+ }
+
+ if (errors) {
+ if (errors.commands_only) {
+ new Flash(errors.commands_only, 'notice', $(this.$el)); // eslint-disable-line
+ this.discard();
+ } else {
+ this.handleError();
+ }
+ } else {
+ this.discard();
+ }
+
+ this.$store.commit('removePlaceholderNotes');
+ })
+ .catch(this.handleError);
}
if (withIssueAction) {
@@ -94,26 +129,6 @@ export default {
$(`.js-btn-issue-action.${btnClass}:visible`).trigger('click');
}
},
- handleNewNoteCreated(res) {
- const { commands_changes, errors, valid } = res;
-
- if (!valid && errors) {
- const { commands_only } = errors;
-
- if (commands_only) {
- new Flash(commands_only, 'notice', $(this.$el)); // eslint-disable-line
- $(this.$refs.textarea).trigger('clear-commands-cache.atwho');
- this.$store.dispatch('poll');
- this.discard();
- } else {
- this.handleError();
- }
- } else {
- this.discard();
- }
-
- this.$store.commit('removePlaceholderSystemNote');
- },
discard() {
// `blur` is needed to clear slash commands autocomplete cache if event fired.
// `focus` is needed to remain cursor in the textarea.
@@ -143,7 +158,7 @@ export default {
const quickActions = AjaxCache.get(gl.GfmAutoComplete.dataSources.commands);
const { note } = this;
- const executedCommands = quickActions.filter((command, index) => {
+ const executedCommands = quickActions.filter((command) => {
const commandRegex = new RegExp(`/${command.name}`);
return commandRegex.test(note);
});
@@ -162,6 +177,9 @@ export default {
hasQuickActions() {
return REGEX_QUICK_ACTIONS.test(this.note);
},
+ stripQuickActions() {
+ return this.note.replace(REGEX_QUICK_ACTIONS, '').trim();
+ },
},
mounted() {
const issuableDataEl = document.getElementById('js-issuable-app-initial-data');
diff --git a/app/assets/javascripts/notes/components/issue_note_body.vue b/app/assets/javascripts/notes/components/issue_note_body.vue
index 73af85b3b171ac71e648a82c6d28aea761e5c7d8..ee9318cbd6a0eeecffe6394db75411f62bdc0a3b 100644
--- a/app/assets/javascripts/notes/components/issue_note_body.vue
+++ b/app/assets/javascripts/notes/components/issue_note_body.vue
@@ -39,10 +39,10 @@ export default {
},
initTaskList() {
if (this.canEdit) {
- new TaskList({
+ this.taskList = new TaskList({
dataType: 'note',
fieldName: 'note',
- selector: '.notes'
+ selector: '.notes',
});
}
},
diff --git a/app/assets/javascripts/notes/components/issue_notes.vue b/app/assets/javascripts/notes/components/issue_notes.vue
index f9de277e465769d54b6eb5355e7a554d37e8a29b..18e181d1b805df128c7cbdaa4baa5d3f43c4f351 100644
--- a/app/assets/javascripts/notes/components/issue_notes.vue
+++ b/app/assets/javascripts/notes/components/issue_notes.vue
@@ -9,6 +9,7 @@ import IssueNote from './issue_note.vue';
import IssueDiscussion from './issue_discussion.vue';
import IssueSystemNote from './issue_system_note.vue';
import IssueCommentForm from './issue_comment_form.vue';
+import PlaceholderNote from './issue_placeholder_note.vue';
import PlaceholderSystemNote from './issue_placeholder_system_note.vue';
Vue.use(Vuex);
@@ -27,6 +28,7 @@ export default {
IssueDiscussion,
IssueSystemNote,
IssueCommentForm,
+ PlaceholderNote,
PlaceholderSystemNote,
},
computed: {
@@ -37,12 +39,12 @@ export default {
},
methods: {
component(note) {
- if (note.placeholderNote) {
+ if (note.isPlaceholderNote) {
if (note.placeholderType === 'systemNote') {
return PlaceholderSystemNote;
}
- }
- else if (note.individual_note) {
+ return PlaceholderNote;
+ } else if (note.individual_note) {
return note.notes[0].system ? IssueSystemNote : IssueNote;
}
diff --git a/app/assets/javascripts/notes/components/issue_placeholder_note.vue b/app/assets/javascripts/notes/components/issue_placeholder_note.vue
new file mode 100644
index 0000000000000000000000000000000000000000..af249c56a3df62e42681a6e5d71a581ed2835864
--- /dev/null
+++ b/app/assets/javascripts/notes/components/issue_placeholder_note.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
diff --git a/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue b/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
index d84e236c92c4615aea7f1b59326aabd701e132da..6738d82e7e7ce0a7a79a6f53d1beba00c024eda6 100644
--- a/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
+++ b/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
@@ -4,7 +4,7 @@ export default {
note: {
type: Object,
required: true,
- }
+ },
},
};
diff --git a/app/assets/javascripts/notes/stores/issue_notes_store.js b/app/assets/javascripts/notes/stores/issue_notes_store.js
index 5da416b9320d15a45e07f6393d1e01527d234153..469b850c3fba8c6eda0874c9c43f64dc0b7908e1 100644
--- a/app/assets/javascripts/notes/stores/issue_notes_store.js
+++ b/app/assets/javascripts/notes/stores/issue_notes_store.js
@@ -108,30 +108,25 @@ const mutations = {
setLastFetchedAt(storeState, fetchedAt) {
storeState.lastFetchedAt = fetchedAt;
},
- showPlaceholderSystemNote(storeState, data) {
+ showPlaceholderNote(storeState, data) {
storeState.notes.push({
- placeholderNote: true,
individual_note: true,
- placeholderType: 'systemNote',
+ isPlaceholderNote: true,
+ placeholderType: data.isSystemNote ? 'systemNote' : 'note',
notes: [
{
- id: 'placeholderSystemNote',
body: data.noteBody,
},
],
});
},
- removePlaceholderSystemNote(storeState) {
- let index = -1;
+ removePlaceholderNotes(storeState) {
+ const { notes } = storeState;
- storeState.notes.forEach((n, i) => {
- if (n.placeholderNote && n.placeholderType === 'systemNote') {
- index = i;
+ for (let i = notes.length - 1; i >= 0; i -= 1) {
+ if (notes[i].isPlaceholderNote) {
+ notes.splice(i, 1);
}
- });
-
- if (index > -1) {
- storeState.notes.splice(index, 1);
}
},
};
@@ -185,7 +180,7 @@ const actions = {
return res;
});
},
- poll(context, data) {
+ poll(context) {
const { notesPath } = $('.js-notes-wrapper')[0].dataset;
return service