@eventcatalog/core 3.0.0-beta.25 → 3.0.0-beta.26
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.
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/catalog-to-astro-content-directory.cjs +2 -19
- package/dist/catalog-to-astro-content-directory.d.cts +1 -2
- package/dist/catalog-to-astro-content-directory.d.ts +1 -2
- package/dist/catalog-to-astro-content-directory.js +3 -5
- package/dist/{chunk-RA6AYXGJ.js → chunk-3YJD7KVJ.js} +1 -1
- package/dist/{chunk-NAW6EPCS.js → chunk-5TB5SKXE.js} +1 -1
- package/dist/{chunk-3SWCGDD7.js → chunk-6VKMP3FH.js} +1 -1
- package/dist/{chunk-R2BJ7MJG.js → chunk-6Z6ARMQS.js} +1 -17
- package/dist/{chunk-DFHXF3VF.js → chunk-MZTNQHMI.js} +1 -1
- package/dist/{chunk-OJA6CNVO.js → chunk-WQFW32XA.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -18
- package/dist/eventcatalog.js +7 -10
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +95 -90
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +144 -0
- package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +34 -8
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -2
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +140 -109
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +5 -14
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +247 -59
- package/eventcatalog/src/components/SchemaExplorer/SchemaFilters.tsx +64 -126
- package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +41 -43
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +42 -15
- package/eventcatalog/src/components/Tables/Table.tsx +96 -77
- package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +108 -74
- package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +74 -55
- package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +36 -36
- package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +110 -77
- package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +105 -94
- package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +31 -26
- package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +115 -215
- package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +145 -243
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +2 -2
- package/eventcatalog/src/pages/_index.astro +239 -554
- package/eventcatalog/src/pages/directory/[type]/index.astro +6 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +194 -121
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +94 -70
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +56 -45
- package/eventcatalog/src/pages/studio.astro +124 -72
- package/package.json +1 -1
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
|
|
2
1
|
import { createColumnHelper } from '@tanstack/react-table';
|
|
3
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
4
3
|
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
|
|
5
4
|
import { buildUrl } from '@utils/url-builder';
|
|
6
5
|
import type { TData } from '../Table';
|
|
7
6
|
import type { CollectionUserTypes } from '@types';
|
|
8
7
|
import type { CollectionEntry } from 'astro:content';
|
|
9
|
-
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid';
|
|
8
|
+
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon, MagnifyingGlassIcon } from '@heroicons/react/24/solid';
|
|
9
|
+
import { Users } from 'lucide-react';
|
|
10
10
|
import type { TableConfiguration } from '@types';
|
|
11
11
|
const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
|
|
12
12
|
|
|
13
|
+
const getMessageIconAndColor = (collection: string) => {
|
|
14
|
+
if (collection === 'events') return { Icon: BoltIcon, color: 'orange' };
|
|
15
|
+
if (collection === 'commands') return { Icon: ChatBubbleLeftIcon, color: 'blue' };
|
|
16
|
+
if (collection === 'queries') return { Icon: MagnifyingGlassIcon, color: 'green' };
|
|
17
|
+
return { Icon: ChatBubbleLeftIcon, color: 'gray' };
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
export const columns = (tableConfiguration: TableConfiguration) => [
|
|
14
21
|
columnHelper.accessor('data.name', {
|
|
15
22
|
id: 'name',
|
|
16
23
|
header: () => <span>{tableConfiguration.columns?.name?.label || 'Name'}</span>,
|
|
17
24
|
cell: (info) => {
|
|
18
|
-
const
|
|
19
|
-
const type = useMemo(() => messageRaw.collection.slice(0, -1), [messageRaw.collection]);
|
|
25
|
+
const team = info.row.original;
|
|
20
26
|
return (
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<span className="font-semibold">{messageRaw.data.name}</span>
|
|
30
|
-
</span>
|
|
31
|
-
</span>
|
|
32
|
-
</div>
|
|
33
|
-
</a>
|
|
34
|
-
</div>
|
|
27
|
+
<a href={buildUrl(`/docs/${team.collection}/${team.data.id}`)} className="group inline-flex items-center">
|
|
28
|
+
<span className="inline-flex items-center rounded-md border border-gray-200 bg-white hover:border-pink-300 hover:bg-pink-50 transition-colors">
|
|
29
|
+
<span className="flex items-center justify-center w-6 h-6 bg-pink-500 rounded-l-md">
|
|
30
|
+
<Users className="h-3 w-3 text-white" />
|
|
31
|
+
</span>
|
|
32
|
+
<span className="px-2 py-1 text-xs text-gray-700 group-hover:text-gray-900">{team.data.name}</span>
|
|
33
|
+
</span>
|
|
34
|
+
</a>
|
|
35
35
|
);
|
|
36
36
|
},
|
|
37
37
|
meta: {
|
|
@@ -41,215 +41,115 @@ export const columns = (tableConfiguration: TableConfiguration) => [
|
|
|
41
41
|
filterFn: filterByName,
|
|
42
42
|
}),
|
|
43
43
|
|
|
44
|
-
columnHelper.accessor(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
columnHelper.accessor(
|
|
45
|
+
(row) => {
|
|
46
|
+
const events = row.data.ownedEvents || [];
|
|
47
|
+
const commands = row.data.ownedCommands || [];
|
|
48
|
+
const queries = row.data.ownedQueries || [];
|
|
49
|
+
return [...events, ...commands, ...queries];
|
|
50
50
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
51
|
+
{
|
|
52
|
+
id: 'ownedMessages',
|
|
53
|
+
header: () => <span>{tableConfiguration.columns?.ownedMessages?.label || 'Owned messages'}</span>,
|
|
54
|
+
meta: {
|
|
55
|
+
showFilter: false,
|
|
56
|
+
},
|
|
57
|
+
cell: (info) => {
|
|
58
|
+
const messages = info.getValue() as Array<
|
|
59
|
+
CollectionEntry<'events'> | CollectionEntry<'commands'> | CollectionEntry<'queries'>
|
|
60
|
+
>;
|
|
61
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
62
|
+
|
|
63
|
+
if (messages?.length === 0 || !messages)
|
|
64
|
+
return (
|
|
65
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-400 bg-gray-50 rounded-md border border-gray-100">
|
|
66
|
+
No messages
|
|
67
|
+
</span>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const visibleItems = isExpanded ? messages : messages.slice(0, 4);
|
|
71
|
+
const hiddenCount = messages.length - 4;
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className="flex flex-col gap-1.5">
|
|
75
|
+
{visibleItems.map((message, index: number) => {
|
|
76
|
+
const { Icon, color } = getMessageIconAndColor(message.collection);
|
|
77
|
+
return (
|
|
78
|
+
<a
|
|
79
|
+
key={`${message.data.id}-${index}`}
|
|
80
|
+
href={buildUrl(`/docs/${message.collection}/${message.data.id}/${message.data.version}`)}
|
|
81
|
+
className="group inline-flex items-center"
|
|
82
|
+
>
|
|
83
|
+
<span
|
|
84
|
+
className={`inline-flex items-center rounded-md border border-gray-200 bg-white hover:border-${color}-300 hover:bg-${color}-50 transition-colors`}
|
|
74
85
|
>
|
|
75
|
-
<
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
))}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
columnHelper.accessor('data.ownedCommands', {
|
|
98
|
-
id: 'ownedCommands',
|
|
99
|
-
header: () => <span>{tableConfiguration.columns?.ownedCommands?.label || 'Owned commands'}</span>,
|
|
100
|
-
meta: {
|
|
101
|
-
filterVariant: 'collection',
|
|
102
|
-
collectionFilterKey: 'ownedCommands',
|
|
103
|
-
},
|
|
104
|
-
cell: (info) => {
|
|
105
|
-
const commands = info.getValue();
|
|
106
|
-
if (commands?.length === 0 || !commands)
|
|
107
|
-
return <div className="font-light text-sm text-gray-400/60 text-left italic">Team owns no commands</div>;
|
|
108
|
-
|
|
109
|
-
const isExpandable = commands?.length > 10;
|
|
110
|
-
const isOpen = isExpandable ? commands?.length < 10 : true;
|
|
111
|
-
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<div>
|
|
115
|
-
{isExpandable && (
|
|
116
|
-
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
117
|
-
{isExpanded ? '▼' : '▶'} {commands.length} command{commands.length !== 1 ? 's' : ''}
|
|
118
|
-
</button>
|
|
119
|
-
)}
|
|
120
|
-
{isExpanded && (
|
|
121
|
-
<ul>
|
|
122
|
-
{commands.map((command: CollectionEntry<'commands'>, index: number) => (
|
|
123
|
-
<li key={`${command.data.id}-${index}`} className="py-1 group font-light ">
|
|
124
|
-
<a
|
|
125
|
-
href={buildUrl(`/docs/${command.collection}/${command.data.id}/${command.data.version}`)}
|
|
126
|
-
className="group-hover:text-primary flex space-x-1 items-center "
|
|
127
|
-
>
|
|
128
|
-
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
129
|
-
<span className="flex items-center">
|
|
130
|
-
<span className={`bg-blue-500 h-full rounded-tl rounded-bl p-1`}>
|
|
131
|
-
<ChatBubbleLeftIcon className="h-4 w-4 text-white" />
|
|
132
|
-
</span>
|
|
133
|
-
<span className="leading-none px-2 group-hover:underline ">
|
|
134
|
-
{command.data.name} (v{command.data.version})
|
|
135
|
-
</span>
|
|
136
|
-
</span>
|
|
137
|
-
</div>
|
|
138
|
-
</a>
|
|
139
|
-
</li>
|
|
140
|
-
))}
|
|
141
|
-
</ul>
|
|
142
|
-
)}
|
|
143
|
-
</div>
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
// return commands.length;
|
|
147
|
-
},
|
|
148
|
-
footer: (info) => info.column.id,
|
|
149
|
-
filterFn: filterCollectionByName('ownedCommands'),
|
|
150
|
-
}),
|
|
151
|
-
|
|
152
|
-
columnHelper.accessor('data.ownedQueries', {
|
|
153
|
-
id: 'ownedQueries',
|
|
154
|
-
header: () => <span>{tableConfiguration.columns?.ownedQueries?.label || 'Owned queries'}</span>,
|
|
155
|
-
meta: {
|
|
156
|
-
filterVariant: 'collection',
|
|
157
|
-
collectionFilterKey: 'ownedQueries',
|
|
158
|
-
},
|
|
159
|
-
cell: (info) => {
|
|
160
|
-
const queries = info.getValue();
|
|
161
|
-
if (queries?.length === 0 || !queries)
|
|
162
|
-
return <div className="font-light text-sm text-gray-400/60 text-left italic">Team owns no queries</div>;
|
|
163
|
-
|
|
164
|
-
const isExpandable = queries?.length > 10;
|
|
165
|
-
const isOpen = isExpandable ? queries?.length < 10 : true;
|
|
166
|
-
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<div>
|
|
170
|
-
{isExpandable && (
|
|
171
|
-
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
172
|
-
{isExpanded ? '▼' : '▶'} {queries.length} query{queries.length !== 1 ? 's' : ''}
|
|
173
|
-
</button>
|
|
174
|
-
)}
|
|
175
|
-
{isExpanded && (
|
|
176
|
-
<ul>
|
|
177
|
-
{queries.map((query: CollectionEntry<'queries'>, index: number) => (
|
|
178
|
-
<li key={`${query.data.id}-${index}`} className="py-1 group font-light ">
|
|
179
|
-
<a
|
|
180
|
-
href={buildUrl(`/docs/${query.collection}/${query.data.id}/${query.data.version}`)}
|
|
181
|
-
className="group-hover:text-primary flex space-x-1 items-center "
|
|
182
|
-
>
|
|
183
|
-
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
184
|
-
<span className="flex items-center">
|
|
185
|
-
<span className={`bg-blue-500 h-full rounded-tl rounded-bl p-1`}>
|
|
186
|
-
<ChatBubbleLeftIcon className="h-4 w-4 text-white" />
|
|
187
|
-
</span>
|
|
188
|
-
<span className="leading-none px-2 group-hover:underline ">
|
|
189
|
-
{query.data.name} (v{query.data.version})
|
|
190
|
-
</span>
|
|
191
|
-
</span>
|
|
192
|
-
</div>
|
|
193
|
-
</a>
|
|
194
|
-
</li>
|
|
195
|
-
))}
|
|
196
|
-
</ul>
|
|
197
|
-
)}
|
|
198
|
-
</div>
|
|
199
|
-
);
|
|
200
|
-
|
|
201
|
-
// return commands.length;
|
|
202
|
-
},
|
|
203
|
-
footer: (info) => info.column.id,
|
|
204
|
-
filterFn: filterCollectionByName('ownedCommands'),
|
|
205
|
-
}),
|
|
86
|
+
<span className={`flex items-center justify-center w-6 h-6 bg-${color}-500 rounded-l-md`}>
|
|
87
|
+
<Icon className="h-3 w-3 text-white" />
|
|
88
|
+
</span>
|
|
89
|
+
<span className="px-2 py-1 text-xs text-gray-700 group-hover:text-gray-900">
|
|
90
|
+
{message.data.name}
|
|
91
|
+
<span className="text-gray-400 ml-1">v{message.data.version}</span>
|
|
92
|
+
</span>
|
|
93
|
+
</span>
|
|
94
|
+
</a>
|
|
95
|
+
);
|
|
96
|
+
})}
|
|
97
|
+
{hiddenCount > 0 && (
|
|
98
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="text-xs text-gray-500 hover:text-gray-700 text-left">
|
|
99
|
+
{isExpanded ? 'Show less' : `+${hiddenCount} more`}
|
|
100
|
+
</button>
|
|
101
|
+
)}
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
),
|
|
206
107
|
|
|
207
108
|
columnHelper.accessor('data.ownedServices', {
|
|
208
109
|
id: 'ownedServices',
|
|
209
|
-
header: () => <span>{tableConfiguration.columns?.ownedServices?.label || 'Owned
|
|
110
|
+
header: () => <span>{tableConfiguration.columns?.ownedServices?.label || 'Owned services'}</span>,
|
|
210
111
|
meta: {
|
|
211
112
|
filterVariant: 'collection',
|
|
212
113
|
collectionFilterKey: 'ownedServices',
|
|
213
114
|
},
|
|
214
115
|
cell: (info) => {
|
|
215
116
|
const services = info.getValue();
|
|
117
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
118
|
+
|
|
216
119
|
if (services?.length === 0 || !services)
|
|
217
|
-
return
|
|
120
|
+
return (
|
|
121
|
+
<span className="inline-flex items-center px-2 py-1 text-xs text-gray-400 bg-gray-50 rounded-md border border-gray-100">
|
|
122
|
+
No services
|
|
123
|
+
</span>
|
|
124
|
+
);
|
|
218
125
|
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
126
|
+
const visibleItems = isExpanded ? services : services.slice(0, 4);
|
|
127
|
+
const hiddenCount = services.length - 4;
|
|
222
128
|
|
|
223
129
|
return (
|
|
224
|
-
<div>
|
|
225
|
-
{
|
|
226
|
-
<
|
|
227
|
-
{
|
|
130
|
+
<div className="flex flex-col gap-1.5">
|
|
131
|
+
{visibleItems.map((service: CollectionEntry<'services'>, index: number) => (
|
|
132
|
+
<a
|
|
133
|
+
key={`${service.data.id}-${index}`}
|
|
134
|
+
href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.version}`)}
|
|
135
|
+
className="group inline-flex items-center"
|
|
136
|
+
>
|
|
137
|
+
<span className="inline-flex items-center rounded-md border border-gray-200 bg-white hover:border-pink-300 hover:bg-pink-50 transition-colors">
|
|
138
|
+
<span className="flex items-center justify-center w-6 h-6 bg-pink-500 rounded-l-md">
|
|
139
|
+
<ServerIcon className="h-3 w-3 text-white" />
|
|
140
|
+
</span>
|
|
141
|
+
<span className="px-2 py-1 text-xs text-gray-700 group-hover:text-gray-900">
|
|
142
|
+
{service.data.name}
|
|
143
|
+
<span className="text-gray-400 ml-1">v{service.data.version}</span>
|
|
144
|
+
</span>
|
|
145
|
+
</span>
|
|
146
|
+
</a>
|
|
147
|
+
))}
|
|
148
|
+
{hiddenCount > 0 && (
|
|
149
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="text-xs text-gray-500 hover:text-gray-700 text-left">
|
|
150
|
+
{isExpanded ? 'Show less' : `+${hiddenCount} more`}
|
|
228
151
|
</button>
|
|
229
152
|
)}
|
|
230
|
-
{isExpanded && (
|
|
231
|
-
<ul>
|
|
232
|
-
{services.map((service: CollectionEntry<'services'>, index: number) => (
|
|
233
|
-
<li key={`${service.data.id}-${index}`} className="py-1 group font-light ">
|
|
234
|
-
<a
|
|
235
|
-
href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.version}`)}
|
|
236
|
-
className="group-hover:text-primary flex space-x-1 items-center "
|
|
237
|
-
>
|
|
238
|
-
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
239
|
-
<span className="flex items-center">
|
|
240
|
-
<span className={`bg-green-500 h-full rounded-tl rounded-bl p-1`}>
|
|
241
|
-
<ServerIcon className="h-4 w-4 text-white" />
|
|
242
|
-
</span>
|
|
243
|
-
<span className="leading-none px-2 group-hover:underline ">
|
|
244
|
-
{service.data.name} (v{service.data.version})
|
|
245
|
-
</span>
|
|
246
|
-
</span>
|
|
247
|
-
</div>
|
|
248
|
-
</a>
|
|
249
|
-
</li>
|
|
250
|
-
))}
|
|
251
|
-
</ul>
|
|
252
|
-
)}
|
|
253
153
|
</div>
|
|
254
154
|
);
|
|
255
155
|
},
|
|
@@ -260,13 +160,13 @@ export const columns = (tableConfiguration: TableConfiguration) => [
|
|
|
260
160
|
columnHelper.accessor('data.name', {
|
|
261
161
|
header: () => <span>{tableConfiguration.columns?.actions?.label || 'Actions'}</span>,
|
|
262
162
|
cell: (info) => {
|
|
263
|
-
const
|
|
163
|
+
const item = info.row.original;
|
|
264
164
|
return (
|
|
265
165
|
<a
|
|
266
|
-
className="hover:
|
|
267
|
-
href={buildUrl(`/docs/${
|
|
166
|
+
className="inline-flex items-center px-2.5 py-1 text-xs font-medium text-gray-600 bg-gray-50 border border-gray-200 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors whitespace-nowrap"
|
|
167
|
+
href={buildUrl(`/docs/${item.collection}/${item.data.id}`)}
|
|
268
168
|
>
|
|
269
|
-
View
|
|
169
|
+
View team
|
|
270
170
|
</a>
|
|
271
171
|
);
|
|
272
172
|
},
|