Skip to content

Show AI actions in rich text editor

Opportunity

Currently AI actions only appear in the markdown editor, however they're equally useful in the rich text editor.

image

Implementation guide

  1. Setup AI features: https://docs.gitlab.com/ee/development/ai_features/index.html#saas-only-features
  2. The implementation should be very similar to the saved replies feature which already works in the rich text editor. MR: !124745 (merged)
View patch
diff --git a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
index d19eceadca94..773c4dc4de5d 100644
--- a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
@@ -19,11 +19,13 @@ export default {
     ToolbarMoreDropdown,
     CommentTemplatesModal,
     HeaderDivider,
+    AiActionsDropdown: () => import('ee_component/ai/components/ai_actions_dropdown.vue'),
   },
   inject: {
     newCommentTemplatePaths: { default: () => [] },
     tiptapEditor: { default: null },
     contentEditor: { default: null },
+    editorAiActions: { default: () => [] },
   },
   props: {
     supportsQuickActions: {
@@ -67,8 +69,21 @@ export default {
     trackToolbarControlExecution({ contentType, value }) {
       trackUIControl({ property: contentType, value });
     },
+    insertFromAIAction(text, replace = false) {
+      this.insertText(`${text}\n\n---\n\n_${__('This comment was generated by AI')}_`, replace);
+    },
+    replaceFromAIAction(text) {
+      return this.insertFromAIAction(text, true);
+    },
     insertSavedReply(savedReply) {
-      this.tiptapEditor.chain().focus().pasteContent(savedReply).run();
+      this.insertText(savedReply);
+    },
+    insertText(text, clearContent = false) {
+      let commands = this.tiptapEditor.chain().focus();
+      if (clearContent) {
+        commands = commands.clearContent();
+      }
+      commands.pasteContent(text).run();
     },
   },
 };
@@ -85,6 +100,14 @@ export default {
       />
       <header-divider />
     </div>
+    <div v-if="editorAiActions.length" class="gl-display-flex">
+      <ai-actions-dropdown
+        :actions="editorAiActions"
+        @input="insertFromAIAction"
+        @replace="replaceFromAIAction"
+      />
+      <header-divider />
+    </div>
     <div v-if="codeSuggestionsEnabled" class="gl-display-flex">
       <toolbar-button
         v-if="codeSuggestionsEnabled"

Note that the above patch won't ask for confirmation before replacing the content in the description. The reason being that this action can easily be undone by pressing Cmd + Z. But, with some minor code change, you could choose to show the confirmation before replacing too in the actual implementation.

Edited by Himanshu Kapoor