@lobehub/lobehub 2.0.0-next.296 → 2.0.0-next.297

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/package.json +2 -2
  4. package/packages/types/package.json +1 -1
  5. package/packages/types/src/discover/assistants.ts +4 -0
  6. package/packages/types/src/discover/groupAgents.ts +196 -0
  7. package/packages/types/src/discover/index.ts +5 -1
  8. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/DetailProvider.tsx +19 -0
  9. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Members/index.tsx +137 -0
  10. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Nav.tsx +88 -0
  11. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Overview/index.tsx +213 -0
  12. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Related/index.tsx +85 -0
  13. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/TagList.tsx +20 -0
  14. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/index.tsx +71 -0
  15. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Versions/index.tsx +119 -0
  16. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/index.tsx +51 -0
  17. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Header.tsx +253 -0
  18. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/AddGroupAgent.tsx +222 -0
  19. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/index.tsx +34 -0
  20. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/Summary/index.tsx +42 -0
  21. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/index.tsx +41 -0
  22. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/StatusPage/index.tsx +104 -0
  23. package/src/app/[variants]/(main)/community/(detail)/group_agent/index.tsx +103 -0
  24. package/src/app/[variants]/(main)/community/(detail)/group_agent/loading.tsx +1 -0
  25. package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +7 -1
  26. package/src/app/[variants]/(main)/community/(detail)/user/features/UserContent.tsx +2 -0
  27. package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupCard.tsx +186 -0
  28. package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupList.tsx +59 -0
  29. package/src/app/[variants]/(main)/community/(detail)/user/index.tsx +3 -1
  30. package/src/app/[variants]/(main)/community/(list)/assistant/features/List/Item.tsx +26 -8
  31. package/src/app/[variants]/(main)/community/(list)/assistant/index.tsx +1 -0
  32. package/src/app/[variants]/(main)/group/profile/features/GroupProfile/index.tsx +2 -0
  33. package/src/app/[variants]/(main)/group/profile/features/Header/AgentPublishButton/PublishResultModal.tsx +2 -1
  34. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupForkConfirmModal.tsx +60 -0
  35. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupPublishResultModal.tsx +62 -0
  36. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/PublishButton.tsx +122 -0
  37. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/index.tsx +46 -0
  38. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/types.ts +12 -0
  39. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/useMarketGroupPublish.ts +211 -0
  40. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/utils.ts +22 -0
  41. package/src/app/[variants]/router/desktopRouter.config.tsx +7 -0
  42. package/src/locales/default/setting.ts +12 -0
  43. package/src/server/routers/lambda/market/agentGroup.ts +296 -0
  44. package/src/server/routers/lambda/market/index.ts +134 -4
  45. package/src/server/services/discover/index.ts +123 -7
  46. package/src/services/discover.ts +55 -0
  47. package/src/store/discover/slices/groupAgent/action.ts +80 -0
  48. package/src/store/discover/store.ts +3 -0
@@ -0,0 +1,213 @@
1
+ import { BRANDING_NAME } from '@lobechat/business-const';
2
+ import { Avatar, Block, Collapse, Flexbox, Grid, Text } from '@lobehub/ui';
3
+ import { ChatList } from '@lobehub/ui/chat';
4
+ import { createStaticStyles, useTheme } from 'antd-style';
5
+ import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+
8
+ import { DEFAULT_USER_AVATAR_URL } from '@/const/meta';
9
+ import { useUserStore } from '@/store/user';
10
+ import { authSelectors, userProfileSelectors } from '@/store/user/selectors';
11
+
12
+ import Title from '../../../../../features/Title';
13
+ import { useDetailContext } from '../../DetailProvider';
14
+
15
+ const styles = createStaticStyles(({ css, cssVar }) => {
16
+ return {
17
+ desc: css`
18
+ flex: 1;
19
+ margin: 0 !important;
20
+ color: ${cssVar.colorTextSecondary};
21
+ `,
22
+ title: css`
23
+ margin: 0 !important;
24
+ font-size: 14px !important;
25
+ font-weight: 500 !important;
26
+ `,
27
+ };
28
+ });
29
+
30
+ const MemberCard = memo(
31
+ ({
32
+ agent,
33
+ currentVersion,
34
+ }: {
35
+ agent: any;
36
+ currentVersion: any;
37
+ }) => {
38
+ return (
39
+ <Block
40
+ height={'100%'}
41
+ style={{
42
+ cursor: 'default',
43
+ overflow: 'hidden',
44
+ }}
45
+ variant={'outlined'}
46
+ width={'100%'}
47
+ >
48
+ <Flexbox gap={12} padding={16}>
49
+ {/* Avatar and Basic Info */}
50
+ <Flexbox align={'flex-start'} gap={12} horizontal>
51
+ <Avatar
52
+ avatar={currentVersion.avatar || agent.name?.[0]}
53
+ shape={'square'}
54
+ size={40}
55
+ style={{ flex: 'none' }}
56
+ />
57
+ <Flexbox
58
+ flex={1}
59
+ gap={4}
60
+ style={{
61
+ overflow: 'hidden',
62
+ }}
63
+ >
64
+ <Text as={'h3'} className={styles.title} ellipsis>
65
+ {currentVersion.name || agent.name}
66
+ </Text>
67
+ </Flexbox>
68
+ </Flexbox>
69
+
70
+ {/* Description */}
71
+ {currentVersion.description && currentVersion.description !== 'No description provided' && (
72
+ <Text
73
+ as={'p'}
74
+ className={styles.desc}
75
+ ellipsis={{
76
+ rows: 2,
77
+ }}
78
+ >
79
+ {currentVersion.description}
80
+ </Text>
81
+ )}
82
+ </Flexbox>
83
+ </Block>
84
+ );
85
+ },
86
+ );
87
+
88
+ MemberCard.displayName = 'MemberCard';
89
+
90
+ const Overview = memo(() => {
91
+ const [userAvatar, username] = useUserStore((s) => [
92
+ userProfileSelectors.userAvatar(s),
93
+ userProfileSelectors.username(s),
94
+ ]);
95
+
96
+ const isSignedIn = useUserStore(authSelectors.isLogin);
97
+ const { t } = useTranslation('discover');
98
+ const theme = useTheme();
99
+ const {
100
+ examples = [],
101
+ description,
102
+ summary,
103
+ avatar,
104
+ title,
105
+ backgroundColor,
106
+ config,
107
+ memberAgents = [],
108
+ } = useDetailContext();
109
+
110
+ const data: any = [
111
+ {
112
+ content: config?.openingMessage,
113
+ role: 'assistant',
114
+ },
115
+ ...examples,
116
+ ].map((item, index) => {
117
+ let meta = {
118
+ avatar,
119
+ backgroundColor: backgroundColor || 'transparent',
120
+ title,
121
+ };
122
+ if (item.role === 'user') {
123
+ meta = {
124
+ avatar: isSignedIn && !!userAvatar ? userAvatar : DEFAULT_USER_AVATAR_URL,
125
+ backgroundColor: 'transparent',
126
+ title: isSignedIn && !!username ? username : BRANDING_NAME,
127
+ };
128
+ }
129
+
130
+ return {
131
+ extra: {},
132
+ id: index,
133
+ ...item,
134
+ meta,
135
+ };
136
+ });
137
+
138
+ // Sort: supervisors first, then by displayOrder
139
+ const sortedMembers = [...(memberAgents || [])].sort((a: any, b: any) => {
140
+ const aRole = a.role || a.agent?.role;
141
+ const bRole = b.role || b.agent?.role;
142
+ if (aRole === 'supervisor' && bRole !== 'supervisor') return -1;
143
+ if (aRole !== 'supervisor' && bRole === 'supervisor') return 1;
144
+ const aOrder = a.displayOrder || a.agent?.displayOrder || 0;
145
+ const bOrder = b.displayOrder || b.agent?.displayOrder || 0;
146
+ return aOrder - bOrder;
147
+ });
148
+
149
+ return (
150
+ <Flexbox gap={16}>
151
+ <Collapse
152
+ defaultActiveKey={['summary']}
153
+ expandIconPlacement={'end'}
154
+ items={[
155
+ {
156
+ children: summary || description,
157
+ key: 'summary',
158
+ label: t('groupAgents.details.summary.title', { defaultValue: 'Summary' }),
159
+ },
160
+ ]}
161
+ variant={'outlined'}
162
+ />
163
+
164
+ {/* Members Section */}
165
+ {memberAgents.length > 0 && (
166
+ <>
167
+ <Title>
168
+ {t('groupAgents.details.members.title', { defaultValue: 'Member Agents' })} (
169
+ {memberAgents.length})
170
+ </Title>
171
+ <Grid rows={4} width={'100%'}>
172
+ {sortedMembers.map((member: any, index) => {
173
+ // Support both flat structure and nested structure
174
+ const agent = member.agent || member;
175
+ const currentVersion = member.currentVersion || member;
176
+ return (
177
+ <MemberCard
178
+ agent={agent}
179
+ currentVersion={currentVersion}
180
+ key={agent.identifier || index}
181
+ />
182
+ );
183
+ })}
184
+ </Grid>
185
+ </>
186
+ )}
187
+
188
+ {data.length > 0 && config?.openingMessage && (
189
+ <>
190
+ <Title>
191
+ {t('groupAgents.details.overview.example', { defaultValue: 'Conversation Example' })}
192
+ </Title>
193
+ <Block
194
+ style={{
195
+ background: theme.colorBgContainerSecondary,
196
+ }}
197
+ variant={'outlined'}
198
+ >
199
+ <ChatList
200
+ data={data}
201
+ renderMessages={{
202
+ default: ({ id, editableContent }) => <div id={id}>{editableContent}</div>,
203
+ }}
204
+ style={{ width: '100%' }}
205
+ />
206
+ </Block>
207
+ </>
208
+ )}
209
+ </Flexbox>
210
+ );
211
+ });
212
+
213
+ export default Overview;
@@ -0,0 +1,85 @@
1
+ import { Avatar, Flexbox, Text , Grid } from '@lobehub/ui';
2
+ import qs from 'query-string';
3
+ import { memo } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { useNavigate } from 'react-router-dom';
6
+ import urlJoin from 'url-join';
7
+
8
+ import { type DiscoverGroupAgentItem } from '@/types/discover';
9
+
10
+ import Title from '../../../../../features/Title';
11
+ import { useDetailContext } from '../../DetailProvider';
12
+
13
+ const GroupAgentCard = memo<DiscoverGroupAgentItem>((item) => {
14
+ const navigate = useNavigate();
15
+
16
+ const handleClick = () => {
17
+ if (!item.identifier) return;
18
+ navigate(qs.stringifyUrl({
19
+ url: urlJoin('/community/group_agent', item.identifier),
20
+ }));
21
+ };
22
+
23
+ return (
24
+ <Flexbox
25
+ gap={12}
26
+ onClick={handleClick}
27
+ padding={16}
28
+ style={{
29
+ border: '1px solid var(--lobe-border-color)',
30
+ borderRadius: 8,
31
+ cursor: 'pointer',
32
+ transition: 'all 0.2s',
33
+ }}
34
+ >
35
+ <Flexbox align="center" gap={12} horizontal>
36
+ <Avatar avatar={item.avatar || item.title[0]} shape="square" size={48} />
37
+ <Flexbox flex={1} gap={4}>
38
+ <Text ellipsis style={{ fontWeight: 500 }}>
39
+ {item.title}
40
+ </Text>
41
+ <Text ellipsis style={{ fontSize: 12, opacity: 0.65 }} type="secondary">
42
+ {item.description}
43
+ </Text>
44
+ </Flexbox>
45
+ </Flexbox>
46
+ </Flexbox>
47
+ );
48
+ });
49
+
50
+ const Related = memo(() => {
51
+ const { t } = useTranslation('discover');
52
+ const { related = [], category } = useDetailContext();
53
+
54
+ return (
55
+ <Flexbox gap={16}>
56
+ <Title
57
+ more={t('groupAgents.details.related.more', { defaultValue: 'View More' })}
58
+ moreLink={qs.stringifyUrl(
59
+ {
60
+ query: {
61
+ category,
62
+ },
63
+ url: '/community/group_agent',
64
+ },
65
+ { skipNull: true },
66
+ )}
67
+ >
68
+ {t('groupAgents.details.related.listTitle', { defaultValue: 'Related Group Agents' })}
69
+ </Title>
70
+ {related.length > 0 ? (
71
+ <Grid rows={4}>
72
+ {related.map((item) => (
73
+ <GroupAgentCard key={item.identifier} {...item} />
74
+ ))}
75
+ </Grid>
76
+ ) : (
77
+ <Flexbox align="center" padding={32} style={{ color: '#999' }}>
78
+ {t('groupAgents.details.related.empty', { defaultValue: 'No related group agents found' })}
79
+ </Flexbox>
80
+ )}
81
+ </Flexbox>
82
+ );
83
+ });
84
+
85
+ export default Related;
@@ -0,0 +1,20 @@
1
+ import { Tag as AntdTag, Flexbox } from '@lobehub/ui';
2
+ import { memo } from 'react';
3
+
4
+ interface TagListProps {
5
+ tags?: string[];
6
+ }
7
+
8
+ const TagList = memo<TagListProps>(({ tags = [] }) => {
9
+ if (!tags || tags.length === 0) return null;
10
+
11
+ return (
12
+ <Flexbox gap={8} horizontal wrap={'wrap'}>
13
+ {tags.map((tag, index) => (
14
+ <AntdTag key={index}>{tag}</AntdTag>
15
+ ))}
16
+ </Flexbox>
17
+ );
18
+ });
19
+
20
+ export default TagList;
@@ -0,0 +1,71 @@
1
+ import { Block, Flexbox, Icon, Tag } from '@lobehub/ui';
2
+ import { cssVar } from 'antd-style';
3
+ import { MessageCircleHeartIcon, MessageCircleQuestionIcon } from 'lucide-react';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import Title from '../../../../../features/Title';
8
+ import MarkdownRender from '../../../../features/MakedownRender';
9
+ import { useDetailContext } from '../../DetailProvider';
10
+ import TagList from './TagList';
11
+
12
+ const SystemRole = memo(() => {
13
+ const { t } = useTranslation('discover');
14
+ const { tokenUsage, tags = [], config } = useDetailContext();
15
+
16
+ const { systemRole, openingMessage, openingQuestions } = config || {};
17
+ return (
18
+ <Flexbox gap={16}>
19
+ {systemRole && (
20
+ <>
21
+ <Title tag={tokenUsage && <Tag>{t('groupAgents.details.tokenUsage', { defaultValue: `${tokenUsage} tokens` })}</Tag>}>
22
+ {t('groupAgents.details.systemRole.title', { defaultValue: 'System Role' })}
23
+ </Title>
24
+ <Block gap={16} padding={16} variant={'outlined'}>
25
+ {<MarkdownRender>{systemRole.trimEnd()}</MarkdownRender>}
26
+ <TagList tags={tags} />
27
+ </Block>
28
+ </>
29
+ )}
30
+ {openingMessage && (
31
+ <>
32
+ <Title>
33
+ {t('groupAgents.details.systemRole.openingMessage', {
34
+ defaultValue: 'Opening Message',
35
+ })}
36
+ </Title>
37
+ <Block align={'flex-start'} gap={12} horizontal padding={16} variant={'outlined'}>
38
+ <Icon
39
+ color={cssVar.colorError}
40
+ icon={MessageCircleHeartIcon}
41
+ size={20}
42
+ style={{
43
+ marginTop: 4,
44
+ }}
45
+ />
46
+ <MarkdownRender>{openingMessage?.trimEnd()}</MarkdownRender>
47
+ </Block>
48
+ </>
49
+ )}
50
+ {openingQuestions && openingQuestions.length > 0 && (
51
+ <>
52
+ <Title tag={<Tag>{openingQuestions?.length}</Tag>}>
53
+ {t('groupAgents.details.systemRole.openingQuestions', {
54
+ defaultValue: 'Opening Questions',
55
+ })}
56
+ </Title>
57
+ <Flexbox gap={8}>
58
+ {openingQuestions?.map((item, key) => (
59
+ <Block gap={12} horizontal key={key} padding={16} variant={'outlined'}>
60
+ <Icon color={cssVar.colorWarning} icon={MessageCircleQuestionIcon} size={20} />
61
+ <MarkdownRender>{item}</MarkdownRender>
62
+ </Block>
63
+ ))}
64
+ </Flexbox>
65
+ </>
66
+ )}
67
+ </Flexbox>
68
+ );
69
+ });
70
+
71
+ export default SystemRole;
@@ -0,0 +1,119 @@
1
+ import { Block, Flexbox, Icon, Tag } from '@lobehub/ui';
2
+ import { cssVar } from 'antd-style';
3
+ import { CheckIcon, MinusIcon } from 'lucide-react';
4
+ import { memo, useMemo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import InlineTable from '@/components/InlineTable';
8
+ import PublishedTime from '@/components/PublishedTime';
9
+
10
+ import Title from '../../../../../features/Title';
11
+ import { useDetailContext } from '../../DetailProvider';
12
+
13
+ const Versions = memo(() => {
14
+ const { t } = useTranslation('discover');
15
+ const { versions = [], currentVersion } = useDetailContext();
16
+
17
+ const statusTagMap = useMemo(
18
+ () => ({
19
+ archived: {
20
+ color: 'default' as const,
21
+ label: t('groupAgents.details.version.status.archived', { defaultValue: 'Archived' }),
22
+ },
23
+ deprecated: {
24
+ color: 'warning' as const,
25
+ label: t('groupAgents.details.version.status.deprecated', { defaultValue: 'Deprecated' }),
26
+ },
27
+ published: {
28
+ color: 'success' as const,
29
+ label: t('groupAgents.details.version.status.published', { defaultValue: 'Published' }),
30
+ },
31
+ unpublished: {
32
+ color: 'default' as const,
33
+ label: t('groupAgents.details.version.status.unpublished', { defaultValue: 'Unpublished' }),
34
+ },
35
+ }),
36
+ [t],
37
+ );
38
+
39
+ if (!versions.length) {
40
+ return (
41
+ <Flexbox gap={16}>
42
+ <Title>
43
+ {t('groupAgents.details.version.title', { defaultValue: 'Version History' })}
44
+ </Title>
45
+ <Block padding={24} variant={'outlined'}>
46
+ {t('groupAgents.details.version.empty', { defaultValue: 'No version history available' })}
47
+ </Block>
48
+ </Flexbox>
49
+ );
50
+ }
51
+
52
+ return (
53
+ <Flexbox gap={16}>
54
+ <Title>
55
+ {t('groupAgents.details.version.title', { defaultValue: 'Version History' })}
56
+ </Title>
57
+ <Block variant={'outlined'}>
58
+ <InlineTable
59
+ columns={[
60
+ {
61
+ dataIndex: 'version',
62
+ render: (_: any, record: any) => {
63
+ const statusKey =
64
+ record.status &&
65
+ Object.prototype.hasOwnProperty.call(statusTagMap, record.status)
66
+ ? (record.status as keyof typeof statusTagMap)
67
+ : undefined;
68
+ const statusMeta = statusKey ? statusTagMap[statusKey] : undefined;
69
+
70
+ return (
71
+ <Flexbox align={'center'} gap={8} horizontal>
72
+ <code style={{ fontSize: 14 }}>{record.version}</code>
73
+ {(record.isLatest || record.version === currentVersion) && (
74
+ <Tag color={'info'}>
75
+ {t('groupAgents.details.version.table.isLatest', { defaultValue: 'Latest' })}
76
+ </Tag>
77
+ )}
78
+ {statusMeta && <Tag color={statusMeta.color}>{statusMeta.label}</Tag>}
79
+ </Flexbox>
80
+ );
81
+ },
82
+ title: t('groupAgents.details.version.table.version', { defaultValue: 'Version' }),
83
+ },
84
+ {
85
+ align: 'center',
86
+ dataIndex: 'isValidated',
87
+ render: (_: any, record: any) => (
88
+ <Icon
89
+ color={record.isValidated ? cssVar.colorSuccess : cssVar.colorTextDescription}
90
+ icon={record.isValidated ? CheckIcon : MinusIcon}
91
+ />
92
+ ),
93
+ title: t('groupAgents.details.version.table.isValidated', {
94
+ defaultValue: 'Validated',
95
+ }),
96
+ },
97
+ {
98
+ align: 'end',
99
+ dataIndex: 'createdAt',
100
+ render: (_: any, record: any) => (
101
+ <PublishedTime date={record.createdAt} showPrefix={false} />
102
+ ),
103
+ title: t('groupAgents.details.version.table.publishAt', {
104
+ defaultValue: 'Published At',
105
+ }),
106
+ },
107
+ ]}
108
+ dataSource={versions}
109
+ rowKey={'version'}
110
+ size={'middle'}
111
+ />
112
+ </Block>
113
+ </Flexbox>
114
+ );
115
+ });
116
+
117
+ Versions.displayName = 'GroupAgentVersions';
118
+
119
+ export default Versions;
@@ -0,0 +1,51 @@
1
+ import { Flexbox } from '@lobehub/ui';
2
+ import { useResponsive } from 'antd-style';
3
+ import { useQueryState } from 'nuqs';
4
+ import { memo } from 'react';
5
+
6
+ import Sidebar from '../Sidebar';
7
+ import Nav, { GroupAgentNavKey } from './Nav';
8
+ import Overview from './Overview';
9
+ import SystemRole from './SystemRole';
10
+ import Versions from './Versions';
11
+
12
+ const Details = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
13
+ const { mobile = isMobile } = useResponsive();
14
+ const [activeTabParam, setActiveTab] = useQueryState('activeTab');
15
+ const activeTab = activeTabParam || GroupAgentNavKey.Overview;
16
+
17
+ return (
18
+ <Flexbox gap={24}>
19
+ {/* Navigation */}
20
+ <Nav
21
+ activeTab={activeTab as GroupAgentNavKey}
22
+ mobile={mobile}
23
+ setActiveTab={(tab) => setActiveTab(tab)}
24
+ />
25
+
26
+ <Flexbox
27
+ gap={48}
28
+ horizontal={!mobile}
29
+ style={mobile ? { flexDirection: 'column-reverse' } : undefined}
30
+ >
31
+ {/* Main Content */}
32
+ <Flexbox
33
+ style={{
34
+ overflow: 'hidden',
35
+ }}
36
+ width={'100%'}
37
+ >
38
+ {/* Tab Content */}
39
+ {activeTab === GroupAgentNavKey.Overview && <Overview />}
40
+ {activeTab === GroupAgentNavKey.SystemRole && <SystemRole />}
41
+ {activeTab === GroupAgentNavKey.Versions && <Versions />}
42
+ </Flexbox>
43
+
44
+ {/* Sidebar */}
45
+ <Sidebar mobile={mobile} />
46
+ </Flexbox>
47
+ </Flexbox>
48
+ );
49
+ });
50
+
51
+ export default Details;