Skip to content

Commit c534644

Browse files
authored
Merge pull request #915 from amitamrutiya/add-widgets
Create a dashboard widgets that are common in the meshery and cloud
2 parents 521d78c + 597af1a commit c534644

29 files changed

+2408
-0
lines changed

package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"access": "public"
117117
},
118118
"dependencies": {
119+
"@layer5/meshery-design-embed": "^0.4.0",
119120
"billboard.js": "^3.14.3",
120121
"js-yaml": "^4.1.0",
121122
"lodash": "^4.17.21",
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import { ReactNode } from 'react';
2+
import { Box, Button, Card, CardActions, CardContent, Typography } from '../../../base';
3+
import { styled, useTheme } from '../../../theme';
4+
import { PrecentageLabel, SliderDiv } from '../styles';
5+
6+
interface ActionButtonCardProps {
7+
title: string;
8+
description: ReactNode;
9+
icon: ReactNode;
10+
customComponent?: ReactNode;
11+
href?: string;
12+
target?: string;
13+
onClick?: () => void;
14+
btnTitle: string;
15+
disabled?: boolean;
16+
showProgress?: boolean;
17+
actionButton?: boolean;
18+
maxDescriptionWidth?: string;
19+
completedSteps?: string[];
20+
totalSteps: number;
21+
playgroundCardBackgroundImgSrc?: string;
22+
}
23+
24+
const BoxContainer = styled(Card)<{ playgroundCardBackgroundImgSrc?: string }>(
25+
({ theme, playgroundCardBackgroundImgSrc }) => ({
26+
backgroundImage: playgroundCardBackgroundImgSrc
27+
? `url(${playgroundCardBackgroundImgSrc})`
28+
: 'none',
29+
backgroundPosition: 'right bottom',
30+
backgroundSize: 'cover',
31+
backgroundRepeat: 'no-repeat',
32+
minWidth: 285,
33+
height: '100%',
34+
position: 'relative',
35+
backgroundColor:
36+
theme.palette.mode === 'dark' ? theme.palette.background.card : theme.palette.common.white
37+
})
38+
);
39+
40+
const StyledCard = styled(Card)(({ theme }) => ({
41+
minWidth: 275,
42+
height: '100%',
43+
backgroundColor:
44+
theme.palette.mode === 'dark' ? theme.palette.background.card : theme.palette.common.white
45+
}));
46+
47+
const IconTitleWrapper = styled(Box)({
48+
display: 'flex',
49+
alignItems: 'center',
50+
gap: '0.5rem'
51+
});
52+
53+
const ContentWrapper = styled(Box)({
54+
display: 'flex',
55+
flexDirection: 'column'
56+
});
57+
58+
const DescriptionTypography = styled(Typography)<{ maxWidth?: string }>(({ theme, maxWidth }) => ({
59+
marginLeft: theme.spacing(1),
60+
marginBottom: theme.spacing(1),
61+
minHeight: '4.5rem',
62+
[theme.breakpoints.between('sm', 'lg')]: {
63+
maxWidth: maxWidth || '100%'
64+
}
65+
}));
66+
67+
const StandardDescriptionTypography = styled(Typography)({
68+
marginLeft: 8,
69+
marginBottom: 8,
70+
minHeight: '3rem'
71+
});
72+
73+
const ProgressWrapper = styled(Typography)({
74+
marginLeft: 8,
75+
marginBottom: 8
76+
});
77+
78+
const CustomComponentWrapper = styled(Box)({
79+
display: 'flex',
80+
marginLeft: 8
81+
});
82+
83+
const ActionButtonCard = ({
84+
title,
85+
description,
86+
icon,
87+
customComponent,
88+
href,
89+
onClick,
90+
btnTitle,
91+
disabled = false,
92+
showProgress = false,
93+
actionButton = true,
94+
maxDescriptionWidth = '100%',
95+
completedSteps,
96+
totalSteps,
97+
playgroundCardBackgroundImgSrc
98+
}: ActionButtonCardProps) => {
99+
const completed = completedSteps ? completedSteps.length : 0;
100+
const theme = useTheme();
101+
102+
const completedPercentage = (): number => {
103+
return Math.round((100 / totalSteps) * completed);
104+
};
105+
106+
const percentage = completedPercentage();
107+
108+
if (title === 'CLOUD NATIVE PLAYGROUND') {
109+
return (
110+
<BoxContainer playgroundCardBackgroundImgSrc={playgroundCardBackgroundImgSrc}>
111+
<CardContent
112+
style={{
113+
zIndex: 2,
114+
position: 'relative',
115+
display: 'flex',
116+
flexDirection: 'column',
117+
gap: '1rem'
118+
}}
119+
>
120+
<IconTitleWrapper>
121+
{icon}
122+
<Typography variant="h6" fontWeight="700">
123+
{title}
124+
</Typography>
125+
</IconTitleWrapper>
126+
<ContentWrapper>
127+
<DescriptionTypography maxWidth={maxDescriptionWidth}>
128+
{description}
129+
</DescriptionTypography>
130+
{showProgress && (
131+
<ProgressWrapper>
132+
<SliderDiv
133+
value={percentage}
134+
size="small"
135+
aria-label="Default"
136+
valueLabelDisplay="auto"
137+
/>
138+
<PrecentageLabel size="small" completedPercentage={percentage} theme={theme}>
139+
{`${percentage}%`}
140+
</PrecentageLabel>
141+
</ProgressWrapper>
142+
)}
143+
<CustomComponentWrapper>{customComponent}</CustomComponentWrapper>
144+
{actionButton && (
145+
<CardActions>
146+
<Button disabled={disabled} variant="contained" href={href} onClick={onClick}>
147+
{btnTitle}
148+
</Button>
149+
</CardActions>
150+
)}
151+
</ContentWrapper>
152+
</CardContent>
153+
</BoxContainer>
154+
);
155+
}
156+
157+
return (
158+
<StyledCard>
159+
<CardContent
160+
style={{
161+
zIndex: 2,
162+
position: 'relative',
163+
display: 'flex',
164+
flexDirection: 'column',
165+
gap: '1rem'
166+
}}
167+
>
168+
<IconTitleWrapper>
169+
{icon}
170+
<Typography variant="h6" fontWeight="700" component="div" sx={{ mx: 1 }}>
171+
{typeof title === 'string' ? title?.toUpperCase() : title}
172+
</Typography>
173+
</IconTitleWrapper>
174+
<ContentWrapper>
175+
<StandardDescriptionTypography>{description}</StandardDescriptionTypography>
176+
{showProgress && (
177+
<ProgressWrapper>
178+
<SliderDiv
179+
value={percentage}
180+
size="small"
181+
aria-label="Default"
182+
valueLabelDisplay="auto"
183+
/>
184+
<PrecentageLabel size="small" completedPercentage={percentage} theme={theme}>
185+
{`${percentage}%`}
186+
</PrecentageLabel>
187+
</ProgressWrapper>
188+
)}
189+
<CustomComponentWrapper>{customComponent}</CustomComponentWrapper>
190+
{actionButton && (
191+
<CardActions>
192+
<Button disabled={disabled} variant="contained" href={href} onClick={onClick}>
193+
{showProgress ? (percentage === 100 ? 'Revisit' : btnTitle) : btnTitle}
194+
</Button>
195+
</CardActions>
196+
)}
197+
</ContentWrapper>
198+
</CardContent>
199+
</StyledCard>
200+
);
201+
};
202+
203+
export default ActionButtonCard;

0 commit comments

Comments
 (0)