PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/app/assets/javascripts/notes/components/note_body.vue

https://gitlab.com/klml/gitlab-ee
Vue | 207 lines | 192 code | 9 blank | 6 comment | 6 complexity | 64541c61ba8aaf99af917ac2395aead7 MD5 | raw file
  1. <script>
  2. /* eslint-disable vue/no-v-html */
  3. import $ from 'jquery';
  4. import { escape } from 'lodash';
  5. import { mapActions, mapGetters, mapState } from 'vuex';
  6. import '~/behaviors/markdown/render_gfm';
  7. import Suggestions from '~/vue_shared/components/markdown/suggestions.vue';
  8. import autosave from '../mixins/autosave';
  9. import noteAttachment from './note_attachment.vue';
  10. import noteAwardsList from './note_awards_list.vue';
  11. import noteEditedText from './note_edited_text.vue';
  12. import noteForm from './note_form.vue';
  13. export default {
  14. components: {
  15. noteEditedText,
  16. noteAwardsList,
  17. noteAttachment,
  18. noteForm,
  19. Suggestions,
  20. },
  21. mixins: [autosave],
  22. props: {
  23. note: {
  24. type: Object,
  25. required: true,
  26. },
  27. line: {
  28. type: Object,
  29. required: false,
  30. default: null,
  31. },
  32. file: {
  33. type: Object,
  34. required: false,
  35. default: null,
  36. },
  37. canEdit: {
  38. type: Boolean,
  39. required: true,
  40. },
  41. isEditing: {
  42. type: Boolean,
  43. required: false,
  44. default: false,
  45. },
  46. helpPagePath: {
  47. type: String,
  48. required: false,
  49. default: '',
  50. },
  51. },
  52. computed: {
  53. ...mapGetters(['getDiscussion', 'suggestionsCount']),
  54. ...mapGetters('diffs', ['suggestionCommitMessage']),
  55. discussion() {
  56. if (!this.note.isDraft) return {};
  57. return this.getDiscussion(this.note.discussion_id);
  58. },
  59. ...mapState({
  60. batchSuggestionsInfo: (state) => state.notes.batchSuggestionsInfo,
  61. }),
  62. noteBody() {
  63. return this.note.note;
  64. },
  65. hasSuggestion() {
  66. return this.note.suggestions && this.note.suggestions.length;
  67. },
  68. lineType() {
  69. return this.line ? this.line.type : null;
  70. },
  71. commitMessage() {
  72. // Please see this issue comment for why these
  73. // are hard-coded to 1:
  74. // https://gitlab.com/gitlab-org/gitlab/-/issues/291027#note_468308022
  75. const suggestionsCount = 1;
  76. const filesCount = 1;
  77. const filePaths = this.file ? [this.file.file_path] : [];
  78. const suggestion = this.suggestionCommitMessage({
  79. file_paths: filePaths.join(', '),
  80. suggestions_count: suggestionsCount,
  81. files_count: filesCount,
  82. });
  83. return escape(suggestion);
  84. },
  85. },
  86. mounted() {
  87. this.renderGFM();
  88. if (this.isEditing) {
  89. this.initAutoSave(this.note);
  90. }
  91. },
  92. updated() {
  93. this.renderGFM();
  94. if (this.isEditing) {
  95. if (!this.autosave) {
  96. this.initAutoSave(this.note);
  97. } else {
  98. this.setAutoSave();
  99. }
  100. }
  101. },
  102. methods: {
  103. ...mapActions([
  104. 'submitSuggestion',
  105. 'submitSuggestionBatch',
  106. 'addSuggestionInfoToBatch',
  107. 'removeSuggestionInfoFromBatch',
  108. ]),
  109. renderGFM() {
  110. $(this.$refs['note-body']).renderGFM();
  111. },
  112. handleFormUpdate(note, parentElement, callback, resolveDiscussion) {
  113. this.$emit('handleFormUpdate', note, parentElement, callback, resolveDiscussion);
  114. },
  115. formCancelHandler(shouldConfirm, isDirty) {
  116. this.$emit('cancelForm', shouldConfirm, isDirty);
  117. },
  118. applySuggestion({ suggestionId, flashContainer, callback = () => {}, message }) {
  119. const { discussion_id: discussionId, id: noteId } = this.note;
  120. return this.submitSuggestion({
  121. discussionId,
  122. noteId,
  123. suggestionId,
  124. flashContainer,
  125. message,
  126. }).then(callback);
  127. },
  128. applySuggestionBatch({ flashContainer }) {
  129. return this.submitSuggestionBatch({ flashContainer });
  130. },
  131. addSuggestionToBatch(suggestionId) {
  132. const { discussion_id: discussionId, id: noteId } = this.note;
  133. this.addSuggestionInfoToBatch({ suggestionId, discussionId, noteId });
  134. },
  135. removeSuggestionFromBatch(suggestionId) {
  136. this.removeSuggestionInfoFromBatch(suggestionId);
  137. },
  138. },
  139. };
  140. </script>
  141. <template>
  142. <div ref="note-body" :class="{ 'js-task-list-container': canEdit }" class="note-body">
  143. <suggestions
  144. v-if="hasSuggestion && !isEditing"
  145. :suggestions="note.suggestions"
  146. :suggestions-count="suggestionsCount"
  147. :batch-suggestions-info="batchSuggestionsInfo"
  148. :note-html="note.note_html"
  149. :line-type="lineType"
  150. :help-page-path="helpPagePath"
  151. :default-commit-message="commitMessage"
  152. @apply="applySuggestion"
  153. @applyBatch="applySuggestionBatch"
  154. @addToBatch="addSuggestionToBatch"
  155. @removeFromBatch="removeSuggestionFromBatch"
  156. />
  157. <div v-else class="note-text md" v-html="note.note_html"></div>
  158. <note-form
  159. v-if="isEditing"
  160. ref="noteForm"
  161. :is-editing="isEditing"
  162. :note-body="noteBody"
  163. :note-id="note.id"
  164. :line="line"
  165. :note="note"
  166. :help-page-path="helpPagePath"
  167. :discussion="discussion"
  168. :resolve-discussion="note.resolve_discussion"
  169. @handleFormUpdate="handleFormUpdate"
  170. @cancelForm="formCancelHandler"
  171. />
  172. <!-- eslint-disable vue/no-mutating-props -->
  173. <textarea
  174. v-if="canEdit"
  175. v-model="note.note"
  176. :data-update-url="note.path"
  177. class="hidden js-task-list-field"
  178. dir="auto"
  179. ></textarea>
  180. <!-- eslint-enable vue/no-mutating-props -->
  181. <note-edited-text
  182. v-if="note.last_edited_at"
  183. :edited-at="note.last_edited_at"
  184. :edited-by="note.last_edited_by"
  185. action-text="Edited"
  186. class="note_edited_ago"
  187. />
  188. <note-awards-list
  189. v-if="note.award_emoji && note.award_emoji.length"
  190. :note-id="note.id"
  191. :note-author-id="note.author.id"
  192. :awards="note.award_emoji"
  193. :toggle-award-path="note.toggle_award_path"
  194. :can-award-emoji="note.current_user.can_award_emoji"
  195. />
  196. <note-attachment v-if="note.attachment" :attachment="note.attachment" />
  197. </div>
  198. </template>