From dbf624cd8abe939fc1268770e74506226de335c1 Mon Sep 17 00:00:00 2001 From: Alexander Petkov Date: Wed, 19 Jul 2023 01:16:21 +0300 Subject: [PATCH 1/4] donations/grid: Fix donations association to user --- .../admin/donations/grid/RenderEditBillingEmailCell.tsx | 3 ++- src/components/admin/donations/grid/RenderEditPersonCell.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx b/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx index ac1a28955..cb59126a8 100644 --- a/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx +++ b/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx @@ -35,7 +35,7 @@ export default function RenderEditBillingEmailCell({ const initialPerson = { firstName: params.row.billingEmail, lastName: '', - email: params.row.email || params.row.billingEmail || null, + email: params.row.email || params.row.billingEmail || '', } const [person, setPerson] = React.useState({ ...initialPerson, @@ -59,6 +59,7 @@ export default function RenderEditBillingEmailCell({ const onClick = () => { if (person) { const donationData: UserDonationInput = params.row + donationData.targetPersonId = undefined donationData.billingEmail = person.email mutation.mutate(donationData) } else { diff --git a/src/components/admin/donations/grid/RenderEditPersonCell.tsx b/src/components/admin/donations/grid/RenderEditPersonCell.tsx index 22525f20e..c53805c27 100644 --- a/src/components/admin/donations/grid/RenderEditPersonCell.tsx +++ b/src/components/admin/donations/grid/RenderEditPersonCell.tsx @@ -37,7 +37,7 @@ export default function RenderEditPersonCell({ params.row.person && params.row.person.firstName ? params.row.person.firstName : 'Anonymous', lastName: params.row.person && params.row.person.lastName ? params.row.person.lastName : 'Donor', - email: params.row.email || params.row.billingEmail || null, + email: params.row.email || params.row.billingEmail || '', } const [person, setPerson] = React.useState({ ...initialPerson, @@ -62,6 +62,7 @@ export default function RenderEditPersonCell({ if (person) { const donationData: UserDonationInput = params.row donationData.targetPersonId = person.id + donationData.billingEmail = undefined mutation.mutate(donationData) } else { AlertStore.show(t('donations:alerts.requiredError'), 'error') From 34b2d2c19e1d93d30fd6a244b1a5825d759d20c2 Mon Sep 17 00:00:00 2001 From: Alexander Petkov Date: Wed, 19 Jul 2023 12:38:21 +0300 Subject: [PATCH 2/4] admin/donations: Extend donor's autocomplete to look for email --- .../donations/grid/RenderEditPersonCell.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/components/admin/donations/grid/RenderEditPersonCell.tsx b/src/components/admin/donations/grid/RenderEditPersonCell.tsx index c53805c27..0c9da8585 100644 --- a/src/components/admin/donations/grid/RenderEditPersonCell.tsx +++ b/src/components/admin/donations/grid/RenderEditPersonCell.tsx @@ -4,7 +4,7 @@ import { useMutation } from '@tanstack/react-query' import { useTranslation } from 'next-i18next' import { GridRenderEditCellParams } from '@mui/x-data-grid' import { TextField, Tooltip, Box } from '@mui/material' -import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete' +import Autocomplete from '@mui/material/Autocomplete' import { Save } from '@mui/icons-material' import { PersonResponse } from 'gql/person' import { DonationResponse, UserDonationInput } from 'gql/donations' @@ -87,12 +87,18 @@ export default function RenderEditPersonCell({ )} isOptionEqualToValue={(option, value) => option.firstName === value.firstName} - filterOptions={createFilterOptions({ - matchFrom: 'any', - limit: 5, - ignoreCase: true, - trim: true, - })} + filterOptions={(options, state) => { + const displayOptions = options.filter( + (option) => + option.firstName + .toLowerCase() + .trim() + .includes(state.inputValue.toLowerCase().trim()) || + option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()), + ) + + return displayOptions + }} clearText={t('donations:cta.clear')} noOptionsText={t('donations:noOptions')} openText={t('donations:cta.open')} From 190c76724a44daf81001d0d0da637f8936781c2e Mon Sep 17 00:00:00 2001 From: Alexander Petkov Date: Thu, 20 Jul 2023 12:09:22 +0300 Subject: [PATCH 3/4] admin/donations: Move autocomplete filter to its own function --- .../grid/RenderEditBillingEmailCell.tsx | 14 ++----------- .../donations/grid/RenderEditPersonCell.tsx | 14 ++----------- .../common/person/PersonAutoCompleteFilter.ts | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 24 deletions(-) create mode 100644 src/components/common/person/PersonAutoCompleteFilter.ts diff --git a/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx b/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx index cb59126a8..943428c60 100644 --- a/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx +++ b/src/components/admin/donations/grid/RenderEditBillingEmailCell.tsx @@ -11,6 +11,7 @@ import { DonationResponse, UserDonationInput } from 'gql/donations' import { useEditDonation } from 'service/donation' import { ApiErrors } from 'service/apiErrors' import { AlertStore } from 'stores/AlertStore' +import { personFilter } from 'components/common/person/PersonAutoCompleteFilter' interface RenderEditCellProps { params: GridRenderEditCellParams @@ -87,18 +88,7 @@ export default function RenderEditBillingEmailCell({ )} isOptionEqualToValue={(option, value) => option.email === value.email} - filterOptions={(options, state) => { - const displayOptions = options.filter( - (option) => - option.firstName - .toLowerCase() - .trim() - .includes(state.inputValue.toLowerCase().trim()) || - option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()), - ) - - return displayOptions - }} + filterOptions={personFilter} clearText={t('donations:cta.clear')} noOptionsText={t('donations:noOptions')} openText={t('donations:cta.open')} diff --git a/src/components/admin/donations/grid/RenderEditPersonCell.tsx b/src/components/admin/donations/grid/RenderEditPersonCell.tsx index 0c9da8585..0419c3736 100644 --- a/src/components/admin/donations/grid/RenderEditPersonCell.tsx +++ b/src/components/admin/donations/grid/RenderEditPersonCell.tsx @@ -11,6 +11,7 @@ import { DonationResponse, UserDonationInput } from 'gql/donations' import { useEditDonation } from 'service/donation' import { ApiErrors } from 'service/apiErrors' import { AlertStore } from 'stores/AlertStore' +import { personFilter } from 'components/common/person/PersonAutoCompleteFilter' interface RenderEditCellProps { params: GridRenderEditCellParams @@ -87,18 +88,7 @@ export default function RenderEditPersonCell({ )} isOptionEqualToValue={(option, value) => option.firstName === value.firstName} - filterOptions={(options, state) => { - const displayOptions = options.filter( - (option) => - option.firstName - .toLowerCase() - .trim() - .includes(state.inputValue.toLowerCase().trim()) || - option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()), - ) - - return displayOptions - }} + filterOptions={personFilter} clearText={t('donations:cta.clear')} noOptionsText={t('donations:noOptions')} openText={t('donations:cta.open')} diff --git a/src/components/common/person/PersonAutoCompleteFilter.ts b/src/components/common/person/PersonAutoCompleteFilter.ts new file mode 100644 index 000000000..f35d08501 --- /dev/null +++ b/src/components/common/person/PersonAutoCompleteFilter.ts @@ -0,0 +1,21 @@ +import { PersonResponse } from 'gql/person' +import { FilterOptionsState } from '@mui/material' + +/** + * Custom function to filter person related autocomplete inputs, based on either firstname or email + * @param options AutoComplete prop + * @param state AutoComplete prop + * @returns + */ +export const personFilter = ( + options: PersonResponse[], + state: FilterOptionsState, +) => { + const displayOptions = options.filter( + (option) => + option.firstName.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()) || + option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()), + ) + + return displayOptions +} From 07f1ffc6124fea4a352ecf9750ca9f9e9368b50b Mon Sep 17 00:00:00 2001 From: Alexander Petkov Date: Thu, 20 Jul 2023 12:18:19 +0300 Subject: [PATCH 4/4] personFilter: Expand filter rules to look for last name --- .../common/person/PersonAutoCompleteFilter.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/common/person/PersonAutoCompleteFilter.ts b/src/components/common/person/PersonAutoCompleteFilter.ts index f35d08501..38eedbab9 100644 --- a/src/components/common/person/PersonAutoCompleteFilter.ts +++ b/src/components/common/person/PersonAutoCompleteFilter.ts @@ -2,7 +2,7 @@ import { PersonResponse } from 'gql/person' import { FilterOptionsState } from '@mui/material' /** - * Custom function to filter person related autocomplete inputs, based on either firstname or email + * Custom function to filter person related autocomplete inputs, based on either firstname, lastname or email * @param options AutoComplete prop * @param state AutoComplete prop * @returns @@ -11,11 +11,13 @@ export const personFilter = ( options: PersonResponse[], state: FilterOptionsState, ) => { - const displayOptions = options.filter( - (option) => - option.firstName.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()) || - option.email.toLowerCase().trim().includes(state.inputValue.toLowerCase().trim()), - ) + const displayOptions = options.filter((option) => { + const name = `${option.firstName.toLowerCase()} ${option.lastName.toLowerCase()}` + return ( + name.includes(state.inputValue.toLowerCase()) || + option.email.toLowerCase().includes(state.inputValue.toLowerCase()) + ) + }) return displayOptions }