Skip to content

Commit 9e1cbae

Browse files
authored
Merge branch 'master' into fix/faheemonhub/update-meshery-cloud-design
Signed-off-by: TheFaheem <[email protected]>
2 parents 39ca988 + 1c32b4d commit 9e1cbae

File tree

32 files changed

+4834
-2471
lines changed

32 files changed

+4834
-2471
lines changed

package-lock.json

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

package.json

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,33 +73,18 @@
7373
"redux": "^5.0.1",
7474
"rehype-raw": "^6.1.1",
7575
"remark-gfm": "^3.0.1",
76+
"rollup": "^4.34.8",
7677
"ts-jest": "^29.1.1",
7778
"tsup": "^8.2.4",
7879
"typescript": "^5.3.3"
7980
},
8081
"peerDependencies": {
81-
"@emotion/react": "^11.11.3",
82-
"@emotion/styled": "^11.11.0",
83-
"@mui/material": "^5.15.11",
8482
"@xstate/react": "^4.1.1",
85-
"lodash": "^4.17.21",
86-
"react": ">=17",
87-
"react-dom": ">=17",
83+
"react": "^17.0.2 || ^18.3.1",
84+
"react-dom": "^17.0.2 || ^18.3.1",
8885
"xstate": "^5.18.2"
8986
},
9087
"peerDependenciesMeta": {
91-
"lodash": {
92-
"optional": true
93-
},
94-
"@emotion/react": {
95-
"optional": true
96-
},
97-
"@emotion/styled": {
98-
"optional": true
99-
},
100-
"@mui/material": {
101-
"optional": true
102-
},
10388
"react": {
10489
"optional": true
10590
},
@@ -111,15 +96,18 @@
11196
"access": "public"
11297
},
11398
"dependencies": {
99+
"@emotion/react": "^11.11.3",
100+
"@emotion/styled": "^11.11.0",
114101
"@layer5/meshery-design-embed": "^0.4.0",
102+
"@mui/material": "^5.15.11",
103+
"@types/mui-datatables": "*",
115104
"billboard.js": "^3.14.3",
116105
"js-yaml": "^4.1.0",
117106
"lodash": "^4.17.21",
118107
"moment": "^2.30.1",
108+
"mui-datatables": "*",
119109
"re-resizable": "^6.10.3",
120110
"react-draggable": "^4.4.6",
121-
"react-share": "^5.1.0",
122-
"mui-datatables": "*",
123-
"@types/mui-datatables": "*"
111+
"react-share": "^5.1.0"
124112
}
125-
}
113+
}

src/actors/eventBus.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ export interface EventBusEvent<Type extends string, Data = unknown> {
1111
export type EventType<T> = T extends EventBusEvent<infer Type, any> ? Type : never;
1212

1313
// Helper type to extract payload type for a given event type
14-
export type DataType<T, Type extends string> = T extends EventBusEvent<Type, infer Data>
15-
? Data
16-
: never;
14+
export type DataType<T, Type extends string> =
15+
T extends EventBusEvent<Type, infer Data> ? Data : never;
1716

1817
// Generic EventBus class
1918
export class EventBus<T extends EventBusEvent<string, any>> {

src/custom/CatalogDesignTable/AuthorCell.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ const AuthorCell: React.FC<AuthorCellProps> = ({
2323
firstName && lastName
2424
? `${firstName} ${lastName}`
2525
: firstName
26-
? firstName
27-
: lastName
28-
? lastName
29-
: '';
26+
? firstName
27+
: lastName
28+
? lastName
29+
: '';
3030

3131
return (
3232
<Box sx={{ '& > img': { mr: 2, flexShrink: 0 } }}>

src/custom/CatalogDesignTable/CatalogDesignTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ export const CatalogDesignsTable: React.FC<CatalogDesignsTableProps> = ({
212212
tableBackgroundColor
213213
? tableBackgroundColor
214214
: theme.palette.mode === 'light'
215-
? theme.palette.background.default
216-
: theme.palette.background.secondary
215+
? theme.palette.background.default
216+
: theme.palette.background.secondary
217217
}
218218
/>
219219
</ErrorBoundary>

src/custom/ChapterCard/style.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ALABASTER_WHITE, MIDNIGHT_BLACK } from '../../theme';
55
export const ChapterCardWrapper = styled('div')(({ theme }) => ({
66
transition: '0.8s cubic-bezier(0.2, 0.8, 0.2, 1)',
77
padding: '1rem 1.25rem',
8-
width: '64rem',
8+
width: '100%',
99
backgroundColor: theme.palette.mode === 'light' ? ALABASTER_WHITE : MIDNIGHT_BLACK,
1010
display: 'flex',
1111
border: `1px solid ${
@@ -45,15 +45,9 @@ export const ChapterDescription = styled('div')({
4545
},
4646
'@media screen and (max-width: 650px)': {
4747
p: {
48-
whiteSpace: 'nowrap',
48+
whiteSpace: 'normal',
4949
overflow: 'hidden',
50-
textOverflow: 'ellipsis',
51-
width: '75vw'
52-
}
53-
},
54-
'@media screen and (max-width: 650px) and (min-width: 300px)': {
55-
p: {
56-
width: '68vw'
50+
textOverflow: 'ellipsis'
5751
}
5852
}
5953
});
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import { ExpandMore } from '@mui/icons-material';
2+
import { MouseEvent, useState } from 'react';
3+
import { Avatar, AvatarGroup, Popover, Typography } from '../../base';
4+
import { iconSmall } from '../../constants/iconsSizes';
5+
import { styled, useTheme } from '../../theme';
6+
import { DARK_TEAL_BLUE } from '../../theme/colors/colors';
7+
import { CustomTooltip } from '../CustomTooltip';
8+
9+
/**
10+
* CollaboratorAvatarGroup is a component that displays a group of user avatars with a popup for additional users.
11+
*
12+
* @component
13+
* @example
14+
* ```tsx
15+
* const users = {
16+
* 'client1': {
17+
* name: 'John Doe',
18+
* avatar_url: 'https://example.com/avatar1.jpg',
19+
* border_color: '#00B39F',
20+
* user_id: 'user123'
21+
* }
22+
* };
23+
*
24+
* <CollaboratorAvatarGroup
25+
* users={users}
26+
* providerUrl="https://redirect.com"
27+
* />
28+
* ```
29+
*/
30+
31+
/**
32+
* User object structure representing a collaborator
33+
* @interface User
34+
* @property {string} name - Display name of the user
35+
* @property {string} avatar_url - URL to the user's avatar image
36+
* @property {string} border_color - Color code for the avatar border (e.g., '#00B39F')
37+
* @property {string} user_id - Unique identifier for the user
38+
*/
39+
interface User {
40+
name: string;
41+
avatar_url: string;
42+
border_color: string;
43+
user_id: string;
44+
}
45+
46+
/**
47+
* Collection of users mapped by their client IDs
48+
* @interface Users
49+
* @property {User} [clientID] - User object mapped to their client ID
50+
*/
51+
interface Users {
52+
[clientID: string]: User;
53+
}
54+
55+
/**
56+
* Props for the CollaboratorAvatarGroup component
57+
* @interface CollaboratorAvatarGroupProps
58+
* @property {Users} users - Object containing user information mapped by client IDs
59+
* @property {string} providerUrl - Base URL of the provider (e.g., 'https://github.com')
60+
*/
61+
interface CollaboratorAvatarGroupProps {
62+
users: Users;
63+
providerUrl: string;
64+
}
65+
66+
interface StyledAvatarProps {
67+
borderColor: string;
68+
}
69+
const StyledAvatar = styled(Avatar)<StyledAvatarProps>(({ theme, borderColor }) => {
70+
return {
71+
width: theme.spacing(4),
72+
height: theme.spacing(4),
73+
cursor: 'pointer',
74+
border: `1.5px solid ${borderColor || theme.palette.common.white} !important`
75+
};
76+
});
77+
78+
const MoreAvatarButton = styled('div')(({ theme }) => ({
79+
width: theme.spacing(4.5),
80+
height: theme.spacing(4.5),
81+
border: `1.5px solid ${theme.palette.common.white}`,
82+
borderRadius: '50%',
83+
background: DARK_TEAL_BLUE,
84+
display: 'flex',
85+
justifyContent: 'center',
86+
alignItems: 'center',
87+
marginLeft: '-10px',
88+
zIndex: 0,
89+
'&:hover': {
90+
cursor: 'pointer'
91+
}
92+
}));
93+
94+
const PopupAvatarWrapper = styled('div')({
95+
display: 'flex',
96+
alignItems: 'center',
97+
padding: '5px 15px 5px 10px',
98+
'&:hover': {
99+
cursor: 'pointer',
100+
background: '#cecece80 !important'
101+
}
102+
});
103+
104+
const UserName = styled(Typography)({
105+
marginLeft: '10px'
106+
});
107+
108+
const StyledPopover = styled(Popover)(() => ({
109+
'& .MuiPopover-paper': {
110+
marginTop: '10px',
111+
maxHeight: '331px'
112+
}
113+
}));
114+
115+
const CollaboratorAvatarGroup = ({
116+
users,
117+
providerUrl
118+
}: CollaboratorAvatarGroupProps): JSX.Element => {
119+
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
120+
121+
const openInNewTab = (url: string): void => {
122+
window.open(url, '_blank', 'noreferrer');
123+
};
124+
125+
const handleClick = (event: MouseEvent<HTMLDivElement>): void => {
126+
setAnchorEl(event.currentTarget);
127+
};
128+
129+
const handleClose = (): void => {
130+
setAnchorEl(null);
131+
};
132+
133+
const totalUsers = Object.entries(users).length;
134+
const visibleAvatars = 4;
135+
const theme = useTheme();
136+
return (
137+
<AvatarGroup max={visibleAvatars + 1}>
138+
{Object.entries(users)
139+
.slice(0, visibleAvatars)
140+
.map(([clientID, user]) => {
141+
return (
142+
<CustomTooltip key={clientID} title={user.name} arrow>
143+
<StyledAvatar
144+
key={clientID}
145+
alt={user.name}
146+
src={user.avatar_url}
147+
borderColor={user.border_color}
148+
imgProps={{ referrerPolicy: 'no-referrer' }}
149+
onClick={() => openInNewTab(`${providerUrl}/user/${user.user_id}`)}
150+
/>
151+
</CustomTooltip>
152+
);
153+
})}
154+
{totalUsers > visibleAvatars && (
155+
<>
156+
<MoreAvatarButton onClick={handleClick} aria-describedby="user-popover">
157+
{anchorEl ? (
158+
<ExpandMore
159+
fill={theme.palette.common.white}
160+
{...iconSmall}
161+
style={{ marginLeft: '4px' }}
162+
/>
163+
) : (
164+
<Typography
165+
variant="body2"
166+
style={{ color: theme.palette.common.white, fontSize: '12px' }}
167+
>
168+
{`+${totalUsers - visibleAvatars}`}
169+
</Typography>
170+
)}
171+
</MoreAvatarButton>
172+
<StyledPopover
173+
id="user-popover"
174+
open={Boolean(anchorEl)}
175+
anchorEl={anchorEl}
176+
onClose={handleClose}
177+
anchorOrigin={{
178+
vertical: 'bottom',
179+
horizontal: 'left'
180+
}}
181+
transformOrigin={{
182+
vertical: 'top',
183+
horizontal: 'left'
184+
}}
185+
>
186+
{Object.entries(users)
187+
.slice(visibleAvatars, totalUsers)
188+
.map(([clientID, user]) => (
189+
<PopupAvatarWrapper
190+
key={clientID}
191+
onClick={() => openInNewTab(`${providerUrl}/user/${user.user_id}`)}
192+
>
193+
<StyledAvatar
194+
alt={user.name}
195+
src={user.avatar_url}
196+
borderColor={user.border_color}
197+
imgProps={{ referrerPolicy: 'no-referrer' }}
198+
/>
199+
<UserName variant="body1">{user.name}</UserName>
200+
</PopupAvatarWrapper>
201+
))}
202+
</StyledPopover>
203+
</>
204+
)}
205+
</AvatarGroup>
206+
);
207+
};
208+
209+
export default CollaboratorAvatarGroup;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import CollaboratorAvatarGroup from './CollaboratorAvatarGroup';
2+
3+
export { CollaboratorAvatarGroup };

src/custom/Feedback/style.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,15 @@ export const FeedbackOptionButton = styled(Button)<FeedbackMessageProps>(({ them
256256
? BLACK
257257
: SNOW_WHITE
258258
: theme.palette.mode === 'dark'
259-
? DARK_JUNGLE_GREEN
260-
: DARK_SLATE_GRAY,
259+
? DARK_JUNGLE_GREEN
260+
: DARK_SLATE_GRAY,
261261
color: isOpen
262262
? theme.palette.mode === 'dark'
263263
? SNOW_WHITE
264264
: BLACK
265265
: theme.palette.mode === 'dark'
266-
? SNOW_WHITE
267-
: SNOW_WHITE,
266+
? SNOW_WHITE
267+
: SNOW_WHITE,
268268
fill: isOpen ? theme.palette.icon.default : SNOW_WHITE,
269269
stroke: isOpen ? theme.palette.icon.inverse : theme.palette.icon.brand,
270270
'&:hover': {

src/custom/Panel/style.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ListItemProps } from '@mui/material';
22
import { Box, IconButton, ListItem } from '../../base';
33
import { PanelDragHandleIcon } from '../../icons/PanelDragHandle';
4-
import { black, styled } from '../../theme';
4+
import { styled } from '../../theme';
55
import { PanelProps } from './Panel';
66

77
export const ListHeader = styled(ListItem)(({ theme }) => ({
@@ -86,10 +86,10 @@ export const PanelContainer = styled(Box)<{ intitialPosition: PanelProps['intiti
8686
borderRadius: '8px',
8787
overflow: 'hidden',
8888
flexShrink: 0,
89-
zIndex: 99999,
89+
zIndex: 100,
9090
position: 'absolute',
9191
backgroundColor: theme.palette.background.blur?.light,
92-
boxShadow: `0 4px 16px ${black}`,
92+
boxShadow: `0 4px 16px ${theme.palette.background.blur?.light}`,
9393
maxHeight: '80%',
9494
display: 'flex',
9595
boxSizing: 'border-box',

0 commit comments

Comments
 (0)