@eventcatalog/core 2.19.8 → 2.20.0
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 +1 -1
- package/dist/{chunk-EOMM4FAP.js → chunk-3C6KBZOA.js} +1 -1
- package/dist/{chunk-7ZLQ4G47.js → chunk-I5QQKYHU.js} +1 -1
- package/dist/{chunk-ODEP5MMW.js → chunk-PCV7T4HR.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +2 -2
- package/dist/eventcatalog.js +3 -3
- package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewer.astro +1 -1
- package/eventcatalog/src/components/Tables/Table.tsx +33 -7
- package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +253 -0
- package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +289 -0
- package/eventcatalog/src/components/Tables/columns/index.tsx +6 -1
- package/eventcatalog/src/layouts/DirectoryLayout.astro +110 -0
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +11 -15
- package/eventcatalog/src/pages/directory/[type]/index.astro +69 -0
- package/eventcatalog/src/pages/directory/index.astro +242 -0
- package/eventcatalog/src/types/index.ts +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-3C6KBZOA.js";
|
|
4
|
+
import "../chunk-I5QQKYHU.js";
|
|
5
|
+
import "../chunk-PCV7T4HR.js";
|
|
6
6
|
import "../chunk-E7TXTI7G.js";
|
|
7
7
|
export {
|
|
8
8
|
log_build_default as default
|
|
@@ -34,7 +34,7 @@ __export(catalog_to_astro_content_directory_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(catalog_to_astro_content_directory_exports);
|
|
36
36
|
|
|
37
|
-
// node_modules/.pnpm/tsup@8.3.
|
|
37
|
+
// node_modules/.pnpm/tsup@8.3.6_jiti@1.21.7_postcss@8.5.1_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js
|
|
38
38
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
39
39
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
40
40
|
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
|
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
|
|
25
|
-
// node_modules/.pnpm/tsup@8.3.
|
|
25
|
+
// node_modules/.pnpm/tsup@8.3.6_jiti@1.21.7_postcss@8.5.1_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js
|
|
26
26
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
27
27
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
28
28
|
|
|
@@ -161,7 +161,7 @@ var import_axios = __toESM(require("axios"), 1);
|
|
|
161
161
|
var import_os = __toESM(require("os"), 1);
|
|
162
162
|
|
|
163
163
|
// package.json
|
|
164
|
-
var version = "2.
|
|
164
|
+
var version = "2.20.0";
|
|
165
165
|
|
|
166
166
|
// src/constants.ts
|
|
167
167
|
var VERSION = version;
|
package/dist/eventcatalog.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./chunk-SHCMAL37.js";
|
|
4
4
|
import {
|
|
5
5
|
log_build_default
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-3C6KBZOA.js";
|
|
7
|
+
import "./chunk-I5QQKYHU.js";
|
|
8
8
|
import {
|
|
9
9
|
catalogToAstro
|
|
10
10
|
} from "./chunk-WF34R5UT.js";
|
|
11
11
|
import {
|
|
12
12
|
VERSION
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PCV7T4HR.js";
|
|
14
14
|
import {
|
|
15
15
|
generate
|
|
16
16
|
} from "./chunk-YEQVKHST.js";
|
|
@@ -55,7 +55,7 @@ try {
|
|
|
55
55
|
} else {
|
|
56
56
|
schema = JSON.parse(schema);
|
|
57
57
|
// Lets JSON schema control if the component should be rendered or not
|
|
58
|
-
if (schema['x-eventcatalog-render-schema-viewer']) {
|
|
58
|
+
if (schema['x-eventcatalog-render-schema-viewer'] !== undefined) {
|
|
59
59
|
render = schema['x-eventcatalog-render-schema-viewer'];
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -20,14 +20,24 @@ import { isSameVersion } from '@utils/collections/util';
|
|
|
20
20
|
declare module '@tanstack/react-table' {
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
interface ColumnMeta<TData extends RowData, TValue> {
|
|
23
|
-
filterVariant?: 'collection' | 'name' | 'badges';
|
|
24
|
-
collectionFilterKey?:
|
|
23
|
+
filterVariant?: 'collection' | 'name' | 'badges' | 'text';
|
|
24
|
+
collectionFilterKey?:
|
|
25
|
+
| 'producers'
|
|
26
|
+
| 'consumers'
|
|
27
|
+
| 'sends'
|
|
28
|
+
| 'receives'
|
|
29
|
+
| 'services'
|
|
30
|
+
| 'ownedCommands'
|
|
31
|
+
| 'ownedEvents'
|
|
32
|
+
| 'ownedServices'
|
|
33
|
+
| 'associatedTeams';
|
|
34
|
+
filteredItemHasVersion?: boolean;
|
|
25
35
|
showFilter?: boolean;
|
|
26
36
|
className?: string;
|
|
27
37
|
}
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
export type TCollectionTypes = 'domains' | 'services' | CollectionMessageTypes | 'flows';
|
|
40
|
+
export type TCollectionTypes = 'domains' | 'services' | CollectionMessageTypes | 'flows' | 'users' | 'teams';
|
|
31
41
|
|
|
32
42
|
export type TData<T extends TCollectionTypes> = {
|
|
33
43
|
collection: T;
|
|
@@ -92,6 +102,19 @@ export type TData<T extends TCollectionTypes> = {
|
|
|
92
102
|
};
|
|
93
103
|
}>;
|
|
94
104
|
// ---------------------------------------------------------------------------
|
|
105
|
+
// Users
|
|
106
|
+
avatarUrl?: string;
|
|
107
|
+
email?: string;
|
|
108
|
+
slackDirectMessageUrl?: string;
|
|
109
|
+
msTeamsDirectMessageUrl?: string;
|
|
110
|
+
role?: string;
|
|
111
|
+
ownedCommands: any;
|
|
112
|
+
ownedEvents: any;
|
|
113
|
+
ownedServices: any;
|
|
114
|
+
associatedTeams: any;
|
|
115
|
+
|
|
116
|
+
// Teams
|
|
117
|
+
members: any;
|
|
95
118
|
};
|
|
96
119
|
};
|
|
97
120
|
|
|
@@ -121,7 +144,6 @@ export const Table = <T extends TCollectionTypes>({
|
|
|
121
144
|
|
|
122
145
|
useEffect(() => {
|
|
123
146
|
const checkbox = document.getElementById(checkboxLatestId);
|
|
124
|
-
|
|
125
147
|
function handleChange(evt: Event) {
|
|
126
148
|
setShowOnlyLatest((evt.target as HTMLInputElement).checked);
|
|
127
149
|
}
|
|
@@ -266,7 +288,7 @@ export const Table = <T extends TCollectionTypes>({
|
|
|
266
288
|
};
|
|
267
289
|
|
|
268
290
|
function Filter<T extends TCollectionTypes>({ column }: { column: Column<TData<T>, unknown> }) {
|
|
269
|
-
const { filterVariant, collectionFilterKey } = column.columnDef.meta ?? {};
|
|
291
|
+
const { filterVariant, collectionFilterKey, filteredItemHasVersion = true } = column.columnDef.meta ?? {};
|
|
270
292
|
|
|
271
293
|
const columnFilterValue = column.getFilterValue();
|
|
272
294
|
|
|
@@ -275,7 +297,9 @@ function Filter<T extends TCollectionTypes>({ column }: { column: Column<TData<T
|
|
|
275
297
|
const rows = column.getFacetedRowModel().rows;
|
|
276
298
|
const data = rows.map((row) => row.original.data?.[collectionFilterKey] ?? []).flat();
|
|
277
299
|
|
|
278
|
-
const allItems = data.map((item) =>
|
|
300
|
+
const allItems = data.map((item) =>
|
|
301
|
+
filteredItemHasVersion ? `${item?.data.name} (v${item?.data.version})` : `${item?.data.name}`
|
|
302
|
+
);
|
|
279
303
|
const uniqueItemsInList = Array.from(new Set(allItems));
|
|
280
304
|
|
|
281
305
|
return uniqueItemsInList.sort().slice(0, 2000);
|
|
@@ -289,7 +313,9 @@ function Filter<T extends TCollectionTypes>({ column }: { column: Column<TData<T
|
|
|
289
313
|
})
|
|
290
314
|
.flat();
|
|
291
315
|
|
|
292
|
-
const allItems = data.map((item) =>
|
|
316
|
+
const allItems = data.map((item) =>
|
|
317
|
+
filteredItemHasVersion ? `${item.data.name} (v${item.data.version})` : `${item.data.name}`
|
|
318
|
+
);
|
|
293
319
|
const uniqueItemsInList = Array.from(new Set(allItems));
|
|
294
320
|
|
|
295
321
|
return uniqueItemsInList.sort().slice(0, 2000);
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
|
|
2
|
+
import { createColumnHelper } from '@tanstack/react-table';
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
|
+
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
|
|
5
|
+
import { buildUrl } from '@utils/url-builder';
|
|
6
|
+
import type { TData } from '../Table';
|
|
7
|
+
import type { CollectionUserTypes } from '@types';
|
|
8
|
+
import { User, Users } from 'lucide-react';
|
|
9
|
+
import type { CollectionEntry } from 'astro:content';
|
|
10
|
+
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid';
|
|
11
|
+
|
|
12
|
+
const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
|
|
13
|
+
|
|
14
|
+
export const getColorAndIconForMessageType = (type: string) => {
|
|
15
|
+
switch (type) {
|
|
16
|
+
case 'event':
|
|
17
|
+
return { color: 'orange', Icon: BoltIcon };
|
|
18
|
+
case 'command':
|
|
19
|
+
return { color: 'blue', Icon: ChatBubbleLeftIcon };
|
|
20
|
+
case 'querie':
|
|
21
|
+
case 'query':
|
|
22
|
+
return { color: 'green', Icon: MagnifyingGlassIcon };
|
|
23
|
+
default:
|
|
24
|
+
return { color: 'gray', Icon: ChatBubbleLeftIcon };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const columns = () => [
|
|
29
|
+
columnHelper.accessor('data.name', {
|
|
30
|
+
id: 'name',
|
|
31
|
+
header: () => <span>Name</span>,
|
|
32
|
+
cell: (info) => {
|
|
33
|
+
const messageRaw = info.row.original;
|
|
34
|
+
const type = useMemo(() => messageRaw.collection.slice(0, -1), [messageRaw.collection]);
|
|
35
|
+
return (
|
|
36
|
+
<div className=" group ">
|
|
37
|
+
<a
|
|
38
|
+
href={buildUrl(`/docs/${messageRaw.collection}/${messageRaw.data.id}`)}
|
|
39
|
+
className={`group-hover:text-pink-500 flex space-x-1 items-center`}
|
|
40
|
+
>
|
|
41
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md group-hover:border-pink-400`}>
|
|
42
|
+
<span className="flex items-center">
|
|
43
|
+
<span className={`bg-pink-500 group-hover:bg-pink-600 h-full rounded-tl rounded-bl p-1`}>
|
|
44
|
+
{!messageRaw.data.avatarUrl && <Users className="h-4 w-4 text-white" />}
|
|
45
|
+
</span>
|
|
46
|
+
<span className="leading-none px-2 group-hover:underline group-hover:text-primary font-light">
|
|
47
|
+
{messageRaw.data.name}
|
|
48
|
+
</span>
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
</a>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
},
|
|
55
|
+
meta: {
|
|
56
|
+
filterVariant: 'name',
|
|
57
|
+
filteredItemHasVersion: false,
|
|
58
|
+
},
|
|
59
|
+
filterFn: filterByName,
|
|
60
|
+
}),
|
|
61
|
+
|
|
62
|
+
columnHelper.accessor('data.members', {
|
|
63
|
+
header: () => <span>Team members</span>,
|
|
64
|
+
meta: {
|
|
65
|
+
// filterVariant: 'collection',
|
|
66
|
+
showFilter: false,
|
|
67
|
+
},
|
|
68
|
+
cell: (info) => {
|
|
69
|
+
const members = info.getValue();
|
|
70
|
+
if (members?.length === 0 || !members)
|
|
71
|
+
return <div className="font-light text-sm text-gray-400/60 text-left italic">Team has no members</div>;
|
|
72
|
+
|
|
73
|
+
return <div>{members.length}</div>;
|
|
74
|
+
},
|
|
75
|
+
footer: (info) => info.column.id,
|
|
76
|
+
filterFn: filterByName,
|
|
77
|
+
}),
|
|
78
|
+
|
|
79
|
+
columnHelper.accessor('data.ownedCommands', {
|
|
80
|
+
header: () => <span>Owned commands</span>,
|
|
81
|
+
meta: {
|
|
82
|
+
filterVariant: 'collection',
|
|
83
|
+
collectionFilterKey: 'ownedCommands',
|
|
84
|
+
},
|
|
85
|
+
cell: (info) => {
|
|
86
|
+
const commands = info.getValue();
|
|
87
|
+
if (commands?.length === 0 || !commands)
|
|
88
|
+
return <div className="font-light text-sm text-gray-400/60 text-left italic">User owns no commands</div>;
|
|
89
|
+
|
|
90
|
+
const isExpandable = commands?.length > 10;
|
|
91
|
+
const isOpen = isExpandable ? commands?.length < 10 : true;
|
|
92
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div>
|
|
96
|
+
{isExpandable && (
|
|
97
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
98
|
+
{isExpanded ? '▼' : '▶'} {commands.length} command{commands.length !== 1 ? 's' : ''}
|
|
99
|
+
</button>
|
|
100
|
+
)}
|
|
101
|
+
{isExpanded && (
|
|
102
|
+
<ul>
|
|
103
|
+
{commands.map((command: CollectionEntry<'commands'>, index: number) => (
|
|
104
|
+
<li key={`${command.data.id}-${index}`} className="py-1 group font-light ">
|
|
105
|
+
<a
|
|
106
|
+
href={buildUrl(`/docs/${command.collection}/${command.data.id}/${command.data.version}`)}
|
|
107
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
108
|
+
>
|
|
109
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
110
|
+
<span className="flex items-center">
|
|
111
|
+
<span className={`bg-blue-500 h-full rounded-tl rounded-bl p-1`}>
|
|
112
|
+
<ChatBubbleLeftIcon className="h-4 w-4 text-white" />
|
|
113
|
+
</span>
|
|
114
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
115
|
+
{command.data.name} (v{command.data.version})
|
|
116
|
+
</span>
|
|
117
|
+
</span>
|
|
118
|
+
</div>
|
|
119
|
+
</a>
|
|
120
|
+
</li>
|
|
121
|
+
))}
|
|
122
|
+
</ul>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// return commands.length;
|
|
128
|
+
},
|
|
129
|
+
footer: (info) => info.column.id,
|
|
130
|
+
filterFn: filterCollectionByName('ownedCommands'),
|
|
131
|
+
}),
|
|
132
|
+
columnHelper.accessor('data.ownedEvents', {
|
|
133
|
+
header: () => <span>Owned Events</span>,
|
|
134
|
+
meta: {
|
|
135
|
+
filterVariant: 'collection',
|
|
136
|
+
collectionFilterKey: 'ownedEvents',
|
|
137
|
+
},
|
|
138
|
+
cell: (info) => {
|
|
139
|
+
const events = info.getValue();
|
|
140
|
+
if (events?.length === 0 || !events)
|
|
141
|
+
return <div className="font-light text-sm text-gray-400/80 text-left italic">User owns no events</div>;
|
|
142
|
+
|
|
143
|
+
const isExpandable = events?.length > 10;
|
|
144
|
+
const isOpen = isExpandable ? events?.length < 10 : true;
|
|
145
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div>
|
|
149
|
+
{isExpandable && (
|
|
150
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
151
|
+
{isExpanded ? '▼' : '▶'} {events.length} event{events.length !== 1 ? 's' : ''}
|
|
152
|
+
</button>
|
|
153
|
+
)}
|
|
154
|
+
{isExpanded && (
|
|
155
|
+
<ul>
|
|
156
|
+
{events.map((event: CollectionEntry<'events'>, index: number) => (
|
|
157
|
+
<li key={`${event.data.id}-${index}`} className="py-1 group font-light ">
|
|
158
|
+
<a
|
|
159
|
+
href={buildUrl(`/docs/${event.collection}/${event.data.id}/${event.data.version}`)}
|
|
160
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
161
|
+
>
|
|
162
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
163
|
+
<span className="flex items-center">
|
|
164
|
+
<span className={`bg-orange-500 h-full rounded-tl rounded-bl p-1`}>
|
|
165
|
+
<BoltIcon className="h-4 w-4 text-white" />
|
|
166
|
+
</span>
|
|
167
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
168
|
+
{event.data.name} (v{event.data.version})
|
|
169
|
+
</span>
|
|
170
|
+
</span>
|
|
171
|
+
</div>
|
|
172
|
+
</a>
|
|
173
|
+
</li>
|
|
174
|
+
))}
|
|
175
|
+
</ul>
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
178
|
+
);
|
|
179
|
+
},
|
|
180
|
+
footer: (info) => info.column.id,
|
|
181
|
+
filterFn: filterCollectionByName('ownedEvents'),
|
|
182
|
+
}),
|
|
183
|
+
columnHelper.accessor('data.ownedServices', {
|
|
184
|
+
header: () => <span>Owned Services</span>,
|
|
185
|
+
meta: {
|
|
186
|
+
filterVariant: 'collection',
|
|
187
|
+
collectionFilterKey: 'ownedServices',
|
|
188
|
+
},
|
|
189
|
+
cell: (info) => {
|
|
190
|
+
const services = info.getValue();
|
|
191
|
+
if (services?.length === 0 || !services)
|
|
192
|
+
return <div className="font-light text-sm text-gray-400/80 text-left italic">User owns no services</div>;
|
|
193
|
+
|
|
194
|
+
const isExpandable = services?.length > 10;
|
|
195
|
+
const isOpen = isExpandable ? services?.length < 10 : true;
|
|
196
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<div>
|
|
200
|
+
{isExpandable && (
|
|
201
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
202
|
+
{isExpanded ? '▼' : '▶'} {services.length} service{services.length !== 1 ? 's' : ''}
|
|
203
|
+
</button>
|
|
204
|
+
)}
|
|
205
|
+
{isExpanded && (
|
|
206
|
+
<ul>
|
|
207
|
+
{services.map((service: CollectionEntry<'services'>, index: number) => (
|
|
208
|
+
<li key={`${service.data.id}-${index}`} className="py-1 group font-light ">
|
|
209
|
+
<a
|
|
210
|
+
href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.version}`)}
|
|
211
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
212
|
+
>
|
|
213
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
214
|
+
<span className="flex items-center">
|
|
215
|
+
<span className={`bg-green-500 h-full rounded-tl rounded-bl p-1`}>
|
|
216
|
+
<ServerIcon className="h-4 w-4 text-white" />
|
|
217
|
+
</span>
|
|
218
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
219
|
+
{service.data.name} (v{service.data.version})
|
|
220
|
+
</span>
|
|
221
|
+
</span>
|
|
222
|
+
</div>
|
|
223
|
+
</a>
|
|
224
|
+
</li>
|
|
225
|
+
))}
|
|
226
|
+
</ul>
|
|
227
|
+
)}
|
|
228
|
+
</div>
|
|
229
|
+
);
|
|
230
|
+
},
|
|
231
|
+
footer: (info) => info.column.id,
|
|
232
|
+
filterFn: filterCollectionByName('ownedServices'),
|
|
233
|
+
}),
|
|
234
|
+
|
|
235
|
+
columnHelper.accessor('data.name', {
|
|
236
|
+
header: () => <span />,
|
|
237
|
+
cell: (info) => {
|
|
238
|
+
const domain = info.row.original;
|
|
239
|
+
return (
|
|
240
|
+
<a
|
|
241
|
+
className="hover:text-primary hover:underline px-4 font-light"
|
|
242
|
+
href={buildUrl(`/docs/${domain.collection}/${domain.data.id}`)}
|
|
243
|
+
>
|
|
244
|
+
View →
|
|
245
|
+
</a>
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
id: 'actions',
|
|
249
|
+
meta: {
|
|
250
|
+
showFilter: false,
|
|
251
|
+
},
|
|
252
|
+
}),
|
|
253
|
+
];
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { createColumnHelper } from '@tanstack/react-table';
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import { filterByName, filterCollectionByName } from '../filters/custom-filters';
|
|
4
|
+
import { buildUrl } from '@utils/url-builder';
|
|
5
|
+
import type { TData } from '../Table';
|
|
6
|
+
import type { CollectionUserTypes } from '@types';
|
|
7
|
+
import { User, Users } from 'lucide-react';
|
|
8
|
+
import type { CollectionEntry } from 'astro:content';
|
|
9
|
+
import { ServerIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid';
|
|
10
|
+
|
|
11
|
+
const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
|
|
12
|
+
|
|
13
|
+
export const columns = () => [
|
|
14
|
+
columnHelper.accessor('data.name', {
|
|
15
|
+
id: 'name',
|
|
16
|
+
header: () => <span>Name</span>,
|
|
17
|
+
cell: (info) => {
|
|
18
|
+
const messageRaw = info.row.original;
|
|
19
|
+
const type = useMemo(() => messageRaw.collection.slice(0, -1), [messageRaw.collection]);
|
|
20
|
+
return (
|
|
21
|
+
<div className=" group ">
|
|
22
|
+
<a
|
|
23
|
+
href={buildUrl(`/docs/${messageRaw.collection}/${messageRaw.data.id}`)}
|
|
24
|
+
className={`group-hover:text-gray-500 flex space-x-1 items-center`}
|
|
25
|
+
>
|
|
26
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md group-hover:border-gray-400`}>
|
|
27
|
+
<span className="flex items-center">
|
|
28
|
+
{!messageRaw.data.avatarUrl && (
|
|
29
|
+
<span className={`bg-gray-300 group-hover:bg-gray-600 h-full rounded-tl rounded-bl p-1`}>
|
|
30
|
+
<User className="h-4 w-4 text-white" />
|
|
31
|
+
</span>
|
|
32
|
+
)}
|
|
33
|
+
{messageRaw.data.avatarUrl && (
|
|
34
|
+
<img src={messageRaw.data.avatarUrl} alt={messageRaw.data.name} className="h-12 w-12 rounded-md p-0.5" />
|
|
35
|
+
)}
|
|
36
|
+
|
|
37
|
+
<span className="leading-none px-2 group-hover:underline group-hover:text-primary font-light">
|
|
38
|
+
{messageRaw.data.name}
|
|
39
|
+
</span>
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
</a>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
meta: {
|
|
47
|
+
filterVariant: 'name',
|
|
48
|
+
filteredItemHasVersion: false,
|
|
49
|
+
},
|
|
50
|
+
filterFn: filterByName,
|
|
51
|
+
}),
|
|
52
|
+
|
|
53
|
+
columnHelper.accessor('data.role', {
|
|
54
|
+
id: 'role',
|
|
55
|
+
header: () => 'Role',
|
|
56
|
+
cell: (info) => <span className="font-light ">{info.renderValue()}</span>,
|
|
57
|
+
footer: (info) => info.column.id,
|
|
58
|
+
meta: {
|
|
59
|
+
showFilter: false,
|
|
60
|
+
className: 'max-w-[200px]',
|
|
61
|
+
},
|
|
62
|
+
filterFn: filterCollectionByName('role'),
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
columnHelper.accessor('data.ownedCommands', {
|
|
66
|
+
header: () => <span>Owned commands</span>,
|
|
67
|
+
meta: {
|
|
68
|
+
filterVariant: 'collection',
|
|
69
|
+
collectionFilterKey: 'ownedCommands',
|
|
70
|
+
},
|
|
71
|
+
cell: (info) => {
|
|
72
|
+
const commands = info.getValue();
|
|
73
|
+
if (commands?.length === 0 || !commands)
|
|
74
|
+
return <div className="font-light text-sm text-gray-400/60 text-left italic">User owns no commands</div>;
|
|
75
|
+
|
|
76
|
+
const isExpandable = commands?.length > 10;
|
|
77
|
+
const isOpen = isExpandable ? commands?.length < 10 : true;
|
|
78
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div>
|
|
82
|
+
{isExpandable && (
|
|
83
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
84
|
+
{isExpanded ? '▼' : '▶'} {commands.length} command{commands.length !== 1 ? 's' : ''}
|
|
85
|
+
</button>
|
|
86
|
+
)}
|
|
87
|
+
{isExpanded && (
|
|
88
|
+
<ul>
|
|
89
|
+
{commands.map((command: CollectionEntry<'commands'>, index: number) => (
|
|
90
|
+
<li key={`${command.data.id}-${index}`} className="py-1 group font-light ">
|
|
91
|
+
<a
|
|
92
|
+
href={buildUrl(`/docs/${command.collection}/${command.data.id}/${command.data.version}`)}
|
|
93
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
94
|
+
>
|
|
95
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
96
|
+
<span className="flex items-center">
|
|
97
|
+
<span className={`bg-blue-500 h-full rounded-tl rounded-bl p-1`}>
|
|
98
|
+
<ChatBubbleLeftIcon className="h-4 w-4 text-white" />
|
|
99
|
+
</span>
|
|
100
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
101
|
+
{command.data.name} (v{command.data.version})
|
|
102
|
+
</span>
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
</a>
|
|
106
|
+
</li>
|
|
107
|
+
))}
|
|
108
|
+
</ul>
|
|
109
|
+
)}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// return commands.length;
|
|
114
|
+
},
|
|
115
|
+
footer: (info) => info.column.id,
|
|
116
|
+
filterFn: filterCollectionByName('ownedCommands'),
|
|
117
|
+
}),
|
|
118
|
+
columnHelper.accessor('data.ownedEvents', {
|
|
119
|
+
header: () => <span>Owned Events</span>,
|
|
120
|
+
meta: {
|
|
121
|
+
filterVariant: 'collection',
|
|
122
|
+
collectionFilterKey: 'ownedEvents',
|
|
123
|
+
},
|
|
124
|
+
cell: (info) => {
|
|
125
|
+
const events = info.getValue();
|
|
126
|
+
if (events?.length === 0 || !events)
|
|
127
|
+
return <div className="font-light text-sm text-gray-400/80 text-left italic">User owns no events</div>;
|
|
128
|
+
|
|
129
|
+
const isExpandable = events?.length > 10;
|
|
130
|
+
const isOpen = isExpandable ? events?.length < 10 : true;
|
|
131
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div>
|
|
135
|
+
{isExpandable && (
|
|
136
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
137
|
+
{isExpanded ? '▼' : '▶'} {events.length} event{events.length !== 1 ? 's' : ''}
|
|
138
|
+
</button>
|
|
139
|
+
)}
|
|
140
|
+
{isExpanded && (
|
|
141
|
+
<ul>
|
|
142
|
+
{events.map((event: CollectionEntry<'events'>, index: number) => (
|
|
143
|
+
<li key={`${event.data.id}-${index}`} className="py-1 group font-light ">
|
|
144
|
+
<a
|
|
145
|
+
href={buildUrl(`/docs/${event.collection}/${event.data.id}/${event.data.version}`)}
|
|
146
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
147
|
+
>
|
|
148
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
149
|
+
<span className="flex items-center">
|
|
150
|
+
<span className={`bg-orange-500 h-full rounded-tl rounded-bl p-1`}>
|
|
151
|
+
<BoltIcon className="h-4 w-4 text-white" />
|
|
152
|
+
</span>
|
|
153
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
154
|
+
{event.data.name} (v{event.data.version})
|
|
155
|
+
</span>
|
|
156
|
+
</span>
|
|
157
|
+
</div>
|
|
158
|
+
</a>
|
|
159
|
+
</li>
|
|
160
|
+
))}
|
|
161
|
+
</ul>
|
|
162
|
+
)}
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
footer: (info) => info.column.id,
|
|
167
|
+
filterFn: filterCollectionByName('ownedEvents'),
|
|
168
|
+
}),
|
|
169
|
+
columnHelper.accessor('data.ownedServices', {
|
|
170
|
+
header: () => <span>Owned Services</span>,
|
|
171
|
+
meta: {
|
|
172
|
+
filterVariant: 'collection',
|
|
173
|
+
collectionFilterKey: 'ownedServices',
|
|
174
|
+
},
|
|
175
|
+
cell: (info) => {
|
|
176
|
+
const services = info.getValue();
|
|
177
|
+
if (services?.length === 0 || !services)
|
|
178
|
+
return <div className="font-light text-sm text-gray-400/80 text-left italic">User owns no services</div>;
|
|
179
|
+
|
|
180
|
+
const isExpandable = services?.length > 10;
|
|
181
|
+
const isOpen = isExpandable ? services?.length < 10 : true;
|
|
182
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<div>
|
|
186
|
+
{isExpandable && (
|
|
187
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
188
|
+
{isExpanded ? '▼' : '▶'} {services.length} service{services.length !== 1 ? 's' : ''}
|
|
189
|
+
</button>
|
|
190
|
+
)}
|
|
191
|
+
{isExpanded && (
|
|
192
|
+
<ul>
|
|
193
|
+
{services.map((service: CollectionEntry<'services'>, index: number) => (
|
|
194
|
+
<li key={`${service.data.id}-${index}`} className="py-1 group font-light ">
|
|
195
|
+
<a
|
|
196
|
+
href={buildUrl(`/docs/${service.collection}/${service.data.id}/${service.data.version}`)}
|
|
197
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
198
|
+
>
|
|
199
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
200
|
+
<span className="flex items-center">
|
|
201
|
+
<span className={`bg-green-500 h-full rounded-tl rounded-bl p-1`}>
|
|
202
|
+
<ServerIcon className="h-4 w-4 text-white" />
|
|
203
|
+
</span>
|
|
204
|
+
<span className="leading-none px-2 group-hover:underline ">
|
|
205
|
+
{service.data.name} (v{service.data.version})
|
|
206
|
+
</span>
|
|
207
|
+
</span>
|
|
208
|
+
</div>
|
|
209
|
+
</a>
|
|
210
|
+
</li>
|
|
211
|
+
))}
|
|
212
|
+
</ul>
|
|
213
|
+
)}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
},
|
|
217
|
+
footer: (info) => info.column.id,
|
|
218
|
+
filterFn: filterCollectionByName('ownedServices'),
|
|
219
|
+
}),
|
|
220
|
+
columnHelper.accessor('data.associatedTeams', {
|
|
221
|
+
header: () => <span>Teams</span>,
|
|
222
|
+
meta: {
|
|
223
|
+
filterVariant: 'collection',
|
|
224
|
+
collectionFilterKey: 'associatedTeams',
|
|
225
|
+
filteredItemHasVersion: false,
|
|
226
|
+
},
|
|
227
|
+
cell: (info) => {
|
|
228
|
+
const teams = info.getValue();
|
|
229
|
+
|
|
230
|
+
const isExpandable = teams?.length > 10;
|
|
231
|
+
const isOpen = isExpandable ? teams?.length < 10 : true;
|
|
232
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
233
|
+
|
|
234
|
+
if (teams?.length === 0 || !teams)
|
|
235
|
+
return <div className="font-light text-sm text-gray-400/80 text-left italic">User is not associated with any teams</div>;
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<div>
|
|
239
|
+
{isExpandable && (
|
|
240
|
+
<button onClick={() => setIsExpanded(!isExpanded)} className="mb-2 text-sm text-gray-600 hover:text-gray-900">
|
|
241
|
+
{isExpanded ? '▼' : '▶'} {teams.length} team{teams.length !== 1 ? 's' : ''}
|
|
242
|
+
</button>
|
|
243
|
+
)}
|
|
244
|
+
{isExpanded && (
|
|
245
|
+
<ul>
|
|
246
|
+
{teams.map((team: CollectionEntry<'teams'>, index: number) => (
|
|
247
|
+
<li key={`${team.data.id}-${index}`} className="py-1 group font-light ">
|
|
248
|
+
<a
|
|
249
|
+
href={buildUrl(`/docs/teams/${team.data.id}`)}
|
|
250
|
+
className="group-hover:text-primary flex space-x-1 items-center "
|
|
251
|
+
>
|
|
252
|
+
<div className={`flex items-center border border-gray-300 shadow-sm rounded-md`}>
|
|
253
|
+
<span className="flex items-center">
|
|
254
|
+
<span className={`bg-pink-500 h-full rounded-tl rounded-bl p-1`}>
|
|
255
|
+
<Users className="h-4 w-4 text-white" />
|
|
256
|
+
</span>
|
|
257
|
+
<span className="leading-none px-2 group-hover:underline ">{team.data.name}</span>
|
|
258
|
+
</span>
|
|
259
|
+
</div>
|
|
260
|
+
</a>
|
|
261
|
+
</li>
|
|
262
|
+
))}
|
|
263
|
+
</ul>
|
|
264
|
+
)}
|
|
265
|
+
</div>
|
|
266
|
+
);
|
|
267
|
+
},
|
|
268
|
+
footer: (info) => info.column.id,
|
|
269
|
+
filterFn: filterCollectionByName('associatedTeams'),
|
|
270
|
+
}),
|
|
271
|
+
columnHelper.accessor('data.name', {
|
|
272
|
+
header: () => <span />,
|
|
273
|
+
cell: (info) => {
|
|
274
|
+
const domain = info.row.original;
|
|
275
|
+
return (
|
|
276
|
+
<a
|
|
277
|
+
className="hover:text-primary hover:underline px-4 font-light"
|
|
278
|
+
href={buildUrl(`/docs/${domain.collection}/${domain.data.id}`)}
|
|
279
|
+
>
|
|
280
|
+
View →
|
|
281
|
+
</a>
|
|
282
|
+
);
|
|
283
|
+
},
|
|
284
|
+
id: 'actions',
|
|
285
|
+
meta: {
|
|
286
|
+
showFilter: false,
|
|
287
|
+
},
|
|
288
|
+
}),
|
|
289
|
+
];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { columns as MessageTableColumns } from './MessageTableColumns';
|
|
2
|
+
import { columns as UserTableColumns } from './UserTableColumns';
|
|
2
3
|
import { columns as ServiceTableColumns } from './ServiceTableColumns';
|
|
3
4
|
import { columns as DomainTableColumns } from './DomainTableColumns';
|
|
4
5
|
import { columns as FlowTableColumns } from './FlowTableColumns';
|
|
5
|
-
|
|
6
|
+
import { columns as TeamsTableColumns } from './TeamsTableColumns';
|
|
6
7
|
export const getColumnsByCollection = (collection: string): any => {
|
|
7
8
|
switch (collection) {
|
|
8
9
|
case 'events':
|
|
@@ -15,6 +16,10 @@ export const getColumnsByCollection = (collection: string): any => {
|
|
|
15
16
|
return DomainTableColumns();
|
|
16
17
|
case 'flows':
|
|
17
18
|
return FlowTableColumns();
|
|
19
|
+
case 'users':
|
|
20
|
+
return UserTableColumns();
|
|
21
|
+
case 'teams':
|
|
22
|
+
return TeamsTableColumns();
|
|
18
23
|
default:
|
|
19
24
|
return [];
|
|
20
25
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Table, type TData, type TCollectionTypes } from '@components/Tables/Table';
|
|
3
|
+
import { QueueListIcon, RectangleGroupIcon, BoltIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/outline';
|
|
4
|
+
import ServerIcon from '@heroicons/react/24/outline/ServerIcon';
|
|
5
|
+
import { getCommands } from '@utils/commands';
|
|
6
|
+
import { getDomains } from '@utils/collections/domains';
|
|
7
|
+
import { getFlows } from '@utils/collections/flows';
|
|
8
|
+
import { getEvents } from '@utils/events';
|
|
9
|
+
import { getServices } from '@utils/collections/services';
|
|
10
|
+
import { buildUrl } from '@utils/url-builder';
|
|
11
|
+
import { getQueries } from '@utils/queries';
|
|
12
|
+
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid';
|
|
13
|
+
import VerticalSideBarLayout from './VerticalSideBarLayout.astro';
|
|
14
|
+
import Checkbox from '@components/Checkbox.astro';
|
|
15
|
+
import { User, Users } from 'lucide-react';
|
|
16
|
+
import { getUsers } from '@utils/users';
|
|
17
|
+
import { getTeams } from '@utils/teams';
|
|
18
|
+
|
|
19
|
+
const users = await getUsers();
|
|
20
|
+
const teams = await getTeams();
|
|
21
|
+
|
|
22
|
+
export interface Props<T extends TCollectionTypes> {
|
|
23
|
+
title: string;
|
|
24
|
+
subtitle: string;
|
|
25
|
+
data: TData<T>[];
|
|
26
|
+
type: T;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { title, subtitle, data, type } = Astro.props;
|
|
30
|
+
const currentPath = Astro.url.pathname;
|
|
31
|
+
|
|
32
|
+
const checkboxLatestId = 'latest-only';
|
|
33
|
+
|
|
34
|
+
const tabs = [
|
|
35
|
+
{
|
|
36
|
+
label: `Users (${users.length})`,
|
|
37
|
+
href: buildUrl('/directory/users'),
|
|
38
|
+
isActive: currentPath === '/directory/users',
|
|
39
|
+
icon: User,
|
|
40
|
+
activeColor: 'orange',
|
|
41
|
+
enabled: users.length > 0,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: `Teams (${teams.length})`,
|
|
45
|
+
href: buildUrl('/directory/teams'),
|
|
46
|
+
isActive: currentPath === '/directory/teams',
|
|
47
|
+
icon: Users,
|
|
48
|
+
activeColor: 'blue',
|
|
49
|
+
enabled: teams.length > 0,
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
<VerticalSideBarLayout title={`Explore | ${title}`}>
|
|
55
|
+
<main class="ml-0">
|
|
56
|
+
<div id="discover-collection-tabs">
|
|
57
|
+
<div class="hidden sm:block">
|
|
58
|
+
<div class="border-b border-gray-200">
|
|
59
|
+
<nav class="flex space-x-8 -mb-0.5 pl-6" aria-label="Tabs">
|
|
60
|
+
{
|
|
61
|
+
tabs.map((tab) => (
|
|
62
|
+
<a
|
|
63
|
+
href={tab.href}
|
|
64
|
+
class={` text-black group inline-flex items-center py-4 px-1 text-sm font-light ${tab.isActive ? `border-${tab.activeColor}-500 border-b-[2px] text-${tab.activeColor}-500` : 'opacity-80'} ${!tab.enabled ? 'disabled' : ''}`}
|
|
65
|
+
aria-current="page"
|
|
66
|
+
>
|
|
67
|
+
<tab.icon
|
|
68
|
+
className={`w-6 h-6 -ml-0.5 mr-2 ${tab.isActive ? `text-${tab.activeColor}-500` : 'text-gray-500'}`}
|
|
69
|
+
/>
|
|
70
|
+
<span>{tab.label}</span>
|
|
71
|
+
</a>
|
|
72
|
+
))
|
|
73
|
+
}
|
|
74
|
+
</nav>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- Table -->
|
|
80
|
+
<div class="pb-20 ml-6 md:pr-10">
|
|
81
|
+
<div>
|
|
82
|
+
<div class="sm:flex sm:items-end py-4 pb-4" id="discover-title">
|
|
83
|
+
<div class="sm:flex-auto space-y-2">
|
|
84
|
+
<h1 class="text-4xl font-semibold text-gray-900 capitalize">{title}</h1>
|
|
85
|
+
<p class="text-md text-gray-700">{subtitle}</p>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="mt-4 flow-root">
|
|
89
|
+
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
|
90
|
+
<div class="inline-block min-w-full align-middle sm:px-6 lg:px-8">
|
|
91
|
+
<Table checkboxLatestId={checkboxLatestId} data={data} collection={type} client:load />
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</main>
|
|
98
|
+
</VerticalSideBarLayout>
|
|
99
|
+
|
|
100
|
+
<style>
|
|
101
|
+
.ec-align-top {
|
|
102
|
+
vertical-align: top !important;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
a.disabled {
|
|
106
|
+
pointer-events: none;
|
|
107
|
+
cursor: default;
|
|
108
|
+
opacity: 0.25;
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
@@ -5,7 +5,7 @@ interface Props {
|
|
|
5
5
|
description?: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
import { BookOpenText, Workflow, TableProperties, House } from 'lucide-react';
|
|
8
|
+
import { BookOpenText, Workflow, TableProperties, House, BookUser } from 'lucide-react';
|
|
9
9
|
import Header from '../components/Header.astro';
|
|
10
10
|
import SEO from '../components/Seo.astro';
|
|
11
11
|
|
|
@@ -14,8 +14,6 @@ import { getDomains } from '@utils/collections/domains';
|
|
|
14
14
|
import { getEvents } from '@utils/events';
|
|
15
15
|
import { getServices } from '@utils/collections/services';
|
|
16
16
|
import { getFlows } from '@utils/collections/flows';
|
|
17
|
-
import { getTeams } from '@utils/teams';
|
|
18
|
-
import { getUsers } from '@utils/users';
|
|
19
17
|
import { isCollectionVisibleInCatalog } from '@eventcatalog';
|
|
20
18
|
import { buildUrl } from '@utils/url-builder';
|
|
21
19
|
import { getQueries } from '@utils/queries';
|
|
@@ -30,13 +28,11 @@ const services = await getServices({ getAllVersions: false });
|
|
|
30
28
|
const domains = await getDomains({ getAllVersions: false });
|
|
31
29
|
const channels = await getChannels({ getAllVersions: false });
|
|
32
30
|
const flows = await getFlows({ getAllVersions: false });
|
|
33
|
-
const teams = await getTeams();
|
|
34
|
-
const users = await getUsers();
|
|
35
31
|
|
|
36
32
|
const messages = [...events, ...commands, ...queries];
|
|
37
33
|
|
|
38
34
|
// @ts-ignore for large catalogs https://github.com/event-catalog/eventcatalog/issues/552
|
|
39
|
-
const allData = [...domains, ...services, ...messages, ...channels, ...flows
|
|
35
|
+
const allData = [...domains, ...services, ...messages, ...channels, ...flows];
|
|
40
36
|
|
|
41
37
|
const currentPath = Astro.url.pathname;
|
|
42
38
|
|
|
@@ -95,6 +91,14 @@ const navigationItems = [
|
|
|
95
91
|
current: currentPath.includes('/discover/'),
|
|
96
92
|
sidebar: false,
|
|
97
93
|
},
|
|
94
|
+
{
|
|
95
|
+
id: '/directory',
|
|
96
|
+
label: 'Directory',
|
|
97
|
+
icon: BookUser,
|
|
98
|
+
href: buildUrl('/directory/users'),
|
|
99
|
+
current: currentPath.includes('/directory'),
|
|
100
|
+
sidebar: false,
|
|
101
|
+
},
|
|
98
102
|
];
|
|
99
103
|
|
|
100
104
|
const allDataAsSideNav = allData.reduce((acc, item) => {
|
|
@@ -103,17 +107,9 @@ const allDataAsSideNav = allData.reduce((acc, item) => {
|
|
|
103
107
|
const currentPath = Astro.url.pathname;
|
|
104
108
|
const route = currentPath.includes('visualiser') ? 'visualiser' : 'docs';
|
|
105
109
|
|
|
106
|
-
if (
|
|
107
|
-
currentPath.includes('visualiser') &&
|
|
108
|
-
(item.collection === 'teams' || item.collection === 'users' || item.collection === 'channels')
|
|
109
|
-
) {
|
|
110
|
-
return acc;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
110
|
const navigationItem = {
|
|
114
111
|
label: item.data.name,
|
|
115
|
-
version: item.
|
|
116
|
-
// items: item.collection === 'users' ? [] : item.headings,
|
|
112
|
+
version: item.data.version,
|
|
117
113
|
visible: isCollectionVisibleInCatalog(item.collection),
|
|
118
114
|
// @ts-ignore
|
|
119
115
|
href: item.data.version
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getUsers } from '@utils/users';
|
|
3
|
+
import { getTeams } from '@utils/teams';
|
|
4
|
+
|
|
5
|
+
import DirectoryLayout, { type Props as DirectoryLayoutProps } from '@layouts/DirectoryLayout.astro';
|
|
6
|
+
|
|
7
|
+
export async function getStaticPaths() {
|
|
8
|
+
const loaders = {
|
|
9
|
+
users: getUsers,
|
|
10
|
+
teams: getTeams,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const itemTypes = ['users', 'teams'] as const;
|
|
14
|
+
const allItems = await Promise.all(itemTypes.map((type) => loaders[type]()));
|
|
15
|
+
|
|
16
|
+
return allItems.flatMap((items, index) => ({
|
|
17
|
+
params: {
|
|
18
|
+
type: itemTypes[index],
|
|
19
|
+
},
|
|
20
|
+
props: {
|
|
21
|
+
data: items,
|
|
22
|
+
type: itemTypes[index],
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { type, data } = Astro.props;
|
|
28
|
+
|
|
29
|
+
function mapToItem(i: any) {
|
|
30
|
+
return {
|
|
31
|
+
collection: i.collection,
|
|
32
|
+
data: {
|
|
33
|
+
id: i.data.id,
|
|
34
|
+
name: i.data.name,
|
|
35
|
+
version: i.data.version,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
<DirectoryLayout
|
|
42
|
+
title={`${type} (${data.length})`}
|
|
43
|
+
subtitle={`Find, filter and search for any ${type} in your system.`}
|
|
44
|
+
data={data.map(
|
|
45
|
+
(d) =>
|
|
46
|
+
({
|
|
47
|
+
collection: d.collection,
|
|
48
|
+
data: {
|
|
49
|
+
id: d.data.id,
|
|
50
|
+
name: d.data.name,
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
role: d.data?.role,
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
avatarUrl: d.data?.avatarUrl,
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
associatedTeams: d.data?.associatedTeams?.map(mapToItem) ?? [],
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
ownedCommands: d.data?.ownedCommands?.map(mapToItem) ?? [],
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
ownedEvents: d.data?.ownedEvents?.map(mapToItem) ?? [],
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
ownedServices: d.data?.ownedServices?.map(mapToItem) ?? [],
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
members: d.data?.members,
|
|
65
|
+
},
|
|
66
|
+
}) as DirectoryLayoutProps<typeof type>['data'][0]
|
|
67
|
+
)}
|
|
68
|
+
type={type}
|
|
69
|
+
/>
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
import VerticalSideBarLayout from '../../layouts/VerticalSideBarLayout.astro';
|
|
3
|
+
import { getUsers } from '@utils/users';
|
|
4
|
+
import { getTeams } from '@utils/teams';
|
|
5
|
+
|
|
6
|
+
const users = await getUsers();
|
|
7
|
+
const teams = await getTeams();
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<VerticalSideBarLayout title="EventCatalog">
|
|
11
|
+
<body class="min-h-screen bg-gray-50">
|
|
12
|
+
<main>
|
|
13
|
+
<div class="container mx-auto px-6 py-20 max-w-[90em]">
|
|
14
|
+
<div class="mb-12">
|
|
15
|
+
<h1 class="text-3xl font-bold text-gray-900 mb-8">Users</h1>
|
|
16
|
+
<div class="bg-white shadow-sm rounded-lg overflow-hidden">
|
|
17
|
+
<table class="min-w-full divide-y divide-gray-200">
|
|
18
|
+
<thead class="bg-gray-50">
|
|
19
|
+
<tr>
|
|
20
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
|
|
21
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Role</th>
|
|
22
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th
|
|
23
|
+
>
|
|
24
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
|
25
|
+
>Contact</th
|
|
26
|
+
>
|
|
27
|
+
</tr>
|
|
28
|
+
</thead>
|
|
29
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
|
30
|
+
{
|
|
31
|
+
users.map((user: any) => (
|
|
32
|
+
<tr class="hover:bg-gray-50">
|
|
33
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
34
|
+
<a href={`/docs/users/${user.data.id}`} class="flex items-center">
|
|
35
|
+
<div class="flex-shrink-0 h-10 w-10">
|
|
36
|
+
<div class="h-10 w-10 bg-blue-100 rounded-full flex items-center justify-center overflow-hidden">
|
|
37
|
+
{user.data.avatarUrl ? (
|
|
38
|
+
<img src={user.data.avatarUrl} alt={user.data.name} class="h-10 w-10 object-cover" />
|
|
39
|
+
) : (
|
|
40
|
+
<svg
|
|
41
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
42
|
+
class="h-5 w-5 text-blue-600"
|
|
43
|
+
fill="none"
|
|
44
|
+
viewBox="0 0 24 24"
|
|
45
|
+
stroke="currentColor"
|
|
46
|
+
>
|
|
47
|
+
<path
|
|
48
|
+
stroke-linecap="round"
|
|
49
|
+
stroke-linejoin="round"
|
|
50
|
+
stroke-width="2"
|
|
51
|
+
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
|
52
|
+
/>
|
|
53
|
+
</svg>
|
|
54
|
+
)}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="ml-4">
|
|
58
|
+
<div class="text-sm font-medium text-gray-900">{user.data.name}</div>
|
|
59
|
+
</div>
|
|
60
|
+
</a>
|
|
61
|
+
</td>
|
|
62
|
+
<td class="px-6 py-4">
|
|
63
|
+
<div class="text-sm text-gray-900">{user.data.role}</div>
|
|
64
|
+
</td>
|
|
65
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
66
|
+
{user.data.email && <div class="text-sm text-gray-900">{user.data.email}</div>}
|
|
67
|
+
</td>
|
|
68
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
69
|
+
<div class="flex items-center space-x-2">
|
|
70
|
+
{user.data.slackDirectMessageUrl && (
|
|
71
|
+
<a
|
|
72
|
+
href={user.data.slackDirectMessageUrl}
|
|
73
|
+
target="_blank"
|
|
74
|
+
rel="noopener"
|
|
75
|
+
class="text-gray-500 hover:text-gray-700"
|
|
76
|
+
>
|
|
77
|
+
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
|
78
|
+
<path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z" />
|
|
79
|
+
</svg>
|
|
80
|
+
</a>
|
|
81
|
+
)}
|
|
82
|
+
{user.data.msTeamsDirectMessageUrl && (
|
|
83
|
+
<a
|
|
84
|
+
href={user.data.msTeamsDirectMessageUrl}
|
|
85
|
+
target="_blank"
|
|
86
|
+
rel="noopener"
|
|
87
|
+
class="text-gray-500 hover:text-gray-700"
|
|
88
|
+
>
|
|
89
|
+
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
|
90
|
+
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" />
|
|
91
|
+
</svg>
|
|
92
|
+
</a>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
</td>
|
|
96
|
+
</tr>
|
|
97
|
+
))
|
|
98
|
+
}
|
|
99
|
+
</tbody>
|
|
100
|
+
</table>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="mb-12">
|
|
105
|
+
<h1 class="text-3xl font-bold text-gray-900 mb-8">Teams</h1>
|
|
106
|
+
<div class="bg-white shadow-sm rounded-lg overflow-hidden">
|
|
107
|
+
<table class="min-w-full divide-y divide-gray-200">
|
|
108
|
+
<thead class="bg-gray-50">
|
|
109
|
+
<tr>
|
|
110
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
|
|
111
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
|
112
|
+
>Summary</th
|
|
113
|
+
>
|
|
114
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
|
115
|
+
>Members</th
|
|
116
|
+
>
|
|
117
|
+
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
|
118
|
+
>Contact</th
|
|
119
|
+
>
|
|
120
|
+
</tr>
|
|
121
|
+
</thead>
|
|
122
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
|
123
|
+
{
|
|
124
|
+
teams.map((team: any) => (
|
|
125
|
+
<tr class="hover:bg-gray-50">
|
|
126
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
127
|
+
<a href={`/docs/teams/${team.data.id}`} class="flex items-center">
|
|
128
|
+
<div class="flex-shrink-0 h-10 w-10">
|
|
129
|
+
<div class="h-10 w-10 bg-green-100 rounded-full flex items-center justify-center overflow-hidden">
|
|
130
|
+
{team.data.avatarUrl ? (
|
|
131
|
+
<img src={team.data.avatarUrl} alt={team.data.name} class="h-10 w-10 object-cover" />
|
|
132
|
+
) : (
|
|
133
|
+
<svg
|
|
134
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
135
|
+
class="h-5 w-5 text-green-600"
|
|
136
|
+
fill="none"
|
|
137
|
+
viewBox="0 0 24 24"
|
|
138
|
+
stroke="currentColor"
|
|
139
|
+
>
|
|
140
|
+
<path
|
|
141
|
+
stroke-linecap="round"
|
|
142
|
+
stroke-linejoin="round"
|
|
143
|
+
stroke-width="2"
|
|
144
|
+
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
|
145
|
+
/>
|
|
146
|
+
</svg>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="ml-4">
|
|
151
|
+
<div class="text-sm font-medium text-gray-900">{team.data.name}</div>
|
|
152
|
+
</div>
|
|
153
|
+
</a>
|
|
154
|
+
</td>
|
|
155
|
+
<td class="px-6 py-4">
|
|
156
|
+
<div class="text-sm text-gray-900">{team.data.summary}</div>
|
|
157
|
+
</td>
|
|
158
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
159
|
+
{team.data.members && <div class="text-sm text-gray-900">{team.data.members.length} members</div>}
|
|
160
|
+
</td>
|
|
161
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
162
|
+
<div class="flex items-center space-x-2">
|
|
163
|
+
{team.data.slackDirectMessageUrl && (
|
|
164
|
+
<a
|
|
165
|
+
href={team.data.slackDirectMessageUrl}
|
|
166
|
+
target="_blank"
|
|
167
|
+
rel="noopener"
|
|
168
|
+
class="text-gray-500 hover:text-gray-700"
|
|
169
|
+
>
|
|
170
|
+
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
|
171
|
+
<path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z" />
|
|
172
|
+
</svg>
|
|
173
|
+
</a>
|
|
174
|
+
)}
|
|
175
|
+
{team.data.msTeamsDirectMessageUrl && (
|
|
176
|
+
<a
|
|
177
|
+
href={team.data.msTeamsDirectMessageUrl}
|
|
178
|
+
target="_blank"
|
|
179
|
+
rel="noopener"
|
|
180
|
+
class="text-gray-500 hover:text-gray-700"
|
|
181
|
+
>
|
|
182
|
+
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
|
183
|
+
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" />
|
|
184
|
+
</svg>
|
|
185
|
+
</a>
|
|
186
|
+
)}
|
|
187
|
+
</div>
|
|
188
|
+
</td>
|
|
189
|
+
</tr>
|
|
190
|
+
))
|
|
191
|
+
}
|
|
192
|
+
</tbody>
|
|
193
|
+
</table>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</main>
|
|
198
|
+
</body>
|
|
199
|
+
</VerticalSideBarLayout>
|
|
200
|
+
|
|
201
|
+
<style>
|
|
202
|
+
.filter-btn.active {
|
|
203
|
+
background-color: #f3f4f6;
|
|
204
|
+
color: #111827;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.filter-btn {
|
|
208
|
+
color: #6b7280;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.filter-btn:hover {
|
|
212
|
+
color: #111827;
|
|
213
|
+
}
|
|
214
|
+
</style>
|
|
215
|
+
|
|
216
|
+
<script>
|
|
217
|
+
const filterButtons = document.querySelectorAll('.filter-btn');
|
|
218
|
+
const rows = document.querySelectorAll('tr[data-type]');
|
|
219
|
+
|
|
220
|
+
filterButtons.forEach((button) => {
|
|
221
|
+
button.addEventListener('click', () => {
|
|
222
|
+
filterButtons.forEach((btn) => btn.classList.remove('active'));
|
|
223
|
+
button.classList.add('active');
|
|
224
|
+
|
|
225
|
+
const filter = button.getAttribute('data-filter');
|
|
226
|
+
|
|
227
|
+
rows.forEach((row) => {
|
|
228
|
+
if (filter === 'all') {
|
|
229
|
+
row.style.display = 'table-row';
|
|
230
|
+
} else {
|
|
231
|
+
const rowType = row.getAttribute('data-type');
|
|
232
|
+
row.style.display = rowType === filter ? 'table-row' : 'none';
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const defaultButton = document.querySelector('[data-filter="all"]');
|
|
239
|
+
if (defaultButton) {
|
|
240
|
+
defaultButton.classList.add('active');
|
|
241
|
+
}
|
|
242
|
+
</script>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type CollectionTypes = 'commands' | 'events' | 'queries' | 'domains' | 'services' | 'flows' | 'channels';
|
|
2
2
|
export type CollectionMessageTypes = 'commands' | 'events' | 'queries';
|
|
3
|
-
|
|
3
|
+
export type CollectionUserTypes = 'users';
|
|
4
4
|
export type PageTypes = 'events' | 'commands' | 'queries' | 'services' | 'domains' | 'channels';
|