Skip to content

Commit

Permalink
feat: Truncate and reduce label sizes + Responsive enhancements (#266)
Browse files Browse the repository at this point in the history
  • Loading branch information
dogmar committed Feb 9, 2023
1 parent 7fcb097 commit 4c85be2
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 61 deletions.
2 changes: 2 additions & 0 deletions assets/src/components/apps/Apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ export default function Apps() {
return (
<ResponsivePageFullWidth
heading="Apps"
// 1528 is magic number for content width when screen is 1640px wide
maxContentWidth={1528}
headingContent={(
<>
<Flex grow={1} />
Expand Down
3 changes: 2 additions & 1 deletion assets/src/components/apps/app/components/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default function Component({
<Card
display="flex"
gap="small"
alignItems="center"
paddingHorizontal="xsmall"
paddingVertical="xxsmall"
grow={1}
Expand All @@ -37,7 +38,7 @@ export default function Component({
type="tertiary"
/>
<Flex
align="center"
align="baseline"
gap="small"
flexShrink={1}
overflow="hidden"
Expand Down
67 changes: 45 additions & 22 deletions assets/src/components/cluster/LabelsAnnotations.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Card, CardProps, Chip } from '@pluralsh/design-system'
import { CardProps, Chip, ChipList } from '@pluralsh/design-system'
import { Div, Flex } from 'honorable'
import { ReactNode } from 'react'
import type { LabelPair, Metadata as MetadataT } from 'generated/graphql'
import type { LabelPair, Maybe, Metadata as MetadataT } from 'generated/graphql'
import { CARD_CONTENT_MAX_WIDTH, MetadataCard } from 'components/utils/Metadata'
import { useTheme } from 'styled-components'

export const mapify = tags => tags.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {})

Expand Down Expand Up @@ -34,45 +36,66 @@ export function LabelsAnnotationsRow({

export function LabelsAnnotationsTag({ name, value }: LabelPair) {
return (
<Chip>
<Chip size="small">
{name}
{value && `: ${value}`}
</Chip>
)
}

function renderLabel(label: Maybe<LabelPair>) {
return (
<>
{label?.name}
{label?.value && `: ${label.value}`}
</>
)
}

export function LabelsAnnotations({
metadata: { labels, annotations },
...props
}: {
metadata: MetadataT
} & CardProps) {
const theme = useTheme()

const hasLabels = labels && labels?.length > 0
const hasAnnotations = annotations && annotations.length > 0
const hasData = hasLabels || hasAnnotations

if (!hasData) {
return null
}

return (
<Card
padding="xlarge"
{...props}
>
<MetadataCard {...props}>
<Flex
direction="column"
gap="xlarge"
maxWidth={(CARD_CONTENT_MAX_WIDTH - theme.spacing.xlarge * 3) / 2}
>
<LabelsAnnotationsRow name="Labels">
{labels?.map(label => (
<LabelsAnnotationsTag
key={label?.name}
{...label}
{hasLabels && (
<LabelsAnnotationsRow name="Labels">
<ChipList
size="small"
limit={8}
values={labels}
transformValue={renderLabel}
/>
))}
</LabelsAnnotationsRow>
<LabelsAnnotationsRow name="Annotations">
{annotations?.map(annotation => (
<LabelsAnnotationsTag
key={annotation?.name}
{...annotation}
</LabelsAnnotationsRow>
)}
{hasAnnotations && (
<LabelsAnnotationsRow name="Annotations">
<ChipList
size="small"
limit={8}
values={annotations}
transformValue={renderLabel}
/>
))}
</LabelsAnnotationsRow>
</LabelsAnnotationsRow>
)}
</Flex>
</Card>
</MetadataCard>
)
}
3 changes: 2 additions & 1 deletion assets/src/components/cluster/containers/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default function Container() {

const match = useMatch('/pods/:namespace/:name/shell/:container/:subpath')
const subpath = match?.params?.subpath || ''
const currentTab = DIRECTORY.find(({ path }) => path === subpath)

const { data, error } = useQuery<{ pod: Pod }>(POD_INFO_Q, {
variables: { name, namespace },
Expand Down Expand Up @@ -148,7 +149,7 @@ export default function Container() {

return (
<ResponsivePageFullWidth
scrollable={false}
scrollable={currentTab?.path === 'metadata'}
heading={containerName}
headingContent={(
<Flex gap="medium">
Expand Down
2 changes: 1 addition & 1 deletion assets/src/components/cluster/nodes/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default function Node() {
stateRef={tabStateRef}
as={(
<ResponsivePageFullWidth
scrollable={(currentTab?.label ?? 'Info') === 'Info'}
scrollable={(currentTab?.label ?? 'Info') === 'Info' || currentTab?.label === 'Metadata'}
heading={name}
headingContent={(
<HeadingTabList
Expand Down
48 changes: 39 additions & 9 deletions assets/src/components/utils/Metadata.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,55 @@
import { Card, SidecarProps } from '@pluralsh/design-system'
import { Div, Flex, H2 } from 'honorable'
import {
CardProps,
Div,
Flex,
H2,
} from 'honorable'
import { Children, forwardRef } from 'react'
import styled from 'styled-components'
import { makeGrid } from 'utils/makeGrid'

const MAX_COLS = 4

export const MetadataGridCard = styled(Card)<{$maxCols:number}>(({ theme, maxCols = MAX_COLS }) => ({
...makeGrid({ maxCols, minColWidth: 186, gap: theme.spacing.xlarge }),
padding: theme.spacing.large,
export const CARD_CONTENT_MAX_WIDTH = 1526

const MetadataGridGrid = styled.div<{ maxCols: number }>(({ theme, maxCols = MAX_COLS }) => ({
...makeGrid({
maxCols,
minColWidth: 186,
gap: theme.spacing.xlarge,
}),
}))

export function MetadataCard({ children, ...props }: CardProps) {
return (
<Card
display="flex"
justifyContent="center"
{...props}
>
{/* 1526 is magic number which is the card's width when screen is 1940px wide */}
<Div
maxWidth={CARD_CONTENT_MAX_WIDTH}
width="100%"
padding="xlarge"
>{children}
</Div>
</Card>
)
}

export function MetadataGrid(props) {
const numChildren = Children.count(props.children)
const maxCols = (numChildren < MAX_COLS) ? numChildren : MAX_COLS
const maxCols = numChildren < MAX_COLS ? numChildren : MAX_COLS

return (
<MetadataGridCard
maxCols={maxCols}
{...props}
/>
<MetadataCard>
<MetadataGridGrid
maxCols={maxCols}
{...props}
/>
</MetadataCard>
)
}

Expand Down
14 changes: 1 addition & 13 deletions assets/src/components/utils/layout/ResponsivePageFullWidth.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ResponsiveLayoutPage } from 'components/utils/layout/ResponsiveLayoutPage'
import { useTheme } from 'styled-components'
import { ComponentProps } from 'react'

import { ScrollablePage } from './ScrollablePage'
Expand All @@ -9,8 +8,6 @@ export function ResponsivePageFullWidth({
children,
...props
}: ComponentProps<typeof ScrollablePage>) {
const theme = useTheme()

return (
<ResponsiveLayoutPage
flexDirection="column"
Expand All @@ -23,16 +20,7 @@ export function ResponsivePageFullWidth({
>
<ScrollablePage
scrollable={scrollable}
{...(scrollable
? {
marginRight: 'large',
contentStyles: {
paddingRight: theme.spacing.large - 6,
paddingTop: theme.spacing.medium,
paddingBottom: theme.spacing.large,
},
}
: {})}
fullWidth
{...props}
>
{children}
Expand Down
61 changes: 48 additions & 13 deletions assets/src/components/utils/layout/ScrollablePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,38 @@ import ConsolePageTitle from './ConsolePageTitle'
const ScrollablePageContent = styled.div<{
scrollable?: boolean
extraStyles?: CSSProperties
}>(({ theme, scrollable, extraStyles }) => ({
maxContentWidth?: number
fullWidth?: boolean
}>(({
theme, scrollable, extraStyles, maxContentWidth, fullWidth,
}) => ({
position: 'relative',
height: '100%',
maxHeight: '100%',
width: '100%',
overflowY: scrollable ? 'auto' : 'hidden',
overflowX: 'hidden',
paddingTop: theme.spacing.medium,
paddingRight: scrollable ? theme.spacing.small : 0,
paddingBottom: scrollable ? theme.spacing.xxlarge : theme.spacing.large,
...(extraStyles ?? {}),
position: 'relative',
...(scrollable ? { scrollbarGutter: 'stable' } : {}),
...(scrollable && fullWidth
? {
paddingRight: theme.spacing.large - 6,
}
: {}),
'& > .widthLimiter': {
width: '100%',
paddingTop: theme.spacing.medium,
paddingBottom: scrollable ? theme.spacing.xxlarge : theme.spacing.large,
...(!scrollable
? {
height: '100%',
}
: {}),
...(maxContentWidth
? { maxWidth: maxContentWidth, marginLeft: 'auto', marginRight: 'auto' }
: {}),
...(extraStyles ?? {}),
},
}))

const ScrollShadow = styled.div(({ theme }) => ({
Expand All @@ -38,32 +59,46 @@ export function ScrollablePage({
contentStyles,
children,
scrollable = true,
maxContentWidth,
fullWidth,
...props
}: {
heading: ReactNode
headingContent?: ReactNode | undefined
contentStyles?: CSSProperties
children: ReactNode
scrollable?: boolean
maxContentWidth?: number
fullWidth?: boolean
} & FlexProps) {
return (
<>
{heading && (
<Div position="relative">
{scrollable && <ScrollShadow />}
<ConsolePageTitle
heading={heading}
{...props}
<Div paddingRight={scrollable && fullWidth ? 'large' : undefined}>
<Div
position="relative"
width="100%"
marginLeft="auto"
marginRight="auto"
maxWidth={maxContentWidth}
>
{headingContent}
</ConsolePageTitle>
{scrollable && <ScrollShadow />}
<ConsolePageTitle
heading={heading}
{...props}
>
{headingContent}
</ConsolePageTitle>
</Div>
</Div>
)}
<ScrollablePageContent
scrollable={scrollable}
extraStyles={contentStyles}
maxContentWidth={maxContentWidth}
fullWidth={fullWidth}
>
{children}
<div className="widthLimiter">{children}</div>
</ScrollablePageContent>
</>
)
Expand Down
11 changes: 10 additions & 1 deletion assets/src/utils/makeGrid.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { CSSProperties } from 'styled-components'

export function makeGrid({
gap,
maxCols,
minColWidth,
maxColWidth,
}: {
gap: number
maxCols: number
minColWidth: number
}) {
maxColWidth?: number
}): CSSProperties {
const gapCount = maxCols - 1
const totalGapWidth = gapCount * gap

return {
display: 'grid',
gridTemplateColumns: `repeat(auto-fill, minmax(max(${minColWidth}px, calc((100% - ${totalGapWidth}px) / ${maxCols})), 1fr))`,
gap,
...(maxColWidth
? {
maxWidth: maxCols * maxColWidth + totalGapWidth,
}
: {}),
}
}

0 comments on commit 4c85be2

Please sign in to comment.