Skip to content

Commit 7f89e79

Browse files
Lezek123DzhideX
andauthored
🌐 Gleev v5.6.1
* Add YPP referral pagination (Joystream#6503) * Add hook which correctly fetches and paginates ypp referral data, integrate hook and add necessary changes to make it work * Update VITE_YOUTUBE_SYNC_API_URL in .env * Add market transactions pagination (Joystream#6505) * Move fetching functionality and add pagination within useMarketTransactionsPagination hook, accomodate code to integrate pagination * Remove unnecessary comment * Update packages/atlas/src/hooks/useMarketTransactionsPagination.ts --------- * Update CHANGELOG and bump versions --------- Co-authored-by: Edvin Dzidic <edvindzidic2000@gmail.com>
1 parent 43d40fb commit 7f89e79

File tree

9 files changed

+155
-48
lines changed

9 files changed

+155
-48
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [5.6.1] - 2026-05-09
9+
10+
### Fixed
11+
12+
- YPP referrals pagination issue in Gleev studio: https://github.com/Joystream/atlas/issues/6502
13+
- Market transactions pagination issue in Gleev studio (CRT dashboard): https://github.com/Joystream/atlas/issues/6438
14+
815
## [5.6.0] - 2024-12-23
916

1017
**IMPORTANT:** Depends on Orion release `4.2.0`.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"description": "UI for consuming Joystream - a user governed video platform",
3-
"version": "5.6.0",
3+
"version": "5.6.1",
44
"license": "GPL-3.0",
55
"workspaces": [
66
"packages/*"

packages/atlas/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@joystream/atlas",
33
"description": "UI for consuming Joystream - a user governed video platform",
4-
"version": "5.6.0",
4+
"version": "5.6.1",
55
"license": "GPL-3.0",
66
"scripts": {
77
"start": "vite",

packages/atlas/src/components/YppReferralTable/YppReferralTable.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ export type YppReferral = {
2222
type YppReferralTableProps = {
2323
isLoading: boolean
2424
data: YppReferral[]
25-
}
25+
} & Pick<TableProps, 'pagination'>
2626

27-
export const YppReferralTable = ({ isLoading, data }: YppReferralTableProps) => {
27+
export const YppReferralTable = ({ isLoading, data, pagination }: YppReferralTableProps) => {
2828
const mappedData: TableProps['data'] = useMemo(
2929
() =>
3030
data.map((entry) => ({
@@ -41,6 +41,8 @@ export const YppReferralTable = ({ isLoading, data }: YppReferralTableProps) =>
4141
title="Channels you referred"
4242
columns={COLUMNS}
4343
data={isLoading ? tableLoadingData : mappedData}
44+
pagination={pagination}
45+
pageSize={pagination?.itemsPerPage}
4446
/>
4547
)
4648
}

packages/atlas/src/components/_crt/AmmTransactionsTable/AmmTransactionsTable.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ type AmmTransactionsTableProps = {
5050
data: FullAmmCurveFragment['transactions']
5151
loading: boolean
5252
symbol: string
53-
}
53+
} & Pick<TableProps, 'pagination'>
5454

55-
export const AmmTransactionsTable = ({ data, loading, symbol }: AmmTransactionsTableProps) => {
55+
export const AmmTransactionsTable = ({ data, loading, symbol, pagination }: AmmTransactionsTableProps) => {
5656
const mappedData = useMemo(
5757
() =>
5858
data.map((row) => ({
@@ -80,6 +80,8 @@ export const AmmTransactionsTable = ({ data, loading, symbol }: AmmTransactionsT
8080
data={loading ? tableLoadingData : mappedData ?? []}
8181
columns={COLUMNS}
8282
emptyState={tableEmptyState}
83+
pagination={pagination}
84+
pageSize={pagination?.itemsPerPage}
8385
/>
8486
)
8587
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { useState } from 'react'
2+
3+
import { useGetFullAmmCurveQuery } from '@/api/queries/__generated__/creatorTokens.generated'
4+
import { SentryLogger } from '@/utils/logs'
5+
6+
const separateListIntoChunks = <T>(list: Array<T>, chunkSize: number): Array<T[]> => {
7+
const chunks = []
8+
9+
for (let index = 0; index < list.length; index += chunkSize) {
10+
chunks.push(list.slice(index, index + chunkSize))
11+
}
12+
13+
return chunks
14+
}
15+
16+
export const useMarketTransactionsPagination = ({
17+
ammId,
18+
initialPageSize = 10,
19+
}: {
20+
ammId?: string
21+
initialPageSize?: number
22+
}) => {
23+
const [currentPage, setCurrentPage] = useState(0)
24+
const [perPage, setPerPage] = useState(initialPageSize)
25+
26+
const { data, loading } = useGetFullAmmCurveQuery({
27+
variables: {
28+
where: {
29+
id_eq: ammId,
30+
},
31+
},
32+
skip: !ammId,
33+
onError: (error) => {
34+
SentryLogger.error('Failed to fetch AMM curve', 'CrtMarketTab', error)
35+
},
36+
})
37+
38+
const marketTransactions = data?.ammCurves[0].transactions ?? []
39+
40+
const pages = separateListIntoChunks(
41+
[...marketTransactions].sort((transactionA, transactionB) => transactionB.createdIn - transactionA.createdIn),
42+
perPage
43+
)
44+
45+
return {
46+
currentPage,
47+
setCurrentPage,
48+
marketTransactions: pages[currentPage] ?? [],
49+
totalCount: marketTransactions.length,
50+
loading,
51+
setPerPage,
52+
perPage,
53+
}
54+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { useMemo, useState } from 'react'
2+
import { useQuery } from 'react-query'
3+
4+
import { axiosInstance } from '@/api/axios'
5+
import { YppReferral } from '@/components/YppReferralTable/YppReferralTable'
6+
import { atlasConfig } from '@/config'
7+
import { useUser } from '@/providers/user/user.hooks'
8+
import { YppSyncedChannel } from '@/views/global/YppLandingView/YppLandingView.types'
9+
10+
const YPP_SYNC_URL = atlasConfig.features.ypp.youtubeSyncApiUrl
11+
12+
const separateListIntoChunks = <T>(list: Array<T>, chunkSize: number): Array<T[]> => {
13+
const chunks = []
14+
15+
for (let index = 0; index < list.length; index += chunkSize) {
16+
chunks.push(list.slice(index, index + chunkSize))
17+
}
18+
19+
return chunks
20+
}
21+
22+
export const useYppReferralPagination = ({ initialPageSize = 10 }: { initialPageSize?: number }) => {
23+
const [currentPage, setCurrentPage] = useState(0)
24+
const [perPage, setPerPage] = useState(initialPageSize)
25+
const { channelId } = useUser()
26+
27+
const { isLoading, data } = useQuery(
28+
['referralsTable', channelId],
29+
() => axiosInstance.get<YppSyncedChannel[]>(`${YPP_SYNC_URL}/channels/${channelId}/referrals`),
30+
{ enabled: !!channelId }
31+
)
32+
33+
const yppReferrals: YppReferral[] = useMemo(
34+
() =>
35+
// TODO: For large arrays, the creation of new Date instances for sorting might be a performance consideration.
36+
data?.data
37+
.sort((channelA, channelB) => new Date(channelB.createdAt).getTime() - new Date(channelA.createdAt).getTime())
38+
.map((channelData) => {
39+
return {
40+
date: new Date(channelData.createdAt),
41+
channelId: String(channelData.joystreamChannelId),
42+
status: channelData.yppStatus,
43+
}
44+
}) ?? [],
45+
[data?.data]
46+
)
47+
48+
const pages = separateListIntoChunks(yppReferrals, perPage)
49+
50+
return {
51+
currentPage,
52+
setCurrentPage,
53+
yppReferrals: pages[currentPage] ?? [],
54+
totalCount: yppReferrals.length,
55+
isLoading,
56+
setPerPage,
57+
perPage,
58+
}
59+
}

packages/atlas/src/views/studio/CrtDashboard/tabs/CrtMarketTab.tsx

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import BN from 'bn.js'
22
import { useMemo } from 'react'
33

4-
import { useGetFullAmmCurveQuery } from '@/api/queries/__generated__/creatorTokens.generated'
54
import { FullCreatorTokenFragment } from '@/api/queries/__generated__/fragments.generated'
65
import { SvgJoyTokenMonochrome24 } from '@/assets/icons'
76
import { FlexBox } from '@/components/FlexBox'
@@ -10,29 +9,23 @@ import { WidgetTile } from '@/components/WidgetTile'
109
import { AmmTransactionsTable } from '@/components/_crt/AmmTransactionsTable/AmmTransactionsTable'
1110
import { SkeletonLoader } from '@/components/_loaders/SkeletonLoader'
1211
import { atlasConfig } from '@/config'
12+
import { useMarketTransactionsPagination } from '@/hooks/useMarketTransactionsPagination'
1313
import { useMediaMatch } from '@/hooks/useMediaMatch'
1414
import { HAPI_TO_JOY_RATE } from '@/joystream-lib/config'
1515
import { calcBuyMarketPricePerToken } from '@/utils/crts'
16-
import { SentryLogger } from '@/utils/logs'
1716

1817
type CrtMarketTabProps = {
1918
token: FullCreatorTokenFragment
2019
}
2120

21+
const TILES_PER_PAGE = 10
22+
2223
export const CrtMarketTab = ({ token }: CrtMarketTabProps) => {
2324
const mdMatch = useMediaMatch('md')
2425
const currentAmm = token.ammCurves.find((curve) => !curve.finalized)
25-
const { data, loading } = useGetFullAmmCurveQuery({
26-
variables: {
27-
where: {
28-
id_eq: currentAmm?.id,
29-
},
30-
},
31-
skip: !currentAmm,
32-
onError: (error) => {
33-
SentryLogger.error('Failed to fetch AMM curve', 'CrtMarketTab', error)
34-
},
35-
})
26+
const { loading, marketTransactions, currentPage, setCurrentPage, perPage, setPerPage, totalCount } =
27+
useMarketTransactionsPagination({ ammId: currentAmm?.id, initialPageSize: TILES_PER_PAGE })
28+
3629
const pricePerUnit = useMemo(
3730
() => calcBuyMarketPricePerToken(currentAmm?.mintedByAmm, currentAmm?.ammSlopeParameter, currentAmm?.ammInitPrice),
3831
[currentAmm?.ammInitPrice, currentAmm?.ammSlopeParameter, currentAmm?.mintedByAmm]
@@ -103,7 +96,8 @@ export const CrtMarketTab = ({ token }: CrtMarketTabProps) => {
10396
<AmmTransactionsTable
10497
symbol={token.symbol ?? 'N/A'}
10598
loading={loading}
106-
data={data?.ammCurves[0].transactions ?? []}
99+
data={marketTransactions}
100+
pagination={{ page: currentPage, setPerPage, totalCount, itemsPerPage: perPage, onChangePage: setCurrentPage }}
107101
/>
108102
</>
109103
)

packages/atlas/src/views/studio/YppDashboard/tabs/YppDashboardReferralsTab/YppDashboardReferralsTab.tsx

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,20 @@
1-
import { useMemo } from 'react'
2-
import { useQuery } from 'react-query'
3-
4-
import { axiosInstance } from '@/api/axios'
51
import { SvgActionLinkUrl } from '@/assets/icons'
62
import { EmptyFallback } from '@/components/EmptyFallback'
73
import { GridItem, LayoutGrid } from '@/components/LayoutGrid'
8-
import { YppReferral, YppReferralTable } from '@/components/YppReferralTable/YppReferralTable'
4+
import { YppReferralTable } from '@/components/YppReferralTable/YppReferralTable'
95
import { ReferralLinkButton } from '@/components/_ypp/ReferralLinkButton'
106
import { YppSuspendedBanner } from '@/components/_ypp/YppSuspendedBanner'
117
import { atlasConfig } from '@/config'
12-
import { useUser } from '@/providers/user/user.hooks'
13-
import { YppSyncedChannel } from '@/views/global/YppLandingView/YppLandingView.types'
8+
import { useYppReferralPagination } from '@/hooks/useYppReferralPagination'
149

1510
import { FallbackContainer } from '../YppDashboardTabs.styles'
1611

17-
const YPP_SYNC_URL = atlasConfig.features.ypp.youtubeSyncApiUrl
12+
const TILES_PER_PAGE = 10
1813

1914
export const YppDashboardReferralsTab = () => {
2015
const yppSuspended = atlasConfig.features.ypp.suspended
21-
const { channelId } = useUser()
22-
const { isLoading, data } = useQuery(
23-
['referralsTable', channelId],
24-
() => axiosInstance.get<YppSyncedChannel[]>(`${YPP_SYNC_URL}/channels/${channelId}/referrals`),
25-
{ enabled: !!channelId }
26-
)
27-
28-
const mappedData: YppReferral[] = useMemo(
29-
() =>
30-
data?.data.map((channelData) => {
31-
return {
32-
date: new Date(channelData.createdAt),
33-
channelId: String(channelData.joystreamChannelId),
34-
status: channelData.yppStatus,
35-
}
36-
}) ?? [],
37-
[data?.data]
38-
)
16+
const { isLoading, yppReferrals, currentPage, setCurrentPage, perPage, setPerPage, totalCount } =
17+
useYppReferralPagination({ initialPageSize: TILES_PER_PAGE })
3918

4019
return (
4120
<LayoutGrid>
@@ -45,7 +24,7 @@ export const YppDashboardReferralsTab = () => {
4524
</GridItem>
4625
)}
4726
<GridItem colSpan={{ base: 12 }}>
48-
{!isLoading && !mappedData?.length ? (
27+
{!isLoading && totalCount === 0 ? (
4928
<FallbackContainer>
5029
<EmptyFallback
5130
title="No referred users yet"
@@ -55,7 +34,17 @@ export const YppDashboardReferralsTab = () => {
5534
/>
5635
</FallbackContainer>
5736
) : (
58-
<YppReferralTable data={mappedData} isLoading={isLoading} />
37+
<YppReferralTable
38+
data={yppReferrals}
39+
isLoading={isLoading}
40+
pagination={{
41+
page: currentPage,
42+
setPerPage,
43+
totalCount,
44+
itemsPerPage: perPage,
45+
onChangePage: setCurrentPage,
46+
}}
47+
/>
5948
)}
6049
</GridItem>
6150
</LayoutGrid>

0 commit comments

Comments
 (0)