Skip to content

Commit

Permalink
update pod details layout
Browse files Browse the repository at this point in the history
  • Loading branch information
floreks committed Mar 26, 2024
1 parent 6ae13ba commit 9cf232b
Show file tree
Hide file tree
Showing 11 changed files with 362 additions and 96 deletions.
59 changes: 59 additions & 0 deletions assets/src/components/kubernetes/common/Containers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ReactElement } from 'react'
import { Table } from '@pluralsh/design-system'
import { createColumnHelper } from '@tanstack/react-table'

import {
Pod_Container as ContainerT,
Maybe,
} from '../../../generated/graphql-kubernetes'

const columnHelper = createColumnHelper<ContainerT>()

interface ContainersProps {
containers: Array<Maybe<ContainerT>>
}

const columns = [
// Name
columnHelper.accessor((container) => container?.name, {
id: 'name',
header: 'Name',
cell: ({ getValue }) => getValue(),
}),
// Image
columnHelper.accessor((container) => container?.image, {
id: 'image',
header: 'Image',
cell: ({ getValue }) => getValue(),
}),
// Args
columnHelper.accessor((container) => container?.args, {
id: 'args',
header: 'Args',
cell: ({ getValue }) => getValue(),
}),
// Status
columnHelper.accessor((container) => container?.status?.name, {
id: 'status',
header: 'Status',
cell: ({ getValue }) => getValue(),
}),
]

export default function Containers({
containers,
}: ContainersProps): ReactElement {
console.log(containers)

return (
<Table
data={containers}
columns={columns}
virtualizeRows
css={{
maxHeight: 'unset',
height: '100%',
}}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { createColumnHelper } from '@tanstack/react-table'
import { useMemo } from 'react'

import { ChipList } from '@pluralsh/design-system'

import { Link } from 'react-router-dom'

import {
Expand All @@ -14,14 +12,9 @@ import {
} from '../../../generated/graphql-kubernetes'
import { useDefaultColumns } from '../utils'
import { ResourceList } from '../ResourceList'

import { ClusterTinyFragment } from '../../../generated/graphql'
import { InlineLink } from '../../utils/typography/InlineLink'
import {
STORAGE_CLASSES_REL_PATH,
getResourceDetailsAbsPath,
getStorageResourceDetailsAbsPath,
} from '../../../routes/kubernetesRoutesConsts'
import { getResourceDetailsAbsPath } from '../../../routes/kubernetesRoutesConsts'

import { PVCStatusChip } from './utils'

Expand Down
184 changes: 151 additions & 33 deletions assets/src/components/kubernetes/workloads/Pod.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
import { ReactElement } from 'react'
import { useParams } from 'react-router-dom'
import { Flex } from 'honorable'
import { ReactElement, useRef } from 'react'
import { Link, useMatch, useParams } from 'react-router-dom'
import { useTheme } from 'styled-components'

import { SubTab, TabList, Table } from '@pluralsh/design-system'

import { createColumnHelper } from '@tanstack/react-table'

import { KubernetesClient } from '../../../helpers/kubernetes.client'
import {
PodQueryVariables,
Pod_PodDetail as PodT,
usePodQuery,
} from '../../../generated/graphql-kubernetes'
import LoadingIndicator from '../../utils/LoadingIndicator'
import { ScrollablePage } from '../../utils/layout/ScrollablePage'
import { SubTitle } from '../../cluster/nodes/SubTitle'
import { Metadata } from '../utils'

import { ResponsiveLayoutSidecarContainer } from '../../utils/layout/ResponsiveLayoutSidecarContainer'

import { ResponsiveLayoutPage } from '../../utils/layout/ResponsiveLayoutPage'

import { ResponsiveLayoutSpacer } from '../../utils/layout/ResponsiveLayoutSpacer'

import { LinkTabWrap } from '../../utils/Tabs'

import { getResourceDetailsAbsPath } from '../../../routes/kubernetesRoutesConsts'
import { ClusterTinyFragment } from '../../../generated/graphql'
import { InlineLink } from '../../utils/typography/InlineLink'

import { ScrollablePage } from '../../utils/layout/ScrollablePage'

import { ResponsiveLayoutContentContainer } from '../../utils/layout/ResponsiveLayoutContentContainer'

import { ResponsiveLayoutHeader } from '../../utils/layout/ResponsiveLayoutHeader'

import { ResponsivePageFullWidth } from '../../utils/layout/ResponsivePageFullWidth'

import Containers from '../common/Containers'

import PodSidecar from './PodSidecar'

const directory = [
{ path: '', label: 'Info' },
{ path: 'events', label: 'Events' },
{ path: 'raw', label: 'Raw' },
] as const

const columnHelper = createColumnHelper<any>()

const colNode = columnHelper.accessor((pod) => pod, {
id: 'mock',
header: 'Mock',
cell: ({ getValue, table }) => <div />,
})

export default function Pod(): ReactElement {
const theme = useTheme()
const { clusterId, name, namespace } = useParams()
const { data, loading } = usePodQuery({
client: KubernetesClient(clusterId ?? ''),
Expand All @@ -23,43 +67,117 @@ export default function Pod(): ReactElement {
} as PodQueryVariables,
})

const pod = data?.handleGetPodDetail
const pod = data?.handleGetPodDetail as PodT
const containers = pod?.containers
const conditions = pod?.conditions

const tabStateRef = useRef<any>(null)
const pathMatch = useMatch(`:tab/*`)
const tab = pathMatch?.params?.tab || ''
const currentTab = directory.find(({ path }) => path === tab)

if (loading) {
return <LoadingIndicator />
}

return (
<ScrollablePage
heading="Info"
// headingContent={<ViewLogsButton metadata={pod?.metadata} />}
>
<Flex
direction="column"
gap="xlarge"
<ResponsiveLayoutPage>
<ResponsiveLayoutPage
css={{
display: 'flex',
flexDirection: 'column',
padding: 0,
paddingBottom: theme.spacing.large,

'> div': {
paddingLeft: 0,
paddingTop: 0,
},
}}
>
<section>
<SubTitle>Containers</SubTitle>
{/* <ContainersList */}
{/* containers={containers} */}
{/* containerStatuses={containerStatuses} */}
{/* initContainers={initContainers} */}
{/* initContainerStatuses={initContainerStatuses} */}
{/* namespace={pod?.objectMeta.namespace ?? ''} */}
{/* podName={pod?.objectMeta.name ?? ''} */}
{/* /> */}
</section>
<section>
<SubTitle>Conditions</SubTitle>
{/* <PodConditions conditions={conditions} /> */}
</section>
<section>
<SubTitle>Metadata</SubTitle>
{/* <PodMetadata pod={pod} /> */}
</section>
</Flex>
</ScrollablePage>
<ResponsiveLayoutHeader
css={{
paddingRight: theme.spacing.xlarge,
overflow: 'hidden',
}}
>
<div
css={{
height: '100%',
width: '100%',
maxWidth: theme.breakpoints.desktopLarge,
marginRight: 'auto',
marginLeft: 'auto',
}}
>
<TabList
scrollable
gap="xxsmall"
stateRef={tabStateRef}
stateProps={{
orientation: 'horizontal',
selectedKey: currentTab?.path,
}}
marginRight="medium"
paddingBottom="xxsmall"
>
{directory.map(({ label, path }) => (
<LinkTabWrap
subTab
key={path}
textValue={label}
to=""
>
<SubTab
key={path}
textValue={label}
>
{label}
</SubTab>
</LinkTabWrap>
))}
</TabList>
</div>
</ResponsiveLayoutHeader>
<ResponsivePageFullWidth
noPadding
maxContentWidth={theme.breakpoints.desktopLarge}
>
<div
css={{
display: 'flex',
flexDirection: 'column',
height: '100%',
gap: theme.spacing.large,
}}
>
<section>
<SubTitle>Containers</SubTitle>
<Containers containers={containers} />
</section>
<section>
<SubTitle>Conditions</SubTitle>
<Table
data={[]}
columns={[colNode]}
virtualizeRows
css={{
maxHeight: 'unset',
height: '100%',
}}
/>
</section>
<section>
<SubTitle>Metadata</SubTitle>
<Metadata objectMeta={pod?.objectMeta} />
</section>
</div>
</ResponsivePageFullWidth>
</ResponsiveLayoutPage>
<ResponsiveLayoutSpacer />
<ResponsiveLayoutSidecarContainer>
<PodSidecar pod={pod} />
</ResponsiveLayoutSidecarContainer>
</ResponsiveLayoutPage>
)
}
43 changes: 43 additions & 0 deletions assets/src/components/kubernetes/workloads/PodSidecar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ReactElement } from 'react'

import { useTheme } from 'styled-components'

import { Sidecar, SidecarItem } from '@pluralsh/design-system'

import { A } from 'honorable'
import { Link } from 'react-router-dom'

import { Pod_PodDetail as PodT } from '../../../generated/graphql-kubernetes'
import { StatusChip } from '../../cluster/TableElements'
import { ReadinessT } from '../../../utils/status'

interface PodSidecarProps {
pod: Nullable<PodT>
}

export default function PodSidecar({ pod }: PodSidecarProps): ReactElement {
return (
<Sidecar heading="Metadata">
<SidecarItem heading="Pod name">{pod?.objectMeta.name}</SidecarItem>
<SidecarItem heading="Namespace">
{pod?.objectMeta?.namespace}
</SidecarItem>
<SidecarItem heading="IP">{pod?.podIP}</SidecarItem>
<SidecarItem heading="Parent node">
<A
as={Link}
to={`/nodes/${pod?.nodeName}`}
inline
>
{pod?.nodeName}
</A>
</SidecarItem>
<SidecarItem heading="Service account">
{pod?.serviceAccountName}
</SidecarItem>
<SidecarItem heading="Status">
<StatusChip readiness={pod?.podPhase as ReadinessT} />
</SidecarItem>
</Sidecar>
)
}
9 changes: 9 additions & 0 deletions assets/src/components/utils/layout/ResponsiveLayoutHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from 'styled-components'

export const ResponsiveLayoutHeader = styled.div(({ theme }) => ({
display: 'flex',
width: '100%',
overflowX: 'hidden',
paddingBottom: theme.spacing.large,
flexGrow: 1,
}))
Loading

0 comments on commit 9cf232b

Please sign in to comment.