diff --git a/portal-ui/package.json b/portal-ui/package.json index 50f015204..c59ea43a0 100644 --- a/portal-ui/package.json +++ b/portal-ui/package.json @@ -51,7 +51,8 @@ "react-redux": "^7.1.3", "react-router-dom": "^5.1.2", "react-virtualized": "^9.22.2", - "react-window-infinite-loader": "^1.0.5", + "react-window": "^1.8.6", + "react-window-infinite-loader": "^1.0.7", "recharts": "^2.1.1", "redux": "^4.0.5", "redux-thunk": "^2.3.0", @@ -84,6 +85,8 @@ }, "proxy": "http://localhost:9090/", "devDependencies": { + "@types/react-window": "^1.8.5", + "@types/react-window-infinite-loader": "^1.0.5", "@types/recharts": "^1.8.22", "prettier": "2.3.2", "react-app-rewire-hot-loader": "^2.0.1", diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx index a14e49c88..3fd7d05d4 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx @@ -55,7 +55,6 @@ const styles = (theme: Theme) => wordWrap: "break-word", overflowWrap: "break-word", wordBreak: "break-all", - // height: 90, font: "normal normal bold 24px/27px Lato", color: theme.palette.primary.main, diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx index 597f6dc14..3b64d9ec7 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx @@ -49,6 +49,7 @@ import { } from "../../../../common/SecureComponent/permissions"; import PageLayout from "../../Common/Layout/PageLayout"; import SearchBox from "../../Common/SearchBox"; +import VirtualizedList from "../../Common/VirtualizedList/VirtualizedList"; const styles = (theme: Theme) => createStyles({ @@ -66,6 +67,7 @@ const styles = (theme: Theme) => }, bucketList: { marginTop: 25, + height: "calc(100vh - 210px)", }, searchField: { ...searchField.searchField, @@ -172,6 +174,24 @@ const ListBuckets = ({ } }; + const renderItemLine = (index: number) => { + const bucket = filteredRecords[index] || null; + + if (bucket) { + return ( + + ); + } + + return null; + }; + return ( {deleteOpen && ( @@ -262,18 +282,12 @@ const ListBuckets = ({ {loading && } {!loading && ( - {filteredRecords.map((bucket, index) => { - return ( - - ); - })} + {filteredRecords.length !== 0 && ( + + )} {filteredRecords.length === 0 && filterBuckets !== "" && ( . + +import React, { Fragment, ReactElement, useState } from "react"; +import { FixedSizeList as List } from "react-window"; +import InfiniteLoader from "react-window-infinite-loader"; +import { AutoSizer } from "react-virtualized"; + +interface IVirtualizedList { + rowRenderFunction: (index: number) => ReactElement | null; + totalItems: number; + defaultHeight?: number; +} + +let itemStatusMap: any = {}; +const LOADING = 1; +const LOADED = 2; + +const VirtualizedList = ({ + rowRenderFunction, + totalItems, + defaultHeight, +}: IVirtualizedList) => { + const isItemLoaded = (index: any) => !!itemStatusMap[index]; + + const loadMoreItems = (startIndex: number, stopIndex: number) => { + for (let index = startIndex; index <= stopIndex; index++) { + itemStatusMap[index] = LOADING; + } + + for (let index = startIndex; index <= stopIndex; index++) { + itemStatusMap[index] = LOADED; + } + }; + + const RenderItemLine = ({ index, style }: any) => { + return
{rowRenderFunction(index)}
; + }; + + return ( + + + {({ onItemsRendered, ref }) => ( + + {({ width, height }) => { + return ( + + {RenderItemLine} + + ); + }} + + )} + + + ); +}; + +export default VirtualizedList; diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx index e86c50e59..785289afa 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx @@ -45,6 +45,8 @@ import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton"; import AButton from "../../Common/AButton/AButton"; import withSuspense from "../../Common/Components/withSuspense"; +import VirtualizedList from "../../Common/VirtualizedList/VirtualizedList"; +import BucketListItem from "../../Buckets/ListBuckets/BucketListItem"; const CredentialsPrompt = withSuspense( React.lazy(() => import("../../Common/CredentialsPrompt/CredentialsPrompt")) @@ -94,6 +96,10 @@ const styles = (theme: Theme) => textAlign: "right", marginBottom: 8, }, + tenantsList: { + marginTop: 25, + height: "calc(100vh - 195px)", + }, }); const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => { @@ -158,6 +164,16 @@ const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => { setIsLoading(true); }, []); + const renderItemLine = (index: number) => { + const tenant = filteredRecords[index] || null; + + if (tenant) { + return ; + } + + return null; + }; + return ( {showNewCredentials && ( @@ -259,13 +275,16 @@ const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => {
- + {isLoading && } {!isLoading && ( - {filteredRecords.map((t) => { - return ; - })} + {filteredRecords.length !== 0 && ( + + )} {filteredRecords.length === 0 && ( =3.1.1 <6": + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -8373,11 +8393,19 @@ react-virtualized@^9.22.2: prop-types "^15.7.2" react-lifecycles-compat "^3.0.4" -react-window-infinite-loader@^1.0.5: +react-window-infinite-loader@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/react-window-infinite-loader/-/react-window-infinite-loader-1.0.7.tgz#958ef1a689d20dce122ef377583acd987760aee8" integrity sha512-wg3LWkUpG21lhv+cZvNy+p0+vtclZw+9nP2vO6T9PKT50EN1cUq37Dq6FzcM38h/c2domE0gsUhb6jHXtGogAA== +react-window@^1.8.6: + version "1.8.6" + resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112" + integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg== + dependencies: + "@babel/runtime" "^7.0.0" + memoize-one ">=3.1.1 <6" + react@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"