diff --git a/components/dashboard/sections/contributions/Contributions.tsx b/components/dashboard/sections/contributions/Contributions.tsx index 7c85c0772d6..df465a121aa 100644 --- a/components/dashboard/sections/contributions/Contributions.tsx +++ b/components/dashboard/sections/contributions/Contributions.tsx @@ -75,6 +75,7 @@ const dashboardContributionsMetadataQuery = gql` $onlyExpectedFunds: Boolean! $expectedFundsFilter: ExpectedFundsFilter $includeHostedAccounts: Boolean! + $includeChildrenAccounts: Boolean ) { account(slug: $slug) { id @@ -85,6 +86,22 @@ const dashboardContributionsMetadataQuery = gql` settings imageUrl currency + childrenAccounts { + totalCount + nodes { + id + slug + name + ... on AccountWithContributions { + tiers { + nodes { + id + name + } + } + } + } + } ... on AccountWithContributions { canStartResumeContributionsProcess hasResumeContributionsProcessStarted @@ -116,6 +133,7 @@ const dashboardContributionsMetadataQuery = gql` filter: $filter expectedFundsFilter: $expectedFundsFilter includeHostedAccounts: $includeHostedAccounts + includeChildrenAccounts: $includeChildrenAccounts ) { totalCount } @@ -141,6 +159,7 @@ const dashboardContributionsMetadataQuery = gql` status: [ACTIVE, ERROR] includeIncognito: true includeHostedAccounts: $includeHostedAccounts + includeChildrenAccounts: $includeChildrenAccounts ) @skip(if: $onlyExpectedFunds) { totalCount } @@ -160,6 +179,7 @@ const dashboardContributionsMetadataQuery = gql` includeIncognito: true minAmount: 1 includeHostedAccounts: $includeHostedAccounts + includeChildrenAccounts: $includeChildrenAccounts ) @skip(if: $onlyExpectedFunds) { totalCount } @@ -169,6 +189,7 @@ const dashboardContributionsMetadataQuery = gql` includeIncognito: true expectedFundsFilter: $expectedFundsFilter includeHostedAccounts: $includeHostedAccounts + includeChildrenAccounts: $includeChildrenAccounts ) { totalCount } @@ -224,6 +245,7 @@ const dashboardContributionsQuery = gql` $maxAmount: Int $paymentMethod: PaymentMethodReferenceInput $includeHostedAccounts: Boolean! + $includeChildrenAccounts: Boolean $dateFrom: DateTime $dateTo: DateTime $expectedDateFrom: DateTime @@ -252,6 +274,7 @@ const dashboardContributionsQuery = gql` limit: $limit paymentMethod: $paymentMethod includeHostedAccounts: $includeHostedAccounts + includeChildrenAccounts: $includeChildrenAccounts expectedFundsFilter: $expectedFundsFilter orderBy: $orderBy chargedDateFrom: $chargedDateFrom @@ -269,33 +292,35 @@ const dashboardContributionsQuery = gql` ${managedOrderFragment} `; -const getColumns = ({ intl, isIncoming, includeHostedAccounts, onlyExpectedFunds }) => { - const accounts = { +const getColumns = ({ intl, isIncoming, includeHostedAccounts, includeChildrenAccounts, onlyExpectedFunds }) => { + const accounts = swap => ({ accessorKey: 'toAccount', header: intl.formatMessage({ defaultMessage: 'Collective & Contributors', id: 'kklCrk' }), meta: { className: 'max-w-[400px] overflow-hidden' }, cell: ({ cell, row }) => { const toAccount = cell.getValue(); const fromAccount = row.original.fromAccount; + const big = swap ? fromAccount : toAccount; + const small = swap ? toAccount : fromAccount; return (
- + } />
- + } /> @@ -303,16 +328,16 @@ const getColumns = ({ intl, isIncoming, includeHostedAccounts, onlyExpectedFunds
- {toAccount.name || toAccount.slug} + {big.name || big.slug}
- {fromAccount.name || fromAccount.slug} + {small.name || small.slug}
); }, - }; + }); const toAccount = { accessorKey: 'toAccount', @@ -487,7 +512,11 @@ const getColumns = ({ intl, isIncoming, includeHostedAccounts, onlyExpectedFunds return compact([ onlyExpectedFunds ? contributionId : null, - includeHostedAccounts ? accounts : isIncoming ? fromAccount : toAccount, + includeHostedAccounts || includeChildrenAccounts + ? accounts(isIncoming && includeChildrenAccounts) + : isIncoming + ? fromAccount + : toAccount, chargeDate, amount, frequency, @@ -509,9 +538,16 @@ type ContributionsProps = DashboardSectionProps & { direction?: 'INCOMING' | 'OUTGOING'; onlyExpectedFunds?: boolean; includeHostedAccounts?: boolean; + includeChildrenAccounts?: boolean; }; -const Contributions = ({ accountSlug, direction, onlyExpectedFunds, includeHostedAccounts }: ContributionsProps) => { +const Contributions = ({ + accountSlug, + direction, + onlyExpectedFunds, + includeHostedAccounts, + includeChildrenAccounts, +}: ContributionsProps) => { const { toast } = useToast(); const [expireOrder] = useMutation( @@ -559,6 +595,7 @@ const Contributions = ({ accountSlug, direction, onlyExpectedFunds, includeHoste onlyExpectedFunds: !!onlyExpectedFunds, expectedFundsFilter: onlyExpectedFunds ? ExpectedFundsFilter.ALL_EXPECTED_FUNDS : null, includeHostedAccounts: !!includeHostedAccounts, + includeChildrenAccounts: !!includeChildrenAccounts, }, context: API_V2_CONTEXT, fetchPolicy: typeof window !== 'undefined' ? 'cache-and-network' : 'cache-first', @@ -688,9 +725,23 @@ const Contributions = ({ accountSlug, direction, onlyExpectedFunds, includeHoste : null, ].filter(Boolean); + const tierOptions = React.useMemo(() => { + if (metadata?.account.childrenAccounts.nodes?.length === 0) { + return metadata.account?.tiers?.nodes.map(tier => ({ label: tier.name, value: tier.id })); + } else { + const makeOption = account => + account?.tiers?.nodes.map(tier => ({ label: `${tier.name} (${account.name})`, value: tier.id })); + const options = makeOption(metadata?.account); + metadata?.account.childrenAccounts.nodes.forEach(children => { + options.push(...makeOption(children)); + }); + return options; + } + }, [metadata?.account]); + const filterMeta: FilterMeta = { currency: metadata?.account?.currency, - tiers: isIncoming ? metadata?.account?.tiers?.nodes : [], + tierOptions: isIncoming ? tierOptions : [], }; const queryFilter = useQueryFilter({ @@ -716,6 +767,7 @@ const Contributions = ({ accountSlug, direction, onlyExpectedFunds, includeHoste filter: direction || 'OUTGOING', includeIncognito: true, includeHostedAccounts: !!includeHostedAccounts, + includeChildrenAccounts: !!includeChildrenAccounts, ...queryFilter.variables, ...(onlyExpectedFunds ? { @@ -759,6 +811,7 @@ const Contributions = ({ accountSlug, direction, onlyExpectedFunds, includeHoste intl, isIncoming, includeHostedAccounts, + includeChildrenAccounts, onlyExpectedFunds, }); const currentViewCount = views.find(v => v.id === queryFilter.activeViewId)?.count; diff --git a/components/dashboard/sections/contributions/IncomingContributions.tsx b/components/dashboard/sections/contributions/IncomingContributions.tsx index fd8aea7babe..4ba07f1dfe9 100644 --- a/components/dashboard/sections/contributions/IncomingContributions.tsx +++ b/components/dashboard/sections/contributions/IncomingContributions.tsx @@ -5,7 +5,7 @@ import type { DashboardSectionProps } from '../../types'; import Contributions from './Contributions'; const IncomingContributions = (props: DashboardSectionProps) => { - return ; + return ; }; export default IncomingContributions; diff --git a/components/dashboard/sections/contributions/filters.tsx b/components/dashboard/sections/contributions/filters.tsx index a01e6fb1051..b975b792456 100644 --- a/components/dashboard/sections/contributions/filters.tsx +++ b/components/dashboard/sections/contributions/filters.tsx @@ -56,7 +56,7 @@ type FilterValues = z.infer; export type FilterMeta = { currency?: Currency; - tiers?: Array<{ id: string; name: string }>; + tierOptions?: Array<{ label: string; value: string }>; }; type GraphQLQueryVariables = DashboardRecurringContributionsQueryVariables; @@ -103,14 +103,10 @@ export const filters: FilterComponentConfigs = { }, tier: { labelMsg: defineMessage({ defaultMessage: 'Tier', id: 'b07w+D' }), - Component: ({ meta, ...props }) => ( - ({ label: name, value: id })) ?? []} - isMulti - {...props} - /> - ), - valueRenderer: ({ value, meta }) => meta.tiers?.find(tier => tier.id === value)?.name ?? value, + Component: ({ meta, ...props }) => { + return ; + }, + valueRenderer: ({ value, meta }) => meta.tierOptions?.find(tier => tier.value === value)?.label ?? value, }, frequency: { labelMsg: defineMessage({ id: 'Frequency', defaultMessage: 'Frequency' }),