Skip to content

Commit e8bcbde

Browse files
committed
Add "Created by" filter to Expected Funds
1 parent 7b0fadc commit e8bcbde

File tree

8 files changed

+463
-52
lines changed

8 files changed

+463
-52
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import { defineMessage } from 'react-intl';
3+
import { z } from 'zod';
4+
5+
import type { FilterComponentProps, FilterConfig } from '@/lib/filters/filter-types';
6+
import { isMulti } from '@/lib/filters/schemas';
7+
import type { AccountHoverCardFieldsFragment } from '@/lib/graphql/types/v2/graphql';
8+
9+
import ComboSelectFilter from './ComboSelectFilter';
10+
import { AccountRenderer } from './HostedAccountFilter';
11+
12+
type FilterMeta = {
13+
createdByUsers?: Partial<AccountHoverCardFieldsFragment>[];
14+
};
15+
16+
const schema = isMulti(z.string()).optional();
17+
18+
const resultNodeToOption = (account: Partial<AccountHoverCardFieldsFragment>) => ({
19+
label: <AccountRenderer account={account as AccountHoverCardFieldsFragment & { slug: string }} inOptionsList />,
20+
keywords: [account.name],
21+
value: account.slug,
22+
});
23+
24+
function CreatedByFilter({ meta, ...props }: FilterComponentProps<z.infer<typeof schema>, FilterMeta>) {
25+
const options = React.useMemo(() => meta?.createdByUsers?.map(resultNodeToOption) || [], [meta?.createdByUsers]);
26+
27+
return <ComboSelectFilter options={options} isMulti {...props} />;
28+
}
29+
30+
export const createdByFilter: FilterConfig<z.infer<typeof schema>> = {
31+
schema: schema,
32+
filter: {
33+
labelMsg: defineMessage({ defaultMessage: 'Created by', id: 'Agreement.createdBy' }),
34+
Component: CreatedByFilter,
35+
valueRenderer: ({ value, ...props }) => <AccountRenderer account={{ slug: value }} {...props} />,
36+
},
37+
toVariables: (values, key) => ({ [key]: values.map(slug => ({ slug })) }),
38+
};

components/dashboard/filters/HostedAccountFilter.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,21 @@ const hostedAccountFilterSearchQuery = gql`
2727
${accountHoverCardFields}
2828
`;
2929

30-
export const AccountRenderer = ({
31-
account,
32-
inOptionsList,
33-
}: {
30+
export const AccountRenderer = (props: {
3431
account: Partial<AccountHoverCardFieldsFragment> & {
3532
slug: Account['slug'];
3633
};
3734
inOptionsList?: boolean; // For positioning the HoverCard to the right to prevent blocking options list
3835
}) => {
3936
const { data } = useQuery<AccountFilterQuery>(accountFilterQuery, {
40-
variables: { slug: account.slug },
37+
variables: { slug: props.account.slug },
4138
fetchPolicy: 'cache-first',
4239

4340
// skip query if there is already a field from the hover card data (such as description),
4441
// to prevent fetching all accounts when used in the combo select filter that already queries for these fields
45-
skip: !!account.description && !!account.type,
42+
skip: !!props.account.description && !!props.account.type,
4643
});
44+
const account = data?.account ?? props.account;
4745

4846
const trigger = (
4947
<div className="flex h-full w-full max-w-48 items-center justify-between gap-2 overflow-hidden">
@@ -61,7 +59,7 @@ export const AccountRenderer = ({
6159
return (
6260
<AccountHoverCard
6361
account={data.account}
64-
{...(inOptionsList && { hoverCardContentProps: { side: 'right', sideOffset: 24 } })}
62+
{...(props.inOptionsList && { hoverCardContentProps: { side: 'right', sideOffset: 24 } })}
6563
trigger={trigger}
6664
/>
6765
);

components/dashboard/sections/contributions/HostExpectedFunds.tsx

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,27 @@ import type { z } from 'zod';
66

77
import type { FilterComponentConfigs, FiltersToVariables, Views } from '../../../../lib/filters/filter-types';
88
import { gql } from '../../../../lib/graphql/helpers';
9+
import type {
10+
AccountHoverCardFieldsFragment,
11+
DashboardOrdersQueryVariables,
12+
} from '../../../../lib/graphql/types/v2/graphql';
913
import { ExpectedFundsFilter, OrderStatus } from '../../../../lib/graphql/types/v2/schema';
1014
import useQueryFilter from '../../../../lib/hooks/useQueryFilter';
1115
import { FEATURES, requiresUpgrade } from '@/lib/allowed-features';
12-
import type { DashboardOrdersQueryVariables } from '@/lib/graphql/types/v2/graphql';
1316

1417
import { UpgradePlanCTA } from '@/components/platform-subscriptions/UpgradePlanCTA';
1518

19+
import { accountHoverCardFields } from '../../../AccountHoverCard';
1620
import { Button } from '../../../ui/Button';
1721
import { DashboardContext } from '../../DashboardContext';
1822
import DashboardHeader from '../../DashboardHeader';
23+
import { createdByFilter } from '../../filters/CreatedByFilter';
1924
import { expectedDateFilter } from '../../filters/DateFilter';
2025
import type { DashboardSectionProps } from '../../types';
2126

2227
import ContributionsTable from './ContributionsTable';
2328
import CreatePendingContributionModal from './CreatePendingOrderModal';
24-
import type { FilterMeta } from './filters';
29+
import type { FilterMeta as BaseFilterMeta } from './filters';
2530
import {
2631
ContributionAccountingCategoryKinds,
2732
filters as baseFilters,
@@ -39,7 +44,7 @@ enum ContributionsTab {
3944
}
4045

4146
const hostExpectedFundsMetadataQuery = gql`
42-
query HostExpectedFundsMetadata($slug: String!, $expectedFundsFilter: ExpectedFundsFilter) {
47+
query HostExpectedFundsMetadata($slug: String!) {
4348
account(slug: $slug) {
4449
id
4550
slug
@@ -58,25 +63,15 @@ const hostExpectedFundsMetadataQuery = gql`
5863
hostFeePercent
5964
}
6065
}
61-
PENDING: orders(
62-
filter: INCOMING
63-
expectedFundsFilter: $expectedFundsFilter
64-
status: [PENDING]
65-
hostContext: ALL
66-
) {
66+
PENDING: orders(filter: INCOMING, expectedFundsFilter: ONLY_PENDING, status: [PENDING], hostContext: ALL) {
6767
totalCount
6868
}
69-
EXPIRED: orders(
70-
filter: INCOMING
71-
expectedFundsFilter: $expectedFundsFilter
72-
status: [EXPIRED]
73-
hostContext: ALL
74-
) {
69+
EXPIRED: orders(filter: INCOMING, expectedFundsFilter: ONLY_PENDING, status: [EXPIRED], hostContext: ALL) {
7570
totalCount
7671
}
7772
PAID: orders(
7873
filter: INCOMING
79-
expectedFundsFilter: $expectedFundsFilter
74+
expectedFundsFilter: ONLY_PENDING
8075
status: [PAID]
8176
includeIncognito: true
8277
hostContext: ALL
@@ -85,28 +80,45 @@ const hostExpectedFundsMetadataQuery = gql`
8580
}
8681
CANCELED: orders(
8782
filter: INCOMING
88-
expectedFundsFilter: $expectedFundsFilter
83+
expectedFundsFilter: ONLY_PENDING
8984
status: [CANCELLED]
9085
includeIncognito: true
9186
hostContext: ALL
9287
) {
9388
totalCount
9489
}
90+
orders(filter: INCOMING, expectedFundsFilter: ONLY_PENDING, hostContext: ALL) {
91+
createdByUsers {
92+
id
93+
...AccountHoverCardFields
94+
}
95+
}
9596
}
9697
}
98+
${accountHoverCardFields}
9799
`;
98100

99101
const schema = baseSchema.extend({
100102
expectedDate: expectedDateFilter.schema,
103+
createdBy: createdByFilter.schema,
101104
});
105+
106+
type FilterMeta = BaseFilterMeta & {
107+
createdByUsers?: Partial<AccountHoverCardFieldsFragment>[];
108+
};
109+
102110
type FilterValues = z.infer<typeof schema>;
111+
103112
const toVariables: FiltersToVariables<FilterValues, DashboardOrdersQueryVariables, FilterMeta> = {
104-
...baseToVariables,
113+
...(baseToVariables as FiltersToVariables<FilterValues, DashboardOrdersQueryVariables, FilterMeta>),
105114
expectedDate: expectedDateFilter.toVariables,
115+
createdBy: createdByFilter.toVariables,
106116
};
117+
107118
const filters: FilterComponentConfigs<FilterValues, FilterMeta> = {
108119
...baseFilters,
109120
expectedDate: expectedDateFilter.filter,
121+
createdBy: createdByFilter.filter,
110122
};
111123

112124
function HostExpectedFunds({ accountSlug }: DashboardSectionProps) {
@@ -116,6 +128,12 @@ function HostExpectedFunds({ accountSlug }: DashboardSectionProps) {
116128
const isUpgradeRequired = requiresUpgrade(account, FEATURES.EXPECTED_FUNDS);
117129
const [showCreatePendingOrderModal, setShowCreatePendingOrderModal] = React.useState(false);
118130

131+
const { data: metadata, refetch: refetchMetadata } = useQuery(hostExpectedFundsMetadataQuery, {
132+
variables: { slug: accountSlug },
133+
fetchPolicy: typeof window !== 'undefined' ? 'cache-and-network' : 'cache-first',
134+
skip: isUpgradeRequired,
135+
});
136+
119137
const views: Views<z.infer<typeof schema>> = [
120138
{
121139
id: ContributionsTab.ALL,
@@ -158,6 +176,7 @@ function HostExpectedFunds({ accountSlug }: DashboardSectionProps) {
158176
hostSlug: account.isHost ? account.slug : undefined,
159177
includeUncategorized: true,
160178
accountingCategoryKinds: ContributionAccountingCategoryKinds,
179+
createdByUsers: metadata?.account?.orders?.createdByUsers,
161180
};
162181

163182
const queryFilter = useQueryFilter({
@@ -168,16 +187,6 @@ function HostExpectedFunds({ accountSlug }: DashboardSectionProps) {
168187
filters,
169188
});
170189

171-
const { data: metadata, refetch: refetchMetadata } = useQuery(hostExpectedFundsMetadataQuery, {
172-
variables: {
173-
slug: accountSlug,
174-
expectedFundsFilter: ExpectedFundsFilter.ONLY_PENDING,
175-
},
176-
177-
fetchPolicy: typeof window !== 'undefined' ? 'cache-and-network' : 'cache-first',
178-
skip: isUpgradeRequired,
179-
});
180-
181190
const { data, loading, error, refetch } = useQuery(dashboardOrdersQuery, {
182191
variables: {
183192
slug: accountSlug,

components/dashboard/sections/contributions/queries.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const dashboardOrdersQuery = gql`
2828
$expectedFundsFilter: ExpectedFundsFilter
2929
$orderBy: ChronologicalOrderInput
3030
$tier: [TierReferenceInput!]
31+
$createdBy: [AccountReferenceInput]
3132
) {
3233
account(slug: $slug) {
3334
id
@@ -55,6 +56,7 @@ export const dashboardOrdersQuery = gql`
5556
chargedDateFrom: $chargedDateFrom
5657
chargedDateTo: $chargedDateTo
5758
tier: $tier
59+
createdBy: $createdBy
5860
) {
5961
totalCount
6062
nodes {

0 commit comments

Comments
 (0)