@blocklet/payment-react 1.16.3 → 1.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/es/checkout/table.js +6 -1
- package/es/components/country-select.d.ts +1 -6
- package/es/components/country-select.js +8 -9
- package/es/components/over-due-invoice-payment.d.ts +38 -0
- package/es/components/over-due-invoice-payment.js +238 -0
- package/es/components/pricing-table.js +3 -5
- package/es/components/table.js +2 -0
- package/es/index.d.ts +2 -1
- package/es/index.js +3 -1
- package/es/locales/en.js +17 -1
- package/es/locales/zh.js +17 -1
- package/es/payment/summary.js +2 -0
- package/lib/checkout/table.js +4 -1
- package/lib/components/country-select.d.ts +1 -6
- package/lib/components/country-select.js +9 -11
- package/lib/components/over-due-invoice-payment.d.ts +38 -0
- package/lib/components/over-due-invoice-payment.js +285 -0
- package/lib/components/pricing-table.js +3 -5
- package/lib/components/table.js +2 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +8 -0
- package/lib/locales/en.js +17 -1
- package/lib/locales/zh.js +17 -1
- package/lib/payment/summary.js +2 -0
- package/package.json +8 -8
- package/src/checkout/table.tsx +6 -1
- package/src/components/country-select.tsx +10 -12
- package/src/components/over-due-invoice-payment.tsx +306 -0
- package/src/components/pricing-table.tsx +4 -6
- package/src/components/table.tsx +2 -0
- package/src/index.ts +2 -0
- package/src/locales/en.tsx +18 -0
- package/src/locales/zh.tsx +18 -0
- package/src/payment/summary.tsx +2 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { Button, Typography, Stack, CircularProgress, Alert } from '@mui/material';
|
|
3
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
4
|
+
import Toast from '@arcblock/ux/lib/Toast';
|
|
5
|
+
import { joinURL } from 'ufo';
|
|
6
|
+
import type { Invoice, PaymentCurrency, PaymentMethod, Subscription, TInvoiceExpanded } from '@blocklet/payment-types';
|
|
7
|
+
import { useRequest } from 'ahooks';
|
|
8
|
+
import { Dialog } from '@arcblock/ux';
|
|
9
|
+
import { usePaymentContext } from '../contexts/payment';
|
|
10
|
+
import { formatAmount, formatError, getPrefix } from '../libs/util';
|
|
11
|
+
import { useSubscription } from '../hooks/subscription';
|
|
12
|
+
import api from '../libs/api';
|
|
13
|
+
|
|
14
|
+
type DialogProps = {
|
|
15
|
+
open?: boolean;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
title?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type Props = {
|
|
21
|
+
subscriptionId: string;
|
|
22
|
+
mode?: 'default' | 'custom';
|
|
23
|
+
onPaid?: (subscriptionId: string, currencyId: string) => void;
|
|
24
|
+
dialogProps?: DialogProps;
|
|
25
|
+
children?: (
|
|
26
|
+
handlePay: (item: SummaryItem) => void,
|
|
27
|
+
data: {
|
|
28
|
+
subscription: Subscription;
|
|
29
|
+
summary: { [key: string]: SummaryItem };
|
|
30
|
+
invoices: Invoice[];
|
|
31
|
+
subscriptionUrl: string;
|
|
32
|
+
}
|
|
33
|
+
) => React.ReactNode;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type SummaryItem = {
|
|
37
|
+
amount: string;
|
|
38
|
+
currency: PaymentCurrency;
|
|
39
|
+
method: PaymentMethod;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const fetchOverdueInvoices = async (
|
|
43
|
+
subscriptionId: string
|
|
44
|
+
): Promise<{
|
|
45
|
+
subscription: Subscription;
|
|
46
|
+
summary: { [key: string]: SummaryItem };
|
|
47
|
+
invoices: Invoice[];
|
|
48
|
+
}> => {
|
|
49
|
+
const res = await api.get(`/api/subscriptions/${subscriptionId}/overdue/invoices`);
|
|
50
|
+
return res.data;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function OverdueInvoicePayment({
|
|
54
|
+
subscriptionId,
|
|
55
|
+
mode = 'default',
|
|
56
|
+
dialogProps = {},
|
|
57
|
+
children,
|
|
58
|
+
onPaid = () => {},
|
|
59
|
+
}: Props) {
|
|
60
|
+
const { t } = useLocaleContext();
|
|
61
|
+
const { connect } = usePaymentContext();
|
|
62
|
+
const [selectCurrencyId, setSelectCurrencyId] = useState('');
|
|
63
|
+
const [payLoading, setPayLoading] = useState(false);
|
|
64
|
+
const [dialogOpen, setDialogOpen] = useState(dialogProps.open || false);
|
|
65
|
+
const [processedCurrencies, setProcessedCurrencies] = useState<{ [key: string]: number }>({});
|
|
66
|
+
const {
|
|
67
|
+
data = {
|
|
68
|
+
subscription: {} as Subscription,
|
|
69
|
+
summary: {},
|
|
70
|
+
invoices: [],
|
|
71
|
+
},
|
|
72
|
+
error,
|
|
73
|
+
loading,
|
|
74
|
+
runAsync: refresh,
|
|
75
|
+
} = useRequest(() => fetchOverdueInvoices(subscriptionId));
|
|
76
|
+
|
|
77
|
+
const subscriptionUrl = joinURL(getPrefix(), `/customer/subscription/${subscriptionId}`);
|
|
78
|
+
const summaryList = useMemo(() => {
|
|
79
|
+
if (!data?.summary) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
return Object.values(data.summary);
|
|
83
|
+
}, [data?.summary]);
|
|
84
|
+
|
|
85
|
+
const subscription = useSubscription('events');
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (subscription) {
|
|
88
|
+
subscription.on('invoice.paid', ({ response }: { response: TInvoiceExpanded }) => {
|
|
89
|
+
const uniqueKey = `${response.subscription_id}-${response.currency_id}`;
|
|
90
|
+
if (response.subscription_id === subscriptionId && !processedCurrencies[uniqueKey]) {
|
|
91
|
+
Toast.success(t('payment.customer.invoice.paySuccess'));
|
|
92
|
+
setPayLoading(false);
|
|
93
|
+
setProcessedCurrencies({ ...processedCurrencies, [uniqueKey]: 1 });
|
|
94
|
+
refresh().then((res) => {
|
|
95
|
+
if (res.invoices?.length === 0) {
|
|
96
|
+
setDialogOpen(false);
|
|
97
|
+
onPaid(subscriptionId, response.currency_id);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
104
|
+
}, [subscription]);
|
|
105
|
+
|
|
106
|
+
const handlePay = (item: SummaryItem) => {
|
|
107
|
+
const { currency, method } = item;
|
|
108
|
+
if (method.type === 'stripe') {
|
|
109
|
+
Toast.error(t('payment.subscription.overdue.notSupport'));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (payLoading) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
setSelectCurrencyId(currency.id);
|
|
116
|
+
setPayLoading(true);
|
|
117
|
+
if (method.type === 'arcblock' || method.type === 'ethereum') {
|
|
118
|
+
connect.open({
|
|
119
|
+
containerEl: undefined as unknown as Element,
|
|
120
|
+
saveConnect: false,
|
|
121
|
+
action: 'collect-batch',
|
|
122
|
+
prefix: joinURL('/api/did'),
|
|
123
|
+
extraParams: { currencyId: currency.id, subscriptionId },
|
|
124
|
+
onSuccess: () => {
|
|
125
|
+
connect.close();
|
|
126
|
+
},
|
|
127
|
+
onClose: () => {
|
|
128
|
+
connect.close();
|
|
129
|
+
setPayLoading(false);
|
|
130
|
+
},
|
|
131
|
+
onError: (err: any) => {
|
|
132
|
+
Toast.error(formatError(err));
|
|
133
|
+
setPayLoading(false);
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (loading) {
|
|
140
|
+
return <CircularProgress />;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const renderPayButton = (item: SummaryItem, props: any) => {
|
|
144
|
+
const isPayLoading = payLoading && item.currency.id === selectCurrencyId;
|
|
145
|
+
if (item.method.type === 'stripe') {
|
|
146
|
+
return (
|
|
147
|
+
<Button variant="contained" color="primary" onClick={() => window.open(subscriptionUrl, '_blank')} {...props}>
|
|
148
|
+
{t('payment.subscription.overdue.viewNow')}
|
|
149
|
+
</Button>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return (
|
|
153
|
+
<Button variant="contained" color="primary" onClick={() => handlePay(item)} {...props} disabled={isPayLoading}>
|
|
154
|
+
{isPayLoading && <CircularProgress size={14} sx={{ mr: 1, color: 'text.lighter' }} />}
|
|
155
|
+
{t('payment.subscription.overdue.payNow')}
|
|
156
|
+
</Button>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (mode === 'custom' && children && typeof children === 'function') {
|
|
161
|
+
return (
|
|
162
|
+
<Stack>
|
|
163
|
+
{children(handlePay, {
|
|
164
|
+
subscription: data?.subscription as Subscription,
|
|
165
|
+
subscriptionUrl,
|
|
166
|
+
summary: data?.summary as { [key: string]: SummaryItem },
|
|
167
|
+
invoices: data?.invoices as Invoice[],
|
|
168
|
+
})}
|
|
169
|
+
</Stack>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Default mode
|
|
174
|
+
return (
|
|
175
|
+
<Dialog
|
|
176
|
+
open={dialogOpen}
|
|
177
|
+
onClose={() => setDialogOpen(false)}
|
|
178
|
+
title={dialogProps.title || t('payment.subscription.overdue.pastDue')}
|
|
179
|
+
PaperProps={{
|
|
180
|
+
style: { minHeight: 'auto' },
|
|
181
|
+
}}>
|
|
182
|
+
{error ? (
|
|
183
|
+
<Alert severity="error">{error.message}</Alert>
|
|
184
|
+
) : (
|
|
185
|
+
<Stack gap={1}>
|
|
186
|
+
{summaryList.length === 0 && (
|
|
187
|
+
<>
|
|
188
|
+
<Alert severity="success">
|
|
189
|
+
{t('payment.subscription.overdue.empty', {
|
|
190
|
+
// @ts-ignore
|
|
191
|
+
name: data?.subscription?.description,
|
|
192
|
+
})}
|
|
193
|
+
</Alert>
|
|
194
|
+
<Stack direction="row" justifyContent="flex-end" mt={2}>
|
|
195
|
+
<Button
|
|
196
|
+
variant="outlined"
|
|
197
|
+
color="primary"
|
|
198
|
+
onClick={() => setDialogOpen(false)}
|
|
199
|
+
sx={{ width: 'fit-content' }}>
|
|
200
|
+
{/* @ts-ignore */}
|
|
201
|
+
{t('common.know')}
|
|
202
|
+
</Button>
|
|
203
|
+
</Stack>
|
|
204
|
+
</>
|
|
205
|
+
)}
|
|
206
|
+
{summaryList.length === 1 && (
|
|
207
|
+
<>
|
|
208
|
+
<Typography color="text.secondary" variant="body1">
|
|
209
|
+
{t('payment.subscription.overdue.title', {
|
|
210
|
+
// @ts-ignore
|
|
211
|
+
name: data?.subscription?.description,
|
|
212
|
+
count: data?.invoices?.length,
|
|
213
|
+
total: formatAmount(summaryList[0]?.amount, summaryList[0]?.currency?.decimal),
|
|
214
|
+
symbol: summaryList[0]?.currency?.symbol,
|
|
215
|
+
})}
|
|
216
|
+
<br />
|
|
217
|
+
{t('payment.subscription.overdue.description')}
|
|
218
|
+
<a
|
|
219
|
+
href={subscriptionUrl}
|
|
220
|
+
target="_blank"
|
|
221
|
+
rel="noreferrer"
|
|
222
|
+
style={{ color: 'var(--foregrounds-fg-interactive, 0086FF)' }}>
|
|
223
|
+
{t('payment.subscription.overdue.view')}
|
|
224
|
+
</a>
|
|
225
|
+
</Typography>
|
|
226
|
+
<Stack direction="row" justifyContent="flex-end" gap={2} mt={2}>
|
|
227
|
+
<Button variant="outlined" color="primary" onClick={() => setDialogOpen(false)}>
|
|
228
|
+
{/* @ts-ignore */}
|
|
229
|
+
{t('common.cancel')}
|
|
230
|
+
</Button>
|
|
231
|
+
{/* @ts-ignore */}
|
|
232
|
+
{renderPayButton(summaryList[0])}
|
|
233
|
+
</Stack>
|
|
234
|
+
</>
|
|
235
|
+
)}
|
|
236
|
+
{summaryList.length > 1 && (
|
|
237
|
+
<>
|
|
238
|
+
<Typography color="text.secondary" variant="body1">
|
|
239
|
+
{/* @ts-ignore */}
|
|
240
|
+
{t('payment.subscription.overdue.simpleTitle', {
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
name: data?.subscription?.description,
|
|
243
|
+
count: data?.invoices?.length,
|
|
244
|
+
})}
|
|
245
|
+
<br />
|
|
246
|
+
{t('payment.subscription.overdue.description')}
|
|
247
|
+
<a
|
|
248
|
+
href={subscriptionUrl}
|
|
249
|
+
target="_blank"
|
|
250
|
+
rel="noreferrer"
|
|
251
|
+
style={{ color: 'var(--foregrounds-fg-interactive, 0086FF)' }}>
|
|
252
|
+
{t('payment.subscription.overdue.view')}
|
|
253
|
+
</a>
|
|
254
|
+
</Typography>
|
|
255
|
+
<Typography color="text.secondary" variant="body1">
|
|
256
|
+
{t('payment.subscription.overdue.list')}
|
|
257
|
+
</Typography>
|
|
258
|
+
<Stack>
|
|
259
|
+
{summaryList.map((item: any) => (
|
|
260
|
+
<Stack
|
|
261
|
+
key={item?.currency?.id}
|
|
262
|
+
direction="row"
|
|
263
|
+
justifyContent="space-between"
|
|
264
|
+
alignItems="center"
|
|
265
|
+
sx={{
|
|
266
|
+
py: 1,
|
|
267
|
+
px: 0.5,
|
|
268
|
+
borderBottom: '1px solid var(--foregrounds-fg-border, #E0E0E0)',
|
|
269
|
+
'&:hover': {
|
|
270
|
+
background: 'var(--backgrounds-bg-highlight, #eff6ff)',
|
|
271
|
+
},
|
|
272
|
+
mt: 0,
|
|
273
|
+
}}>
|
|
274
|
+
<Typography>
|
|
275
|
+
{t('payment.subscription.overdue.total', {
|
|
276
|
+
total: formatAmount(item?.amount, item?.currency?.decimal),
|
|
277
|
+
currency: item?.currency?.symbol,
|
|
278
|
+
})}
|
|
279
|
+
</Typography>
|
|
280
|
+
{renderPayButton(item, {
|
|
281
|
+
variant: 'text',
|
|
282
|
+
sx: {
|
|
283
|
+
color: 'text.link',
|
|
284
|
+
},
|
|
285
|
+
})}
|
|
286
|
+
</Stack>
|
|
287
|
+
))}
|
|
288
|
+
</Stack>
|
|
289
|
+
</>
|
|
290
|
+
)}
|
|
291
|
+
</Stack>
|
|
292
|
+
)}
|
|
293
|
+
</Dialog>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
OverdueInvoicePayment.defaultProps = {
|
|
298
|
+
mode: 'default',
|
|
299
|
+
onPaid: () => {},
|
|
300
|
+
dialogProps: {
|
|
301
|
+
open: true,
|
|
302
|
+
},
|
|
303
|
+
children: null,
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export default OverdueInvoicePayment;
|
|
@@ -198,13 +198,13 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
198
198
|
// }
|
|
199
199
|
}
|
|
200
200
|
@media (min-width: ${({ theme }) => theme.breakpoints.values.md}px) {
|
|
201
|
-
.price-table-wrap:has(> div:nth-
|
|
201
|
+
.price-table-wrap:has(> div:nth-of-type(1)) {
|
|
202
202
|
max-width: 360px !important;
|
|
203
203
|
}
|
|
204
|
-
.price-table-wrap:has(> div:nth-
|
|
204
|
+
.price-table-wrap:has(> div:nth-of-type(2)) {
|
|
205
205
|
max-width: 780px !important;
|
|
206
206
|
}
|
|
207
|
-
.price-table-wrap:has(> div:nth-
|
|
207
|
+
.price-table-wrap:has(> div:nth-of-type(3)) {
|
|
208
208
|
max-width: 1200px !important;
|
|
209
209
|
}
|
|
210
210
|
}
|
|
@@ -500,9 +500,7 @@ function Subscribe({ x, action, onSelect, currencyId }: any) {
|
|
|
500
500
|
}}
|
|
501
501
|
loading={state.loading === x.price_id && !state.loaded}
|
|
502
502
|
disabled={x.is_disabled}
|
|
503
|
-
onClick={() => handleSelect(x.price_id)}
|
|
504
|
-
loadingPosition="end"
|
|
505
|
-
endIcon={null}>
|
|
503
|
+
onClick={() => handleSelect(x.price_id)}>
|
|
506
504
|
{action}
|
|
507
505
|
</LoadingButton>
|
|
508
506
|
);
|
package/src/components/table.tsx
CHANGED
package/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import CountrySelect from './components/country-select';
|
|
|
28
28
|
import TruncatedText from './components/truncated-text';
|
|
29
29
|
import Link from './components/link';
|
|
30
30
|
import { createLazyComponent } from './components/lazy-loader';
|
|
31
|
+
import OverdueInvoicePayment from './components/over-due-invoice-payment';
|
|
31
32
|
|
|
32
33
|
export { PaymentThemeProvider } from './theme';
|
|
33
34
|
|
|
@@ -73,4 +74,5 @@ export {
|
|
|
73
74
|
Table,
|
|
74
75
|
TruncatedText,
|
|
75
76
|
Link,
|
|
77
|
+
OverdueInvoicePayment,
|
|
76
78
|
};
|
package/src/locales/en.tsx
CHANGED
|
@@ -93,6 +93,7 @@ export default flat({
|
|
|
93
93
|
saveAsDefaultPriceSuccess: 'Set default price successfully',
|
|
94
94
|
stakeAmount: 'Stake Amount',
|
|
95
95
|
slashStakeAmount: 'Slash Stake Amount',
|
|
96
|
+
know: 'I know',
|
|
96
97
|
},
|
|
97
98
|
payment: {
|
|
98
99
|
checkout: {
|
|
@@ -330,6 +331,23 @@ export default flat({
|
|
|
330
331
|
rechargeForSubscription: 'Add funds for subscription',
|
|
331
332
|
},
|
|
332
333
|
},
|
|
334
|
+
subscription: {
|
|
335
|
+
overdue: {
|
|
336
|
+
simpleTitle:
|
|
337
|
+
'There are {count} due invoices for your subscription {name}, you need to pay them to activate your subscription or before making new purchases.',
|
|
338
|
+
title:
|
|
339
|
+
'There are {count} due invoices for your subscription {name}, the total due amount is {total} {symbol}, you need to pay them to activate your subscription or before making new purchases.',
|
|
340
|
+
payNow: 'Pay Now',
|
|
341
|
+
notSupport: 'This payment method is not supported',
|
|
342
|
+
total: 'Total {total} {currency}',
|
|
343
|
+
view: 'View Subscription Details',
|
|
344
|
+
viewNow: 'View Now',
|
|
345
|
+
pastDue: 'Past Due Invoices',
|
|
346
|
+
description: 'If you have any questions, you can choose ',
|
|
347
|
+
list: 'Past Due Invoices:',
|
|
348
|
+
empty: 'There are no overdue invoices for your subscription {name}.',
|
|
349
|
+
},
|
|
350
|
+
},
|
|
333
351
|
},
|
|
334
352
|
refund: {
|
|
335
353
|
type: {
|
package/src/locales/zh.tsx
CHANGED
|
@@ -93,6 +93,7 @@ export default flat({
|
|
|
93
93
|
saveAsDefaultPriceSuccess: '设置默认价格成功',
|
|
94
94
|
stakeAmount: '质押金额',
|
|
95
95
|
slashStakeAmount: '罚没金额',
|
|
96
|
+
know: '我知道了',
|
|
96
97
|
},
|
|
97
98
|
payment: {
|
|
98
99
|
checkout: {
|
|
@@ -320,6 +321,23 @@ export default flat({
|
|
|
320
321
|
rechargeForSubscription: '订阅充值',
|
|
321
322
|
},
|
|
322
323
|
},
|
|
324
|
+
subscription: {
|
|
325
|
+
overdue: {
|
|
326
|
+
title:
|
|
327
|
+
'您的【{name}】订阅共有 {count} 张欠费账单,总计 {total} {symbol},您需要支付这些账单以激活您的订阅,或在进行新的购买之前完成支付。',
|
|
328
|
+
simpleTitle:
|
|
329
|
+
'您的【{name}】订阅共有 {count} 张欠费账单,您需要支付这些账单以激活您的订阅,或在进行新的购买之前完成支付。',
|
|
330
|
+
payNow: '立即支付',
|
|
331
|
+
notSupport: '暂不支持该支付方式',
|
|
332
|
+
total: '总计 {total} {currency}',
|
|
333
|
+
view: '查看订阅详情',
|
|
334
|
+
pastDue: '欠费账单',
|
|
335
|
+
viewNow: '立即查看',
|
|
336
|
+
description: '如果您有任何疑问,可以选择 ',
|
|
337
|
+
list: '欠费账单:',
|
|
338
|
+
empty: '您的【{name}】订阅当前没有欠费账单',
|
|
339
|
+
},
|
|
340
|
+
},
|
|
323
341
|
},
|
|
324
342
|
refund: {
|
|
325
343
|
type: {
|
package/src/payment/summary.tsx
CHANGED
|
@@ -252,6 +252,7 @@ export default function PaymentSummary({
|
|
|
252
252
|
<LoadingButton
|
|
253
253
|
size="small"
|
|
254
254
|
loadingPosition="end"
|
|
255
|
+
endIcon={null}
|
|
255
256
|
color="error"
|
|
256
257
|
variant="text"
|
|
257
258
|
loading={state.loading}
|
|
@@ -284,6 +285,7 @@ export default function PaymentSummary({
|
|
|
284
285
|
<LoadingButton
|
|
285
286
|
size="small"
|
|
286
287
|
loadingPosition="end"
|
|
288
|
+
endIcon={null}
|
|
287
289
|
color={crossSellBehavior === 'required' ? 'info' : 'info'}
|
|
288
290
|
variant={crossSellBehavior === 'required' ? 'text' : 'text'}
|
|
289
291
|
loading={state.loading}
|