Skip to content

Commit 0fbe1be

Browse files
authored
Ri-7465 auto discovery layout (#5181)
Refactor auto-discovery layout and extract column definitions (RI-7465) Refactor Redis Cloud/Cluster discovery UI by extracting column definitions into reusable components. Use enums for column IDs/titles. Add Storybook stories with factory mocks. Extract custom hooks. Align UI with Figma designs. Add testing factories.
1 parent c2bebf6 commit 0fbe1be

File tree

230 files changed

+6320
-2949
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+6320
-2949
lines changed

.storybook/preview-head.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
display: flex;
2020
flex-direction: column;
2121
}
22-
22+
2323
.sbdocs-wrapper div:has(>div>.toc-wrapper){
2424
width:14rem;
2525
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react'
2+
import { Col, FlexItem } from 'uiSrc/components/base/layout/flex'
3+
import { Text } from 'uiSrc/components/base/text'
4+
5+
import type { EmptyStateProps } from './EmptyState.types'
6+
7+
export const EmptyState = ({ message }: EmptyStateProps) => (
8+
<Col centered full>
9+
<FlexItem padding={13}>
10+
<Text size="L">{message}</Text>
11+
</FlexItem>
12+
</Col>
13+
)
14+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface EmptyStateProps {
2+
message: string
3+
}
4+
Lines changed: 4 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,5 @@
1-
import React from 'react'
2-
import styled from 'styled-components'
3-
import { Checkbox } from 'uiSrc/components/base/forms/checkbox/Checkbox'
4-
import { Text, Title } from 'uiSrc/components/base/text'
5-
import { Theme } from 'uiSrc/components/base/theme/types'
6-
import { Col, FlexItem } from 'uiSrc/components/base/layout/flex'
7-
import { FormField } from 'uiSrc/components/base/forms/FormField'
8-
import { IconButton } from 'uiSrc/components/base/forms/buttons'
9-
import { CopyIcon } from 'uiSrc/components/base/icons'
1+
export * from './styles'
102

11-
export const PageTitle = styled(Title).attrs({
12-
size: 'L',
13-
})`
14-
padding-bottom: ${({ theme }: { theme: Theme }) => theme.core.space.space050};
15-
`
16-
export const PageSubTitle = styled(Text).attrs({
17-
size: 'S',
18-
component: 'span',
19-
})`
20-
padding-bottom: ${({ theme }: { theme: Theme }) => theme.core.space.space100};
21-
`
22-
export const SearchContainer = styled(FlexItem)`
23-
max-width: 100%;
24-
padding-top: ${({ theme }: { theme: Theme }) => theme.core.space.space150};
25-
`
26-
export const SearchForm = styled(FormField)`
27-
width: 266px;
28-
`
29-
export const Footer = styled(FlexItem).attrs<{
30-
grow?: boolean | number
31-
padding?: React.ComponentProps<typeof FlexItem>['padding']
32-
}>(({ grow, padding }) => ({
33-
grow: grow ?? false,
34-
padding: padding ?? 6,
35-
}))`
36-
border-top: 1px solid
37-
${({ theme }: { theme: Theme }) => theme.semantic.color.border.neutral400};
38-
`
39-
40-
export const DatabaseContainer = styled(Col)`
41-
position: relative;
42-
padding: ${({ theme }: { theme: Theme }) =>
43-
`${theme.core.space.space250} ${theme.core.space.space200} 0 ${theme.core.space.space200}`};
44-
@media only screen and (min-width: 768px) {
45-
padding: ${({ theme }: { theme: Theme }) =>
46-
`${theme.core.space.space400} ${theme.core.space.space200} 0 ${theme.core.space.space400}`};
47-
max-width: calc(100vw - 95px);
48-
}
49-
`
50-
51-
export const DatabaseWrapper = styled.div`
52-
height: auto;
53-
scrollbar-width: thin;
54-
//overflow: auto;
55-
padding: 1px 1px 75px;
56-
position: relative;
57-
background-color: ${({ theme }: { theme: Theme }) =>
58-
theme.semantic.color.background.neutral100};
59-
flex-grow: 1;
60-
overflow: hidden;
61-
`
62-
export const SelectAllCheckbox = styled(Checkbox)`
63-
& svg {
64-
margin: 0 !important;
65-
}
66-
`
67-
export const CellText = styled(Text).attrs({
68-
size: 'M',
69-
component: 'span',
70-
})`
71-
max-width: 100%;
72-
display: inline-block;
73-
width: auto;
74-
white-space: nowrap;
75-
text-overflow: ellipsis;
76-
overflow: hidden;
77-
`
78-
79-
export const CopyPublicEndpointText = styled(CellText)`
80-
vertical-align: top;
81-
`
82-
83-
export const StatusColumnText = styled(CellText)`
84-
text-transform: capitalize;
85-
`
86-
export const CopyBtn = styled(IconButton).attrs({
87-
icon: CopyIcon,
88-
size: 'L',
89-
})`
90-
margin-left: 15px;
91-
opacity: 0;
92-
height: 0;
93-
transition: opacity 0.25s ease-in-out;
94-
`
95-
96-
export const CopyTextContainer = styled.div`
97-
height: 24px;
98-
line-height: 24px;
99-
width: auto;
100-
max-width: 100%;
101-
padding-right: 34px;
102-
position: relative;
103-
* {
104-
}
105-
106-
&:hover ${CopyBtn} {
107-
opacity: 1;
108-
height: auto;
109-
}
110-
`
3+
export { Header } from './Header'
4+
export { EmptyState } from './EmptyState'
5+
export type { EmptyStateProps } from './EmptyState.types'
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import styled from 'styled-components'
2+
import { Checkbox } from 'uiSrc/components/base/forms/checkbox/Checkbox'
3+
import { Text, Title } from 'uiSrc/components/base/text'
4+
import { Theme } from 'uiSrc/components/base/theme/types'
5+
import { Col, FlexItem } from 'uiSrc/components/base/layout/flex'
6+
import { FormField } from 'uiSrc/components/base/forms/FormField'
7+
import { IconButton } from 'uiSrc/components/base/forms/buttons'
8+
import { CopyIcon } from 'uiSrc/components/base/icons'
9+
10+
export const PageTitle = styled(Title).attrs({
11+
size: 'L',
12+
})`
13+
padding-bottom: ${({ theme }: { theme: Theme }) => theme.core.space.space050};
14+
`
15+
export const PageSubTitle = styled(Text).attrs({
16+
size: 'S',
17+
component: 'span',
18+
})`
19+
padding-bottom: ${({ theme }: { theme: Theme }) => theme.core.space.space100};
20+
`
21+
export const SearchContainer = styled(FlexItem)`
22+
max-width: 100%;
23+
padding-top: ${({ theme }: { theme: Theme }) => theme.core.space.space150};
24+
`
25+
export const SearchForm = styled(FormField)`
26+
width: 266px;
27+
`
28+
export const Footer = styled(FlexItem).attrs<{
29+
grow?: boolean | number
30+
padding?: React.ComponentProps<typeof FlexItem>['padding']
31+
}>(({ grow, padding }) => ({
32+
grow: grow ?? false,
33+
padding: padding ?? 6,
34+
}))`
35+
border-top: 1px solid
36+
${({ theme }: { theme: Theme }) => theme.semantic.color.border.neutral400};
37+
`
38+
39+
export const DatabaseContainer = styled(Col)`
40+
position: relative;
41+
padding: ${({ theme }: { theme: Theme }) =>
42+
`${theme.core.space.space250} ${theme.core.space.space200} 0 ${theme.core.space.space200}`};
43+
@media only screen and (min-width: 768px) {
44+
padding: ${({ theme }: { theme: Theme }) =>
45+
`${theme.core.space.space400} ${theme.core.space.space200} 0 ${theme.core.space.space400}`};
46+
max-width: calc(100vw - 95px);
47+
}
48+
`
49+
50+
export const DatabaseWrapper = styled.div`
51+
height: auto;
52+
scrollbar-width: thin;
53+
padding: ${({ theme }: { theme: Theme }) => theme.core.space.space010};
54+
position: relative;
55+
background-color: ${({ theme }: { theme: Theme }) =>
56+
theme.semantic.color.background.neutral100};
57+
overflow: hidden;
58+
`
59+
export const SelectAllCheckbox = styled(Checkbox)`
60+
& svg {
61+
margin: 0 !important;
62+
}
63+
`
64+
export const CellText = styled(Text).attrs({
65+
size: 'M',
66+
component: 'span',
67+
})`
68+
max-width: 100%;
69+
display: inline-block;
70+
width: auto;
71+
white-space: nowrap;
72+
text-overflow: ellipsis;
73+
overflow: hidden;
74+
`
75+
76+
export const CopyPublicEndpointText = styled(CellText)`
77+
vertical-align: top;
78+
`
79+
80+
export const StatusColumnText = styled(CellText)`
81+
text-transform: capitalize;
82+
`
83+
export const CopyBtn = styled(IconButton).attrs({
84+
icon: CopyIcon,
85+
size: 'L',
86+
})`
87+
margin-left: 15px;
88+
opacity: 0;
89+
height: 0;
90+
transition: opacity 0.25s ease-in-out;
91+
`
92+
93+
export const CopyTextContainer = styled.div`
94+
height: 24px;
95+
line-height: 24px;
96+
width: auto;
97+
max-width: 100%;
98+
padding-right: 34px;
99+
position: relative;
100+
* {
101+
}
102+
103+
&:hover ${CopyBtn} {
104+
opacity: 1;
105+
height: auto;
106+
}
107+
`

redisinsight/ui/src/components/base/display/loader/Loader.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import React, { ComponentProps } from 'react'
2-
32
import { Loader as RedisLoader } from '@redis-ui/components'
4-
import { useTheme, theme } from '@redis-ui/styles'
5-
6-
type Space = typeof theme.core.space
3+
import { useTheme } from '@redis-ui/styles'
4+
import { Theme } from 'uiSrc/components/base/theme/types'
75

86
export type RedisLoaderProps = ComponentProps<typeof RedisLoader>
97

10-
const convertSizeToPx = (tShirtSize: string, space: Space) => {
8+
const convertSizeToPx = (tShirtSize: string, space: Theme['core']['space']) => {
119
switch (tShirtSize.toLowerCase()) {
1210
case 's':
1311
return space.space050

redisinsight/ui/src/components/base/layout/list/list.styles.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212

1313
import { AllIconsType } from 'uiSrc/components/base/icons/RiIcon'
1414
import { IconProps } from 'uiSrc/components/base/icons'
15+
import { Theme } from 'uiSrc/components/base/theme/types'
1516

1617
export const ListClassNames = {
1718
listItem: 'RI-list-group-item',
@@ -25,9 +26,6 @@ export const ListClassNames = {
2526

2627
export const MAX_FORM_WIDTH = 400
2728

28-
export const GAP_SIZES = ['none', 's', 'm'] as const
29-
export type ListGroupGapSize = (typeof GAP_SIZES)[number]
30-
3129
export type ListGroupProps = HTMLAttributes<HTMLUListElement> & {
3230
className?: string
3331
/**
@@ -40,7 +38,7 @@ export type ListGroupProps = HTMLAttributes<HTMLUListElement> & {
4038
* Spacing between list items
4139
* @default s
4240
*/
43-
gap?: ListGroupGapSize
41+
gap?: keyof typeof listStyles.gap
4442

4543
/**
4644
* Sets the max-width of the page.
@@ -55,14 +53,12 @@ export type ListGroupProps = HTMLAttributes<HTMLUListElement> & {
5553

5654
export const listStyles = {
5755
gap: {
58-
none: css`
59-
gap: 0;
60-
`,
56+
none: 'gap: 0;',
6157
s: css`
62-
gap: var(--gap-s);
58+
gap: ${({ theme }: { theme: Theme }) => theme.core.space.space100};
6359
`,
6460
m: css`
65-
gap: var(--gap-m);
61+
gap: ${({ theme }: { theme: Theme }) => theme.core.space.space150};
6662
`,
6763
},
6864
flush: css`
@@ -78,7 +74,7 @@ export const listStyles = {
7874

7975
export const StyledGroup = styled.ul<
8076
Omit<ListGroupProps, 'gap' | 'flush' | 'maxWidth'> & {
81-
$gap?: ListGroupGapSize
77+
$gap?: keyof typeof listStyles.gap
8278
$flush?: boolean
8379
}
8480
>`

redisinsight/ui/src/components/base/tooltip/HoverContent.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ interface RiTooltipContentProps {
88
content: React.ReactNode
99
}
1010

11-
export const HoverContent = ({ title, content }: RiTooltipContentProps) => (
12-
<Col gap="s">
13-
{title && <Title size="XS">{title}</Title>}
14-
{content}
15-
</Col>
16-
)
11+
export const HoverContent = ({ title, content }: RiTooltipContentProps) => {
12+
return (
13+
<Col gap="s">
14+
{typeof title === 'string' ? <Title size="XS">{title}</Title> : title}
15+
{content}
16+
</Col>
17+
)
18+
}

0 commit comments

Comments
 (0)