Skip to content

Commit 7ef2936

Browse files
committed
add self-hosted and cloud instance combined table
1 parent df42b7e commit 7ef2936

File tree

13 files changed

+385
-197
lines changed

13 files changed

+385
-197
lines changed

www/src/components/Plural.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ const Clusters = lazy(() =>
7676
default: module.Clusters,
7777
}))
7878
)
79+
const AllClusters = lazy(() =>
80+
import('./overview/clusters/all/AllClusters').then((module) => ({
81+
default: module.AllClusters,
82+
}))
83+
)
7984
const SelfHostedClusters = lazy(() =>
8085
import('./overview/clusters/self-hosted/SelfHostedClusters').then(
8186
(module) => ({
@@ -646,10 +651,14 @@ export function PluralInner() {
646651
element={
647652
<Navigate
648653
replace
649-
to="self-hosted"
654+
to="all"
650655
/>
651656
}
652657
/>
658+
<Route
659+
path="all"
660+
element={<AllClusters />}
661+
/>
653662
<Route
654663
path="self-hosted"
655664
element={<SelfHostedClusters />}

www/src/components/overview/OverviewHeader.tsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useLocation, useNavigate } from 'react-router-dom'
66
import { LinkTabWrap } from '../utils/Tabs'
77

88
const DIRECTORY = [
9+
{ path: '/overview/clusters/all', label: 'All' },
910
{ path: '/overview/clusters/self-hosted', label: 'Self-hosted clusters' },
1011
{ path: '/overview/clusters/plural-cloud', label: 'Plural cloud instances' },
1112
]
@@ -16,11 +17,6 @@ export default function OverviewHeader(): ReactElement {
1617
const { pathname } = useLocation()
1718
const currentTab = DIRECTORY.find((tab) => pathname?.startsWith(tab.path))
1819

19-
// const [showUnfinished, setShowUnfinished] = useState(hasUnfinishedCreation())
20-
// const { triggerDelete, loading } = useDeleteUnfinishedInstance({
21-
// onClear: () => setShowUnfinished(false),
22-
// })
23-
2420
return (
2521
<Flex justifyContent="space-between">
2622
<TabList
@@ -41,15 +37,6 @@ export default function OverviewHeader(): ReactElement {
4137
))}
4238
</TabList>
4339
<Flex gap="medium">
44-
{/* {showUnfinished && (
45-
<Button
46-
destructive
47-
loading={loading}
48-
onClick={triggerDelete}
49-
>
50-
Cancel cluster creation
51-
</Button>
52-
)} */}
5340
<Button onClick={() => navigate('/create-cluster')}>
5441
Create cluster
5542
</Button>

www/src/components/overview/clusters/ClusterList.tsx

Lines changed: 0 additions & 81 deletions
This file was deleted.

www/src/components/overview/clusters/Clusters.tsx

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { isEmpty } from 'lodash'
2-
import { ReactElement, useContext, useEffect, useState } from 'react'
2+
import { ReactElement, useContext, useEffect, useMemo, useState } from 'react'
33

44
import { Button, Flex, Toast } from '@pluralsh/design-system'
55

66
import { Outlet } from 'react-router-dom'
77

88
import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext'
99

10-
import { FINISHED_LOCAL_CREATE_KEY } from 'components/create-cluster/CreateClusterActions'
10+
import {
11+
FINISHED_CONSOLE_INSTANCE_KEY,
12+
FINISHED_LOCAL_CREATE_KEY,
13+
} from 'components/create-cluster/CreateClusterActions'
1114

1215
import { useTheme } from 'styled-components'
1316

@@ -19,9 +22,23 @@ import ClustersContext from '../../../contexts/ClustersContext'
1922

2023
import OverviewHeader from '../OverviewHeader'
2124

25+
import CurrentUserContext from 'contexts/CurrentUserContext'
2226
import ClusterListEmptyState from './ClusterListEmptyState'
2327
import ClustersHelpSection from './ClustersHelpSection'
2428

29+
import { ConsoleInstanceFragment } from 'generated/graphql'
30+
import {
31+
CombinedClusterT,
32+
CombinedClusterType,
33+
} from './all/AllClustersTableCols'
34+
import { ClusterListElement, fromClusterList } from './clusterListUtils'
35+
36+
export type OverviewContextType = {
37+
selfHostedClusters: ClusterListElement[]
38+
cloudInstances: ConsoleInstanceFragment[]
39+
combinedClusterList: CombinedClusterT[]
40+
}
41+
2542
export const CLUSTERS_ROOT_CRUMB = {
2643
label: 'clusters',
2744
url: '/overview/clusters',
@@ -32,18 +49,58 @@ export const CLUSTERS_OVERVIEW_BREADCRUMBS = [
3249
]
3350

3451
export function Clusters(): ReactElement | null {
35-
const [showToast, setShowToast] = useState(false)
52+
const { spacing } = useTheme()
53+
const [showSupportToast, setShowSupportToast] = useState(false)
54+
const [showPluralCloudToast, setShowPluralCloudToast] = useState(false)
55+
56+
const me = useContext(CurrentUserContext)
3657
const { clusters } = useContext(ClustersContext)
3758
const { instances } = useContext(ConsoleInstancesContext)
3859
const showEmpty = isEmpty(clusters) && isEmpty(instances)
3960

61+
// checks if clusters are still empty after finishing plural cloud setup
4062
useEffect(() => {
4163
if (localStorage.getItem(FINISHED_LOCAL_CREATE_KEY) === 'true') {
42-
if (isEmpty(clusters)) setShowToast(true)
64+
if (isEmpty(clusters)) setShowSupportToast(true)
4365
localStorage.removeItem(FINISHED_LOCAL_CREATE_KEY)
4466
}
4567
}, [clusters])
4668

69+
// shows a success toast after plural cloud instance is created
70+
useEffect(() => {
71+
const id = localStorage.getItem(FINISHED_CONSOLE_INSTANCE_KEY)
72+
73+
if (id && instances.some((i) => i.id === id)) {
74+
localStorage.removeItem(FINISHED_CONSOLE_INSTANCE_KEY)
75+
setShowPluralCloudToast(true)
76+
}
77+
}, [instances])
78+
79+
const ctx: OverviewContextType = useMemo(() => {
80+
const selfHostedClusters = fromClusterList(clusters, me)
81+
const cloudInstances = instances
82+
const combinedClusterList = [
83+
...instances.map((instance) => ({
84+
type: CombinedClusterType.PluralCloud as const,
85+
id: instance.id,
86+
name: instance.name,
87+
status: instance.status,
88+
owner: instance.owner,
89+
consoleUrl: instance.url,
90+
})),
91+
...selfHostedClusters.map((cluster) => ({
92+
type: CombinedClusterType.SelfHosted as const,
93+
...cluster,
94+
})),
95+
]
96+
97+
return {
98+
selfHostedClusters,
99+
cloudInstances,
100+
combinedClusterList,
101+
}
102+
}, [clusters, me, instances])
103+
47104
return (
48105
<Flex
49106
direction="column"
@@ -59,13 +116,22 @@ export function Clusters(): ReactElement | null {
59116
) : (
60117
<>
61118
<OverviewHeader />
62-
<Outlet />
119+
<Outlet context={ctx} />
63120
</>
64121
)}
65122
<ContactSupportToast
66-
open={showToast}
67-
onClose={() => setShowToast(false)}
123+
open={showSupportToast}
124+
onClose={() => setShowSupportToast(false)}
68125
/>
126+
<Toast
127+
show={showPluralCloudToast}
128+
marginBottom={spacing.xsmall}
129+
severity="success"
130+
position="bottom"
131+
onClose={() => setShowPluralCloudToast(false)}
132+
>
133+
Your instance was created successfully!
134+
</Toast>
69135
</Flex>
70136
)
71137
}

www/src/components/overview/clusters/SelfHostedTableCols.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import { A, Div } from 'honorable'
1111
import { Link } from 'react-router-dom'
1212
import styled, { useTheme } from 'styled-components'
1313

14-
import { Source } from '../../../generated/graphql'
14+
import { ClusterFragment, Source } from '../../../generated/graphql'
1515
import { ProviderIcon } from '../../utils/ProviderIcon'
1616

1717
import ClusterHealth from './ClusterHealth'
1818
import ClusterOwner from './ClusterOwner'
19-
import { ClusterListElement } from './types'
19+
import { ClusterListElement } from './clusterListUtils'
2020

2121
const clusterExists = (row: ClusterListElement): boolean =>
2222
row.pingedAt !== null
@@ -40,16 +40,10 @@ const sourceDisplayNames = {
4040
[Source.Demo]: 'Demo',
4141
}
4242

43-
export const ColCluster = columnHelper.accessor((row) => row.name, {
44-
id: 'cluster',
45-
meta: { gridTemplate: '3fr' },
46-
enableGlobalFilter: true,
47-
enableSorting: true,
48-
cell: ({
49-
row: {
50-
original: { id, name, provider, source, accessible, pingedAt },
51-
},
52-
}) => (
43+
export function ClusterDisplay({ cluster }: { cluster: ClusterListElement }) {
44+
const { id, name, provider, source, accessible, pingedAt } = cluster
45+
46+
return (
5347
<CellWrap>
5448
<AppIcon
5549
size="xxsmall"
@@ -75,7 +69,15 @@ export const ColCluster = columnHelper.accessor((row) => row.name, {
7569
<CellCaption>{sourceDisplayNames[source || '']}</CellCaption>
7670
</div>
7771
</CellWrap>
78-
),
72+
)
73+
}
74+
75+
export const ColCluster = columnHelper.accessor((row) => row.name, {
76+
id: 'cluster',
77+
meta: { gridTemplate: '3fr' },
78+
enableGlobalFilter: true,
79+
enableSorting: true,
80+
cell: ({ row }) => <ClusterDisplay cluster={row.original} />,
7981
header: 'Cluster',
8082
})
8183

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Table, useSetBreadcrumbs } from '@pluralsh/design-system'
2+
import { type Row } from '@tanstack/react-table'
3+
import { useNavigate, useOutletContext } from 'react-router-dom'
4+
import { CLUSTERS_OVERVIEW_BREADCRUMBS, OverviewContextType } from '../Clusters'
5+
import {
6+
allClustersCols,
7+
CombinedClusterT,
8+
CombinedClusterType,
9+
} from './AllClustersTableCols'
10+
import { PLURAL_CLOUD_INSTANCES_PATH_ABS } from '../plural-cloud/PluralCloudInstances'
11+
12+
const ALL_CLUSTERS_BREADCRUMBS = [
13+
...CLUSTERS_OVERVIEW_BREADCRUMBS,
14+
{ label: 'all', url: '/overview/clusters/all' },
15+
]
16+
17+
export function AllClusters() {
18+
useSetBreadcrumbs(ALL_CLUSTERS_BREADCRUMBS)
19+
const navigate = useNavigate()
20+
const { combinedClusterList } = useOutletContext<OverviewContextType>()
21+
return (
22+
<Table
23+
data={combinedClusterList}
24+
columns={allClustersCols}
25+
emptyStateProps={{ message: 'No clusters found' }}
26+
onRowClick={(_, { original }: Row<CombinedClusterT>) => {
27+
if (
28+
original.type === CombinedClusterType.SelfHosted &&
29+
original.accessible
30+
)
31+
navigate(`/clusters/${original.id}`)
32+
else if (original.type === CombinedClusterType.PluralCloud)
33+
navigate(PLURAL_CLOUD_INSTANCES_PATH_ABS + `/${original.id}`)
34+
}}
35+
/>
36+
)
37+
}

0 commit comments

Comments
 (0)