BigW Consortium Gitlab

Commit 4dce23c0 by Fatih Acet

IssueNotesRefactor: Implement showing placeholder note while creating note.

parent b3da0ab5
......@@ -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');
......
......@@ -39,10 +39,10 @@ export default {
},
initTaskList() {
if (this.canEdit) {
new TaskList({
this.taskList = new TaskList({
dataType: 'note',
fieldName: 'note',
selector: '.notes'
selector: '.notes',
});
}
},
......
......@@ -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;
}
......
<script>
export default {
props: {
note: {
type: Object,
required: true,
},
},
data() {
return {
currentUser: window.gl.currentUserData,
};
},
};
</script>
<template>
<li class="note being-posted fade-in-half timeline-entry">
<div class="timeline-entry-inner">
<div class="timeline-icon">
<a :href="currentUser.path">
<img
:src="currentUser.avatar_url"
class="avatar s40" />
</a>
</div>
<div
:class="{ discussion: !note.individual_note }"
class="timeline-content">
<div class="note-header">
<div class="note-header-info">
<a :href="currentUser.path">
<span class="hidden-xs">{{currentUser.name}}</span>
<span class="note-headline-light">@{{currentUser.username}}</span>
</a>
</div>
</div>
<div class="note-body">
<div class="note-text">
<p>{{note.body}}</p>
</div>
</div>
</div>
</div>
</li>
</template>
......@@ -4,7 +4,7 @@ export default {
note: {
type: Object,
required: true,
}
},
},
};
</script>
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment