Browse Source

Maintenance: Add support for excepting users from autocomplete search results.

Dusan Vuckovic 10 months ago
parent
commit
629f0e12b3

+ 4 - 0
app/frontend/apps/desktop/components/Form/fields/FieldAgent/FieldAgentWrapper.vue

@@ -16,6 +16,7 @@ interface Props {
   context: FormFieldContext<
     AutoCompleteProps & {
       options?: AutoCompleteAgentOption[]
+      exceptUserInternalId?: number
     }
   >
 }
@@ -47,6 +48,9 @@ Object.assign(props.context, {
     return buildEntityOption(belongsToObject)
   },
   gqlQuery: AutocompleteSearchAgentDocument,
+  additionalQueryParams: {
+    exceptInternalId: props.context.exceptUserInternalId,
+  },
 })
 </script>
 

+ 29 - 0
app/frontend/apps/desktop/components/Form/fields/FieldAgent/__tests__/FieldAgent.spec.ts

@@ -278,4 +278,33 @@ describe('Form - Field - Agent - Query', () => {
 
     expect(wrapper.getByIconName('check2')).toBeInTheDocument()
   })
+
+  it('supports filtering out specific user', async () => {
+    const wrapper = renderComponent(FormKit, {
+      ...wrapperParameters,
+      props: {
+        ...testProps,
+        debounceInterval: 0,
+        exceptUserInternalId: 999,
+      },
+    })
+
+    await wrapper.events.click(await wrapper.findByLabelText('Select…'))
+
+    const filterElement = wrapper.getByRole('searchbox')
+
+    mockAutocompleteSearchAgentQuery({
+      autocompleteSearchAgent: [...testOptions.slice(0, 1)],
+    })
+
+    await wrapper.events.type(filterElement, '*')
+
+    const calls = await waitForAutocompleteSearchAgentQueryCalls()
+
+    expect(calls.at(-1)?.variables).toEqual({
+      input: expect.objectContaining({
+        exceptInternalId: 999,
+      }),
+    })
+  })
 })

+ 7 - 3
app/frontend/apps/desktop/components/Form/fields/FieldAgent/index.ts

@@ -6,9 +6,13 @@ import formUpdaterTrigger from '#shared/form/features/formUpdaterTrigger.ts'
 import FieldAgentWrapper from './FieldAgentWrapper.vue'
 import { autoCompleteProps } from '../FieldAutoComplete/index.ts'
 
-const fieldDefinition = createInput(FieldAgentWrapper, autoCompleteProps, {
-  features: [addLink, formUpdaterTrigger()],
-})
+const fieldDefinition = createInput(
+  FieldAgentWrapper,
+  [...autoCompleteProps, 'exceptUserInternalId'],
+  {
+    features: [addLink, formUpdaterTrigger()],
+  },
+)
 
 export default {
   fieldType: 'agent',

+ 29 - 0
app/frontend/apps/desktop/components/Form/fields/FieldAutoComplete/__tests__/FieldAutoComplete.spec.ts

@@ -481,6 +481,35 @@ describe('Form - Field - AutoComplete - Query', () => {
       },
     ])
   })
+
+  it('supports passing additional query parameters', async () => {
+    const wrapper = renderComponent(FormKit, {
+      ...wrapperParameters,
+      props: {
+        ...testProps,
+        debounceInterval: 0,
+        additionalQueryParams: {
+          limit: 2,
+        },
+      },
+    })
+
+    await wrapper.events.click(wrapper.getByLabelText('Select…'))
+
+    mockAutocompleteSearchUserQuery({
+      autocompleteSearchUser: testOptions,
+    })
+
+    await wrapper.events.type(wrapper.getByRole('searchbox'), '*')
+
+    const calls = await waitForAutocompleteSearchUserQueryCalls()
+
+    expect(calls.at(-1)?.variables).toEqual({
+      input: expect.objectContaining({
+        limit: 2,
+      }),
+    })
+  })
 })
 
 describe('Form - Field - AutoComplete - Initial Options', () => {

+ 26 - 5
app/frontend/apps/desktop/pages/personal-setting/__tests__/personal-setting-out-of-office.spec.ts

@@ -43,6 +43,8 @@ describe('Out of Office page', () => {
   describe('when enabled', () => {
     beforeEach(() => {
       mockAccount({
+        id: '123',
+        internalId: 1,
         firstname: 'John',
         lastname: 'Doe',
         outOfOffice: true,
@@ -172,8 +174,6 @@ describe('Out of Office page', () => {
     it('cannot set replacement agent to blank', async () => {
       const view = await visitView('/personal-setting/out-of-office')
 
-      await vi.dynamicImportSettled()
-
       const input = view.getByLabelText('Replacement agent')
       const button = getByRole(input, 'button')
       await view.events.click(button)
@@ -183,6 +183,30 @@ describe('Out of Office page', () => {
       expect(input).toBeDescribedBy('This field is required.')
     })
 
+    it('cannot set replacement agent to themselves', async () => {
+      const view = await visitView('/personal-setting/out-of-office')
+
+      const inputAgent = view.getByLabelText('Replacement agent')
+
+      await view.events.click(inputAgent)
+
+      const filterElement = getByRole(inputAgent, 'searchbox')
+
+      mockAutocompleteSearchAgentQuery({
+        autocompleteSearchAgent: agentAutocompleteOptions,
+      })
+
+      await view.events.type(filterElement, '*')
+
+      const calls = await waitForAutocompleteSearchAgentQueryCalls()
+
+      expect(calls.at(-1)?.variables).toEqual({
+        input: expect.objectContaining({
+          exceptInternalId: 1,
+        }),
+      })
+    })
+
     it('can disable Out of Office', async () => {
       const view = await visitView('/personal-setting/out-of-office')
 
@@ -204,7 +228,6 @@ describe('Out of Office page', () => {
 
     it('can disable Out of Office and unset settings', async () => {
       const view = await visitView('/personal-setting/out-of-office')
-      await vi.dynamicImportSettled()
 
       const inputActivated = view.getByLabelText('Active')
       await view.events.click(inputActivated)
@@ -252,7 +275,6 @@ describe('Out of Office page', () => {
 
     it('loads current Out of Office settings', async () => {
       const view = await visitView('/personal-setting/out-of-office')
-      await vi.dynamicImportSettled()
 
       expect(view.getByLabelText('Reason for absence')).toHaveValue('')
       expect(view.getByLabelText('Start and end date')).toHaveValue('')
@@ -283,7 +305,6 @@ describe('Out of Office page', () => {
 
     it('can set replacement agent', async () => {
       const view = await visitView('/personal-setting/out-of-office')
-      await vi.dynamicImportSettled()
 
       const inputAgent = view.getByLabelText('Replacement agent')
 

+ 1 - 0
app/frontend/apps/desktop/pages/personal-setting/views/PersonalSettingOutOfOffice.vue

@@ -59,6 +59,7 @@ const schema = defineFormSchema([
         props: {
           clearable: true,
           belongsToObjectField: 'outOfOfficeReplacement',
+          exceptUserInternalId: user.value?.internalId,
         },
       },
       {

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldAgent/graphql/queries/autocompleteSearch/agent.api.ts

@@ -7,7 +7,7 @@ import * as VueCompositionApi from 'vue';
 export type ReactiveFunction<TParam> = () => TParam;
 
 export const AutocompleteSearchAgentDocument = gql`
-    query autocompleteSearchAgent($input: AutocompleteSearchInput!) {
+    query autocompleteSearchAgent($input: AutocompleteSearchUserInput!) {
   autocompleteSearchAgent(input: $input) {
     value
     label

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldAgent/graphql/queries/autocompleteSearch/agent.graphql

@@ -1,4 +1,4 @@
-query autocompleteSearchAgent($input: AutocompleteSearchInput!) {
+query autocompleteSearchAgent($input: AutocompleteSearchUserInput!) {
   autocompleteSearchAgent(input: $input) {
     value
     label

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldCustomer/graphql/queries/autocompleteSearch/user.api.ts

@@ -7,7 +7,7 @@ import * as VueCompositionApi from 'vue';
 export type ReactiveFunction<TParam> = () => TParam;
 
 export const AutocompleteSearchUserDocument = gql`
-    query autocompleteSearchUser($input: AutocompleteSearchInput!) {
+    query autocompleteSearchUser($input: AutocompleteSearchUserInput!) {
   autocompleteSearchUser(input: $input) {
     value
     label

+ 1 - 1
app/frontend/shared/components/Form/fields/FieldCustomer/graphql/queries/autocompleteSearch/user.graphql

@@ -1,4 +1,4 @@
-query autocompleteSearchUser($input: AutocompleteSearchInput!) {
+query autocompleteSearchUser($input: AutocompleteSearchUserInput!) {
   autocompleteSearchUser(input: $input) {
     value
     label

Some files were not shown because too many files changed in this diff