Browse Source

Fixes: Mobile - Inserting a knowledge base entry leads to loss of attachment data.

Florian Liebe 2 years ago
parent
commit
b1522ef10a

+ 3 - 0
app/frontend/apps/mobile/pages/ticket/composable/useTicketEditForm.ts

@@ -34,6 +34,9 @@ export const useTicketEditForm = (ticket: Ref<TicketById | undefined>) => {
       mentionUser: {
         groupNodeId: 'group_id',
       },
+      mentionKnowledgeBase: {
+        attachmentsNodeId: 'attachments',
+      },
       ...currentArticleType.value?.editorMeta,
     }
   })

+ 3 - 0
app/frontend/apps/mobile/pages/ticket/views/TicketCreate.vue

@@ -235,6 +235,9 @@ const ticketArticleMessageSection = getFormSchemaGroupSection(
               mentionUser: {
                 groupNodeId: 'group_id',
               },
+              mentionKnowledgeBase: {
+                attachmentsNodeId: 'attachments',
+              },
             },
           },
           triggerFormUpdater: false,

+ 19 - 4
app/frontend/cypress/shared/components/Form/fields/FieldEditor/editor-mention-knowledge-base.cy.ts

@@ -3,7 +3,7 @@
 import { mockApolloClient } from '@cy/utils'
 import { KnowledgeBaseAnswerSuggestionContentTransformDocument } from '@shared/components/Form/fields/FieldEditor/graphql/mutations/knowledgeBase/suggestion/content/transform.api'
 import { KnowledgeBaseAnswerSuggestionsDocument } from '@shared/components/Form/fields/FieldEditor/graphql/queries/knowledgeBase/answerSuggestions.api'
-import { mountEditor } from './utils'
+import { mountEditorWithAttachments } from './utils'
 
 describe('Testing "knowledge base" popup: "??" command', { retries: 2 }, () => {
   it('inserts a text', () => {
@@ -36,15 +36,27 @@ describe('Testing "knowledge base" popup: "??" command', { retries: 2 }, () => {
           knowledgeBaseAnswerSuggestionContentTransform: {
             __typename: 'KnowledgeBaseAnswerSuggestionContentTransform',
             body: 'knowledge base answer body',
-            // TODO separate test, when added
-            attachments: [],
+            attachments: [
+              {
+                id: 'gid://zammad/Store/2062',
+                name: 'Zammad.png',
+                size: 945213,
+                type: 'image/png',
+                preferences: {
+                  'Content-Type': 'image/png',
+                  resizable: true,
+                  content_preview: true,
+                },
+                __typename: 'StoredFile',
+              },
+            ],
             errors: null,
           },
         },
       }),
     )
 
-    mountEditor()
+    mountEditorWithAttachments()
 
     cy.findByRole('textbox').type('??How to c') // supports space
 
@@ -58,5 +70,8 @@ describe('Testing "knowledge base" popup: "??" command', { retries: 2 }, () => {
       .should('have.text', 'knowledge base answer body')
       .type('{backspace}{backspace}r')
       .should('have.text', 'knowledge base answer bor')
+
+    cy.findByText('Zammad.png').should('exist')
+    cy.findByText('923 KB').should('exist')
   })
 })

+ 39 - 0
app/frontend/cypress/shared/components/Form/fields/FieldEditor/utils.ts

@@ -2,6 +2,7 @@
 
 import { FormKit } from '@formkit/vue'
 import { mountComponent } from '@cy/utils'
+import Form from '@shared/components/Form/Form.vue'
 
 export const mountEditor = (props: Record<string, unknown> = {}) => {
   return mountComponent(FormKit, {
@@ -13,3 +14,41 @@ export const mountEditor = (props: Record<string, unknown> = {}) => {
     },
   })
 }
+
+export const mountEditorWithAttachments = () => {
+  const props = {
+    schema: [
+      {
+        isLayout: true,
+        component: 'FormGroup',
+        children: [
+          {
+            name: 'editor',
+            type: 'editor',
+            props: {
+              meta: {
+                mentionKnowledgeBase: {
+                  attachmentsNodeId: 'attachments',
+                },
+              },
+            },
+          },
+          {
+            name: 'attachments',
+            type: 'file',
+            props: {
+              multiple: true,
+            },
+          },
+        ],
+      },
+    ],
+  }
+
+  return mountComponent(Form, {
+    props,
+    attrs: {
+      class: 'form',
+    },
+  })
+}

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldEditor/graphql/mutations/knowledgeBase/suggestion/content/transform.api.ts

@@ -14,7 +14,7 @@ export const KnowledgeBaseAnswerSuggestionContentTransformDocument = gql`
   ) {
     body
     attachments {
-      internalId
+      id
       name
       size
       type

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldEditor/graphql/mutations/knowledgeBase/suggestion/content/transform.graphql

@@ -8,7 +8,7 @@ mutation knowledgeBaseAnswerSuggestionContentTransform(
   ) {
     body
     attachments {
-      internalId
+      id
       name
       size
       type

+ 27 - 4
app/frontend/shared/components/Form/fields/FieldEditor/suggestions/KnowledgeBaseSuggestion.ts

@@ -4,17 +4,20 @@ import Mention from '@tiptap/extension-mention'
 
 import { MutationHandler, QueryHandler } from '@shared/server/apollo/handler'
 import type { Ref } from 'vue'
+import { cloneDeep } from 'lodash-es'
 import type { FormFieldContext } from '@shared/components/Form/types/field'
 import { debouncedQuery } from '@shared/utils/helpers'
+import { getNodeByName } from '@shared/components/Form/utils'
+import type { FileUploaded } from '../../FieldFile/types'
 import { useKnowledgeBaseAnswerSuggestionsLazyQuery } from '../graphql/queries/knowledgeBase/answerSuggestions.api'
 import buildMentionSuggestion from './suggestions'
 import { useKnowledgeBaseAnswerSuggestionContentTransformMutation } from '../graphql/mutations/knowledgeBase/suggestion/content/transform.api'
-import type { MentionKnowledgeBaseItem } from '../types'
+import type { FieldEditorProps, MentionKnowledgeBaseItem } from '../types'
 
 export const PLUGIN_NAME = 'mentionKnowledgeBase'
 const ACTIVATOR = '??'
 
-export default (context: Ref<FormFieldContext>) => {
+export default (context: Ref<FormFieldContext<FieldEditorProps>>) => {
   const queryHandler = new QueryHandler(
     useKnowledgeBaseAnswerSuggestionsLazyQuery({
       query: '',
@@ -44,11 +47,31 @@ export default (context: Ref<FormFieldContext>) => {
       allowSpaces: true,
       type: 'knowledge-base',
       async insert(props: MentionKnowledgeBaseItem) {
+        const { meta: editorMeta = {}, formId } = context.value
+        const meta = editorMeta[PLUGIN_NAME] || {}
+
         const result = await translateHandler.send({
           translationId: props.id,
-          formId: context.value.formId,
+          formId,
         })
-        // TODO process attachments, use meta[PLUGIN_NAME].attachmentsNodeId
+
+        const attachmentsNodeId = meta?.attachmentsNodeId
+
+        if (attachmentsNodeId) {
+          const attachmentField = getNodeByName(
+            context.value.formId,
+            attachmentsNodeId,
+          )
+
+          const existingAttachments = (cloneDeep(attachmentField?.value) ||
+            []) as FileUploaded[]
+          const newAttachments =
+            result?.knowledgeBaseAnswerSuggestionContentTransform
+              ?.attachments || []
+
+          attachmentField?.input?.([...existingAttachments, ...newAttachments])
+        }
+
         return result?.knowledgeBaseAnswerSuggestionContentTransform?.body || ''
       },
       items: debouncedQuery(async ({ query }) => {

+ 1 - 1
app/frontend/shared/graphql/types.ts

@@ -2621,7 +2621,7 @@ export type KnowledgeBaseAnswerSuggestionContentTransformMutationVariables = Exa
 }>;
 
 
-export type KnowledgeBaseAnswerSuggestionContentTransformMutation = { __typename?: 'Mutations', knowledgeBaseAnswerSuggestionContentTransform?: { __typename?: 'KnowledgeBaseAnswerSuggestionContentTransformPayload', body?: string | null, attachments?: Array<{ __typename?: 'StoredFile', internalId: number, name: string, size?: number | null, type?: string | null, preferences?: any | null }> | null, errors?: Array<{ __typename?: 'UserError', message: string, field?: string | null }> | null } | null };
+export type KnowledgeBaseAnswerSuggestionContentTransformMutation = { __typename?: 'Mutations', knowledgeBaseAnswerSuggestionContentTransform?: { __typename?: 'KnowledgeBaseAnswerSuggestionContentTransformPayload', body?: string | null, attachments?: Array<{ __typename?: 'StoredFile', id: string, name: string, size?: number | null, type?: string | null, preferences?: any | null }> | null, errors?: Array<{ __typename?: 'UserError', message: string, field?: string | null }> | null } | null };
 
 export type KnowledgeBaseAnswerSuggestionsQueryVariables = Exact<{
   query: Scalars['String'];

+ 2 - 2
spec/graphql/gql/mutations/knowledge_base/answer/suggestion/content/transform_spec.rb

@@ -22,7 +22,7 @@ RSpec.describe Gql::Mutations::KnowledgeBase::Answer::Suggestion::Content::Trans
           ) {
             body
             attachments {
-              internalId
+              id
               name
               size
               type
@@ -53,7 +53,7 @@ RSpec.describe Gql::Mutations::KnowledgeBase::Answer::Suggestion::Content::Trans
       it 'contains attachments' do
         expect(gql.result.data['attachments']).to eq([
                                                        {
-                                                         'internalId'  => copied_attachments.first.id,
+                                                         'id'          => Gql::ZammadSchema.id_from_object(copied_attachments.first),
                                                          'name'        => copied_attachments.first.filename,
                                                          'size'        => copied_attachments.first.size.to_i,
                                                          'type'        => copied_attachments.first.preferences['Content-Type'],