@huma-finance/widgets 0.0.62-beta.627 → 0.0.62-beta.631
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/dist/cjs/index.cjs +312 -955
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +567 -1187
- package/dist/index.js.map +1 -1
- package/package.json +13 -6
- package/src/components/Lend/addRedemptionV2/2-ChooseAmount.tsx +6 -1
- package/src/components/Lend/solanaCancelRedemption/index.tsx +11 -1
- package/src/components/Lend/solanaSupply/5-Success.tsx +10 -8
- package/src/components/Lend/supplyV2/6-Success.tsx +10 -8
- package/src/components/Lend/supplyV2/7-Notifications.tsx +6 -1
- package/src/components/Notifi/NotifiContextWrapper.tsx +57 -0
- package/src/components/Notifi/NotifiSubscriptionModal.tsx +118 -113
- package/src/components/SuperfluidFactoring/index.tsx +12 -46
- package/src/hooks/useNotifi.ts +28 -17
- package/src/index.tsx +8 -1
- package/src/theme/coreThemeConstants.ts +1 -1
- package/src/components/Activity.tsx +0 -128
- package/src/components/Factoring/FactoredList.tsx +0 -143
- package/src/components/Factoring/UpcomingList.tsx +0 -90
- package/src/components/Factoring/index.ts +0 -2
- package/src/components/HumaTable.tsx +0 -203
- package/src/components/SuperfluidFactoring/SuperfluidFactoredList.tsx +0 -69
- package/src/components/SuperfluidFactoring/SuperfluidUpcomingList.tsx +0 -169
package/src/hooks/useNotifi.ts
CHANGED
|
@@ -8,6 +8,11 @@ import {
|
|
|
8
8
|
NotifiFrontendClient,
|
|
9
9
|
newFrontendClient,
|
|
10
10
|
} from '@notifi-network/notifi-frontend-client'
|
|
11
|
+
import {
|
|
12
|
+
FtuStage,
|
|
13
|
+
useNotifiFrontendClientContext,
|
|
14
|
+
useNotifiUserSettingContext,
|
|
15
|
+
} from '@notifi-network/notifi-react'
|
|
11
16
|
|
|
12
17
|
export const useDoesChainSupportNotifi = (chainId: number | undefined) => {
|
|
13
18
|
const [notifiChainSupported, setNotifiChainSupported] = useState(false)
|
|
@@ -54,32 +59,31 @@ export const useNotifiClient = (
|
|
|
54
59
|
return { notifiClient }
|
|
55
60
|
}
|
|
56
61
|
|
|
62
|
+
// Check if user is authenticated
|
|
63
|
+
// If not authenticated or expired, have user login
|
|
64
|
+
// After login, check FTU stage
|
|
65
|
+
// If FTU stage is not Done, go to signup flow. Otherwise, skip to next step
|
|
66
|
+
|
|
57
67
|
export const useIsFirstTimeNotifiUser = (
|
|
58
68
|
account: string | undefined,
|
|
59
69
|
chainId: number | undefined,
|
|
60
70
|
) => {
|
|
61
71
|
const [isFirstTimeNotifiUser, setIsFirstTimeNotifiUser] = useState(false)
|
|
62
|
-
const {
|
|
72
|
+
const {
|
|
73
|
+
frontendClientStatus: { isInitialized, isAuthenticated, isExpired },
|
|
74
|
+
} = useNotifiFrontendClientContext()
|
|
75
|
+
const { ftuStage, isLoading: isLoadingFtu } = useNotifiUserSettingContext()
|
|
63
76
|
const { notifiChainSupported } = useDoesChainSupportNotifi(chainId)
|
|
64
77
|
|
|
65
78
|
useEffect(() => {
|
|
66
79
|
const checkIsFirstTimeNotifiUser = async () => {
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
userState == null ||
|
|
72
|
-
(userState.status !== 'authenticated' &&
|
|
73
|
-
userState.status !== 'expired')
|
|
74
|
-
) {
|
|
80
|
+
if (isInitialized && notifiChainSupported) {
|
|
81
|
+
// If the user is not authenticated or expired, they are possibly a first time user.
|
|
82
|
+
if (!isAuthenticated || isExpired) {
|
|
75
83
|
setIsFirstTimeNotifiUser(true)
|
|
76
|
-
} else if (
|
|
77
|
-
// If a user is authenticated, check if they
|
|
78
|
-
|
|
79
|
-
const targetGroups = await notifiClient.getTargetGroups()
|
|
80
|
-
const emailTargets = targetGroups[0]?.emailTargets?.[0]
|
|
81
|
-
|
|
82
|
-
if (emailTargets == null || emailTargets.emailAddress == null) {
|
|
84
|
+
} else if (isAuthenticated) {
|
|
85
|
+
// If a user is authenticated, check if they've completed all the FTU (First Time User) stages.
|
|
86
|
+
if (ftuStage !== FtuStage.Done) {
|
|
83
87
|
setIsFirstTimeNotifiUser(true)
|
|
84
88
|
}
|
|
85
89
|
}
|
|
@@ -87,7 +91,14 @@ export const useIsFirstTimeNotifiUser = (
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
checkIsFirstTimeNotifiUser()
|
|
90
|
-
}, [
|
|
94
|
+
}, [
|
|
95
|
+
ftuStage,
|
|
96
|
+
isAuthenticated,
|
|
97
|
+
isExpired,
|
|
98
|
+
isInitialized,
|
|
99
|
+
isLoadingFtu,
|
|
100
|
+
notifiChainSupported,
|
|
101
|
+
])
|
|
91
102
|
|
|
92
103
|
return { isFirstTimeNotifiUser }
|
|
93
104
|
}
|
package/src/index.tsx
CHANGED
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
SolanaPayment,
|
|
94
94
|
SolanaPaymentProps,
|
|
95
95
|
} from './components/CreditLine/solanaPayment'
|
|
96
|
+
import { NotifiContextWrapper } from './components/Notifi/NotifiContextWrapper'
|
|
96
97
|
|
|
97
98
|
/**
|
|
98
99
|
* Mapping of your JSON-RPC connections indexed by chainId
|
|
@@ -136,7 +137,11 @@ function Widget(props: WCProps<WidgetProps>) {
|
|
|
136
137
|
<ReduxProvider store={store}>
|
|
137
138
|
<Web3Provider {...(props as Web3Props)} defaultChainId={chainId}>
|
|
138
139
|
<AtomProvider>
|
|
139
|
-
<ChainSupportProvider>
|
|
140
|
+
<ChainSupportProvider>
|
|
141
|
+
<NotifiContextWrapper chainId={chainId}>
|
|
142
|
+
{children}
|
|
143
|
+
</NotifiContextWrapper>
|
|
144
|
+
</ChainSupportProvider>
|
|
140
145
|
</AtomProvider>
|
|
141
146
|
</Web3Provider>
|
|
142
147
|
</ReduxProvider>
|
|
@@ -667,3 +672,5 @@ export function SolanaPaymentWidget(props: SolanaPaymentWidgetProps) {
|
|
|
667
672
|
</SolanaWidget>
|
|
668
673
|
)
|
|
669
674
|
}
|
|
675
|
+
|
|
676
|
+
export * from './components/Notifi/NotifiContextWrapper'
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { gql, useQuery } from '@apollo/client'
|
|
2
|
-
import {
|
|
3
|
-
CreditEvent,
|
|
4
|
-
CreditEventText,
|
|
5
|
-
downScale,
|
|
6
|
-
isEmpty,
|
|
7
|
-
PoolInfoType,
|
|
8
|
-
timeUtil,
|
|
9
|
-
} from '@huma-finance/shared'
|
|
10
|
-
import { useMQ } from '@huma-finance/web-shared'
|
|
11
|
-
import { Box, css, useTheme } from '@mui/material'
|
|
12
|
-
import { useWeb3React } from '@web3-react/core'
|
|
13
|
-
import { useEffect, useState } from 'react'
|
|
14
|
-
|
|
15
|
-
import { HumaTable } from './HumaTable'
|
|
16
|
-
|
|
17
|
-
const GET_ACTIVITY = gql`
|
|
18
|
-
query GetCreditLineActivity($pool: String!, $owner: String!, $event: [Int]!) {
|
|
19
|
-
creditEvents(
|
|
20
|
-
where: { pool: $pool, owner: $owner, event_in: $event }
|
|
21
|
-
orderBy: timestamp
|
|
22
|
-
orderDirection: desc
|
|
23
|
-
) {
|
|
24
|
-
id
|
|
25
|
-
amount
|
|
26
|
-
timestamp
|
|
27
|
-
owner
|
|
28
|
-
pool
|
|
29
|
-
event
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
`
|
|
33
|
-
|
|
34
|
-
type Props = {
|
|
35
|
-
poolInfo: PoolInfoType
|
|
36
|
-
targetEvents: CreditEvent[]
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
type ActivityDataType = {
|
|
40
|
-
id: string
|
|
41
|
-
owner: string
|
|
42
|
-
pool: string
|
|
43
|
-
timestamp: string
|
|
44
|
-
amount: string
|
|
45
|
-
event: number
|
|
46
|
-
eventText: string | undefined
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const columns = [
|
|
50
|
-
{ title: 'Action', dataIndex: 'eventText' },
|
|
51
|
-
{
|
|
52
|
-
title: 'Amount',
|
|
53
|
-
action: (record: { amount: string }) => {
|
|
54
|
-
if (isEmpty(record.amount) || Number.isNaN(record.amount)) {
|
|
55
|
-
return ''
|
|
56
|
-
}
|
|
57
|
-
return Number(record.amount).toFixed(2)
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{ title: 'Date', dataIndex: 'timestamp' },
|
|
61
|
-
]
|
|
62
|
-
|
|
63
|
-
export function Activity({
|
|
64
|
-
poolInfo,
|
|
65
|
-
targetEvents,
|
|
66
|
-
}: Props): React.ReactElement | null {
|
|
67
|
-
const theme = useTheme()
|
|
68
|
-
const { account } = useWeb3React()
|
|
69
|
-
const { decimals } = poolInfo.poolUnderlyingToken
|
|
70
|
-
const [events, setEvents] = useState<ActivityDataType[] | undefined>()
|
|
71
|
-
const { data } = useQuery<{
|
|
72
|
-
creditEvents: ActivityDataType[]
|
|
73
|
-
}>(GET_ACTIVITY, {
|
|
74
|
-
variables: {
|
|
75
|
-
pool: poolInfo.pool,
|
|
76
|
-
owner: account,
|
|
77
|
-
event: targetEvents,
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
|
-
const { isSmSize } = useMQ()
|
|
81
|
-
|
|
82
|
-
const getPadding = () => {
|
|
83
|
-
if (isSmSize) {
|
|
84
|
-
return theme.spacing(2, 3)
|
|
85
|
-
}
|
|
86
|
-
return theme.spacing(4, 6)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
if (!data?.creditEvents) {
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
|
-
const result = data.creditEvents.map((item) => {
|
|
94
|
-
const event = JSON.parse(JSON.stringify(item)) as ActivityDataType
|
|
95
|
-
event.eventText = CreditEventText[item.event]
|
|
96
|
-
event.amount = downScale(event.amount, decimals)
|
|
97
|
-
event.timestamp = timeUtil.timestampToLL(Number(event.timestamp))
|
|
98
|
-
return event
|
|
99
|
-
})
|
|
100
|
-
setEvents(result)
|
|
101
|
-
}, [data?.creditEvents, decimals])
|
|
102
|
-
|
|
103
|
-
const styles = {
|
|
104
|
-
wrapper: css`
|
|
105
|
-
margin-top: ${theme.spacing(9)};
|
|
106
|
-
`,
|
|
107
|
-
title: css`
|
|
108
|
-
font-weight: 800;
|
|
109
|
-
font-size: 24px;
|
|
110
|
-
color: ${theme.palette.text.primary};
|
|
111
|
-
margin-bottom: ${theme.spacing(2)};
|
|
112
|
-
`,
|
|
113
|
-
tableWrapper: css`
|
|
114
|
-
box-shadow: 0px 4px 40px 8px rgba(0, 0, 0, 0.04);
|
|
115
|
-
border-radius: 24px;
|
|
116
|
-
padding: ${getPadding()};
|
|
117
|
-
`,
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<Box css={styles.wrapper}>
|
|
122
|
-
<Box css={styles.title}>Recent Activity</Box>
|
|
123
|
-
<Box css={styles.tableWrapper}>
|
|
124
|
-
<HumaTable columns={columns} rows={events} hideRowsPerPage={isSmSize} />
|
|
125
|
-
</Box>
|
|
126
|
-
</Box>
|
|
127
|
-
)
|
|
128
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Box, css, LinearProgress, useTheme } from '@mui/material'
|
|
2
|
-
import { useWeb3React } from '@web3-react/core'
|
|
3
|
-
import {
|
|
4
|
-
AccountStats,
|
|
5
|
-
downScale,
|
|
6
|
-
formatMoney,
|
|
7
|
-
hasRFActiveLoan,
|
|
8
|
-
PoolInfoType,
|
|
9
|
-
timestampToLL,
|
|
10
|
-
} from '@huma-finance/shared'
|
|
11
|
-
import { useMQ, usePoolUnderlyingToken } from '@huma-finance/web-shared'
|
|
12
|
-
import React, { useEffect, useState } from 'react'
|
|
13
|
-
|
|
14
|
-
import { ColumnType } from '../../utilTypes'
|
|
15
|
-
import { HumaTable } from '../HumaTable'
|
|
16
|
-
import { ReceiptIcon } from '../icons'
|
|
17
|
-
|
|
18
|
-
type Props<T> = {
|
|
19
|
-
title: 'Streams' | 'Invoices'
|
|
20
|
-
poolInfo: PoolInfoType
|
|
21
|
-
loading: boolean
|
|
22
|
-
accountStats: AccountStats
|
|
23
|
-
handlePayManually: (item: T) => void
|
|
24
|
-
getColumns: (handlePayManually: (item: T) => void) => ColumnType<T>[]
|
|
25
|
-
setItem?: (
|
|
26
|
-
accountStats: AccountStats,
|
|
27
|
-
) => Promise<{ name?: string; payer?: string }>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function FactoredList<T>({
|
|
31
|
-
title,
|
|
32
|
-
poolInfo,
|
|
33
|
-
loading,
|
|
34
|
-
accountStats,
|
|
35
|
-
handlePayManually,
|
|
36
|
-
getColumns,
|
|
37
|
-
setItem,
|
|
38
|
-
}: Props<T>): React.ReactElement {
|
|
39
|
-
const theme = useTheme()
|
|
40
|
-
const { isMdSize } = useMQ()
|
|
41
|
-
const { isActive, chainId } = useWeb3React()
|
|
42
|
-
const { decimals } = usePoolUnderlyingToken(
|
|
43
|
-
poolInfo.poolName,
|
|
44
|
-
poolInfo.poolType,
|
|
45
|
-
chainId,
|
|
46
|
-
)
|
|
47
|
-
const [factoredItem, setFactoredItem] = useState<Partial<T>>()
|
|
48
|
-
const { creditRecord, receivableInfo } = accountStats
|
|
49
|
-
const hasActiveLoan = hasRFActiveLoan(creditRecord, receivableInfo)
|
|
50
|
-
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
const fetchData = async () => {
|
|
53
|
-
if (creditRecord && receivableInfo?.receivableParam.gt(0) && decimals) {
|
|
54
|
-
const id = receivableInfo.receivableParam.toString()
|
|
55
|
-
const dueDate = timestampToLL(creditRecord.dueDate.toNumber())
|
|
56
|
-
const { receivableAmount } = receivableInfo
|
|
57
|
-
const { totalDue } = creditRecord
|
|
58
|
-
let factoredItem = {
|
|
59
|
-
id,
|
|
60
|
-
due: dueDate,
|
|
61
|
-
icon: <ReceiptIcon css={{ width: '24px' }} />,
|
|
62
|
-
amount: formatMoney(downScale(receivableAmount.toString(), decimals)),
|
|
63
|
-
factored: formatMoney(downScale(totalDue.toString(), decimals)),
|
|
64
|
-
remained: formatMoney(
|
|
65
|
-
downScale(receivableAmount.sub(totalDue).toString(), decimals),
|
|
66
|
-
),
|
|
67
|
-
} as T
|
|
68
|
-
if (setItem) {
|
|
69
|
-
const customProps = await setItem(accountStats)
|
|
70
|
-
factoredItem = { ...factoredItem, ...customProps }
|
|
71
|
-
}
|
|
72
|
-
setFactoredItem(factoredItem)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
fetchData()
|
|
76
|
-
}, [accountStats, creditRecord, decimals, receivableInfo, setItem])
|
|
77
|
-
|
|
78
|
-
const getPadding = () => {
|
|
79
|
-
if (isMdSize) {
|
|
80
|
-
return theme.spacing(0, 1, 1, 1)
|
|
81
|
-
}
|
|
82
|
-
return theme.spacing(0, 2, 2, 2)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const styles = {
|
|
86
|
-
title: css`
|
|
87
|
-
font-weight: 800;
|
|
88
|
-
color: ${theme.palette.text.primary};
|
|
89
|
-
font-size: 24px;
|
|
90
|
-
margin-bottom: ${theme.spacing(2)};
|
|
91
|
-
`,
|
|
92
|
-
description: css`
|
|
93
|
-
font-weight: 400;
|
|
94
|
-
color: ${theme.palette.text.primary};
|
|
95
|
-
font-size: 1rem;
|
|
96
|
-
`,
|
|
97
|
-
tableWrapper: css`
|
|
98
|
-
margin-top: ${theme.spacing(3)};
|
|
99
|
-
padding: ${getPadding()};
|
|
100
|
-
background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
|
|
101
|
-
border: 1px solid #ffffff;
|
|
102
|
-
border-radius: 24px;
|
|
103
|
-
position: relative;
|
|
104
|
-
`,
|
|
105
|
-
progress: css`
|
|
106
|
-
width: calc(100% - 30px);
|
|
107
|
-
position: absolute;
|
|
108
|
-
top: 0;
|
|
109
|
-
left: ${theme.spacing(2)};
|
|
110
|
-
`,
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<Box>
|
|
115
|
-
<Box css={styles.title}>Factored {title}</Box>
|
|
116
|
-
<Box css={styles.description} marginBottom={theme.spacing(6)}>
|
|
117
|
-
{!isActive && (
|
|
118
|
-
<Box component='span'>
|
|
119
|
-
Please connect wallet to check your factored {title.toLowerCase()}.
|
|
120
|
-
</Box>
|
|
121
|
-
)}
|
|
122
|
-
{isActive && !hasActiveLoan && (
|
|
123
|
-
<Box component='span'>
|
|
124
|
-
You don’t have any factored {title.toLowerCase()}.
|
|
125
|
-
</Box>
|
|
126
|
-
)}
|
|
127
|
-
{isActive && hasActiveLoan && factoredItem && (
|
|
128
|
-
<Box css={styles.tableWrapper}>
|
|
129
|
-
{loading && (
|
|
130
|
-
<Box css={styles.progress}>
|
|
131
|
-
<LinearProgress />
|
|
132
|
-
</Box>
|
|
133
|
-
)}
|
|
134
|
-
<HumaTable
|
|
135
|
-
columns={getColumns(handlePayManually)}
|
|
136
|
-
rows={[factoredItem]}
|
|
137
|
-
/>
|
|
138
|
-
</Box>
|
|
139
|
-
)}
|
|
140
|
-
</Box>
|
|
141
|
-
</Box>
|
|
142
|
-
)
|
|
143
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Box, css, LinearProgress, useTheme } from '@mui/material'
|
|
2
|
-
import { useWeb3React } from '@web3-react/core'
|
|
3
|
-
import { useMQ } from '@huma-finance/web-shared'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
|
|
6
|
-
import { ColumnType, WCProps } from '../../utilTypes'
|
|
7
|
-
import { HumaTable } from '../HumaTable'
|
|
8
|
-
|
|
9
|
-
type Props<T> = {
|
|
10
|
-
items: T[] | undefined
|
|
11
|
-
loading: boolean
|
|
12
|
-
columns: ColumnType<T>[]
|
|
13
|
-
title: string
|
|
14
|
-
connectWalletDesc: string
|
|
15
|
-
noItemDesc: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function UpcomingList<T>({
|
|
19
|
-
items,
|
|
20
|
-
loading,
|
|
21
|
-
columns,
|
|
22
|
-
title,
|
|
23
|
-
connectWalletDesc,
|
|
24
|
-
noItemDesc,
|
|
25
|
-
children,
|
|
26
|
-
}: WCProps<Props<T>>): React.ReactElement {
|
|
27
|
-
const theme = useTheme()
|
|
28
|
-
const { isActive } = useWeb3React()
|
|
29
|
-
const { isMdSize, isSmSize } = useMQ()
|
|
30
|
-
|
|
31
|
-
const getPadding = () => {
|
|
32
|
-
if (isMdSize) {
|
|
33
|
-
return theme.spacing(0, 1, 1, 1)
|
|
34
|
-
}
|
|
35
|
-
return theme.spacing(0, 2, 2, 2)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const styles = {
|
|
39
|
-
title: css`
|
|
40
|
-
font-weight: 800;
|
|
41
|
-
color: ${theme.palette.text.primary};
|
|
42
|
-
font-size: 24px;
|
|
43
|
-
margin-bottom: ${theme.spacing(2)};
|
|
44
|
-
`,
|
|
45
|
-
description: css`
|
|
46
|
-
font-weight: 400;
|
|
47
|
-
color: ${theme.palette.text.primary};
|
|
48
|
-
font-size: 1rem;
|
|
49
|
-
`,
|
|
50
|
-
tableWrapper: css`
|
|
51
|
-
margin-top: ${theme.spacing(3)};
|
|
52
|
-
padding: ${getPadding()};
|
|
53
|
-
background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
|
|
54
|
-
border: 1px solid #ffffff;
|
|
55
|
-
border-radius: 24px;
|
|
56
|
-
position: relative;
|
|
57
|
-
`,
|
|
58
|
-
progress: css`
|
|
59
|
-
width: calc(100% - 30px);
|
|
60
|
-
position: absolute;
|
|
61
|
-
top: 0;
|
|
62
|
-
left: ${theme.spacing(2)};
|
|
63
|
-
`,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<Box>
|
|
68
|
-
<Box css={styles.title}>{title}</Box>
|
|
69
|
-
<Box css={styles.description} marginBottom={theme.spacing(6)}>
|
|
70
|
-
{!isActive && <Box component='span'>{connectWalletDesc}</Box>}
|
|
71
|
-
{isActive && !items?.length && <Box>{noItemDesc}</Box>}
|
|
72
|
-
{isActive && !!items?.length && (
|
|
73
|
-
<Box css={styles.tableWrapper}>
|
|
74
|
-
{loading && (
|
|
75
|
-
<Box css={styles.progress}>
|
|
76
|
-
<LinearProgress />
|
|
77
|
-
</Box>
|
|
78
|
-
)}
|
|
79
|
-
<HumaTable
|
|
80
|
-
columns={columns}
|
|
81
|
-
rows={items}
|
|
82
|
-
hideRowsPerPage={isSmSize}
|
|
83
|
-
/>
|
|
84
|
-
</Box>
|
|
85
|
-
)}
|
|
86
|
-
{children}
|
|
87
|
-
</Box>
|
|
88
|
-
</Box>
|
|
89
|
-
)
|
|
90
|
-
}
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { Box, css, Skeleton, TablePagination, useTheme } from '@mui/material'
|
|
2
|
-
import Table from '@mui/material/Table'
|
|
3
|
-
import TableBody from '@mui/material/TableBody'
|
|
4
|
-
import TableCell from '@mui/material/TableCell'
|
|
5
|
-
import TableContainer from '@mui/material/TableContainer'
|
|
6
|
-
import TableHead from '@mui/material/TableHead'
|
|
7
|
-
import TableRow from '@mui/material/TableRow'
|
|
8
|
-
import * as React from 'react'
|
|
9
|
-
|
|
10
|
-
import { useElementDimensions } from '../hooks/useElementDimensions'
|
|
11
|
-
import { ColumnType } from '../utilTypes'
|
|
12
|
-
import { SeparatorIcon } from './icons'
|
|
13
|
-
|
|
14
|
-
type Props<T> = {
|
|
15
|
-
columns: ColumnType<T>[]
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
-
rows?: any[]
|
|
18
|
-
hideRowsPerPage?: boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// @TODO: Move HumaTable along with Superfluid widget to Dapp package
|
|
22
|
-
export function HumaTable<T>({
|
|
23
|
-
columns,
|
|
24
|
-
rows,
|
|
25
|
-
hideRowsPerPage = false,
|
|
26
|
-
}: Props<T>): React.ReactElement | null {
|
|
27
|
-
const theme = useTheme()
|
|
28
|
-
const ref = React.useRef()
|
|
29
|
-
const [page, setPage] = React.useState(0)
|
|
30
|
-
const [rowsPerPage, setRowsPerPage] = React.useState(5)
|
|
31
|
-
const noPagination = rows ? rows.length <= 5 : true
|
|
32
|
-
const rowPerPageOptions = hideRowsPerPage ? [] : [5, 10, 25]
|
|
33
|
-
const { width } = useElementDimensions(ref)
|
|
34
|
-
const isLoading = !columns || !rows
|
|
35
|
-
|
|
36
|
-
const styles = {
|
|
37
|
-
tableHeader: css`
|
|
38
|
-
font-weight: 400;
|
|
39
|
-
${theme.cssMixins.rowVCentered}
|
|
40
|
-
font-size: 14px;
|
|
41
|
-
color: rgba(0, 0, 0, 0.87);
|
|
42
|
-
`,
|
|
43
|
-
tableBody: css`
|
|
44
|
-
font-weight: 400;
|
|
45
|
-
font-size: 14px;
|
|
46
|
-
color: rgba(0, 0, 0, 0.87);
|
|
47
|
-
`,
|
|
48
|
-
empty: css`
|
|
49
|
-
display: flex;
|
|
50
|
-
flex-direction: column;
|
|
51
|
-
align-items: center;
|
|
52
|
-
margin-top: ${theme.spacing(2)};
|
|
53
|
-
font-weight: 400;
|
|
54
|
-
font-size: 14px;
|
|
55
|
-
`,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const handleChangePage = (event: unknown, newPage: number) => {
|
|
59
|
-
setPage(newPage)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const handleChangeRowsPerPage = (
|
|
63
|
-
event: React.ChangeEvent<HTMLInputElement>,
|
|
64
|
-
) => {
|
|
65
|
-
setRowsPerPage(parseInt(event.target.value, 10))
|
|
66
|
-
setPage(0)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const getTableHeader = () => (
|
|
70
|
-
<TableHead>
|
|
71
|
-
<TableRow>
|
|
72
|
-
{columns.map((column, index) => (
|
|
73
|
-
<TableCell key={column.title} width={column.width}>
|
|
74
|
-
<Box css={styles.tableHeader}>
|
|
75
|
-
{index !== 0 && <SeparatorIcon />}
|
|
76
|
-
<Box component='span' sx={{ marginLeft: index ? '12px' : '0' }}>
|
|
77
|
-
{column.title}
|
|
78
|
-
</Box>
|
|
79
|
-
</Box>
|
|
80
|
-
</TableCell>
|
|
81
|
-
))}
|
|
82
|
-
</TableRow>
|
|
83
|
-
</TableHead>
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
if (isLoading) {
|
|
87
|
-
return (
|
|
88
|
-
<Box ref={ref}>
|
|
89
|
-
<Box sx={{ width }}>
|
|
90
|
-
<Skeleton />
|
|
91
|
-
<Skeleton />
|
|
92
|
-
<Skeleton />
|
|
93
|
-
</Box>
|
|
94
|
-
</Box>
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (rows.length === 0) {
|
|
99
|
-
return (
|
|
100
|
-
<TableContainer>
|
|
101
|
-
<Table aria-label='simple table'>{getTableHeader()}</Table>
|
|
102
|
-
<Box css={styles.empty}>
|
|
103
|
-
<Box>No Data</Box>
|
|
104
|
-
</Box>
|
|
105
|
-
</TableContainer>
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<>
|
|
111
|
-
<TableContainer>
|
|
112
|
-
<Table aria-label='simple table'>
|
|
113
|
-
{getTableHeader()}
|
|
114
|
-
<TableBody>
|
|
115
|
-
{rows
|
|
116
|
-
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
|
117
|
-
.map((row) => (
|
|
118
|
-
<TableRow key={row.id || row.name}>
|
|
119
|
-
{columns.map((column, index) => (
|
|
120
|
-
<TableCell
|
|
121
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
122
|
-
key={`${column.dataIndex}-${index}`}
|
|
123
|
-
component='th'
|
|
124
|
-
scope='row'
|
|
125
|
-
css={styles.tableBody}
|
|
126
|
-
width={column.width}
|
|
127
|
-
sx={column.style}
|
|
128
|
-
>
|
|
129
|
-
{column.dataIndex && (
|
|
130
|
-
<Box
|
|
131
|
-
component='span'
|
|
132
|
-
sx={{
|
|
133
|
-
display: 'flex',
|
|
134
|
-
alignItems: 'center',
|
|
135
|
-
marginLeft: theme.spacing(index ? 1 : 0),
|
|
136
|
-
}}
|
|
137
|
-
>
|
|
138
|
-
{row[column.dataIndex]}
|
|
139
|
-
</Box>
|
|
140
|
-
)}
|
|
141
|
-
{column.action && (
|
|
142
|
-
<Box
|
|
143
|
-
component='span'
|
|
144
|
-
sx={{
|
|
145
|
-
display: 'flex',
|
|
146
|
-
alignItems: 'center',
|
|
147
|
-
marginLeft: theme.spacing(index ? 1 : 0),
|
|
148
|
-
lineHeight: 0,
|
|
149
|
-
height: 0,
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
{column.action(row)}
|
|
153
|
-
</Box>
|
|
154
|
-
)}
|
|
155
|
-
</TableCell>
|
|
156
|
-
))}
|
|
157
|
-
</TableRow>
|
|
158
|
-
))}
|
|
159
|
-
</TableBody>
|
|
160
|
-
</Table>
|
|
161
|
-
</TableContainer>
|
|
162
|
-
{!noPagination && (
|
|
163
|
-
<TablePagination
|
|
164
|
-
size='small'
|
|
165
|
-
sx={{
|
|
166
|
-
'.MuiTablePagination-selectLabel': {
|
|
167
|
-
fontSize: '12px',
|
|
168
|
-
},
|
|
169
|
-
'.MuiTablePagination-select': {
|
|
170
|
-
fontSize: '12px',
|
|
171
|
-
},
|
|
172
|
-
'.MuiTablePagination-displayedRows': {
|
|
173
|
-
fontSize: '12px',
|
|
174
|
-
},
|
|
175
|
-
'.MuiTablePagination-menuItem': {
|
|
176
|
-
fontSize: '14px',
|
|
177
|
-
},
|
|
178
|
-
}}
|
|
179
|
-
rowsPerPageOptions={rowPerPageOptions}
|
|
180
|
-
component='div'
|
|
181
|
-
count={rows ? rows.length : 0}
|
|
182
|
-
rowsPerPage={rowsPerPage}
|
|
183
|
-
page={page}
|
|
184
|
-
onPageChange={handleChangePage}
|
|
185
|
-
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
186
|
-
SelectProps={{
|
|
187
|
-
MenuProps: {
|
|
188
|
-
sx: {
|
|
189
|
-
'.MuiTablePagination-menuItem': {
|
|
190
|
-
padding: theme.spacing(1, 0),
|
|
191
|
-
display: 'flex',
|
|
192
|
-
justifyContent: 'center',
|
|
193
|
-
fontSize: '14px',
|
|
194
|
-
lineHeight: '1.2',
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
}}
|
|
199
|
-
/>
|
|
200
|
-
)}
|
|
201
|
-
</>
|
|
202
|
-
)
|
|
203
|
-
}
|