@eventcatalog/core 2.31.4 → 2.32.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/{chunk-C3M26NRD.js → chunk-EIEK445B.js} +1 -1
- package/dist/{chunk-W5HUNIMM.js → chunk-NPZQE3LM.js} +1 -1
- package/dist/{chunk-H5QIDJHP.js → chunk-YXHR3YSA.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +3 -3
- package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +67 -0
- package/eventcatalog/src/components/MDX/MessageTable/MessageTable.client.tsx +2 -2
- package/eventcatalog/src/components/MDX/ResourceGroupTable/ResourceGroupTable.astro +126 -0
- package/eventcatalog/src/components/MDX/ResourceGroupTable/ResourceGroupTable.client.tsx +408 -0
- package/eventcatalog/src/components/MDX/components.tsx +2 -0
- package/eventcatalog/src/components/SideBars/DomainSideBar.astro +8 -0
- package/eventcatalog/src/components/SideBars/FlowSideBar.astro +8 -1
- package/eventcatalog/src/components/SideBars/MessageSideBar.astro +8 -0
- package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +8 -1
- package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +1 -1
- package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +4 -6
- package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +0 -15
- package/eventcatalog/src/content.config.ts +17 -0
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +26 -96
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +19 -16
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/types.ts +1 -0
- package/eventcatalog/src/enterprise/custom-documentation/pages/{index.astro → docs/custom/index.astro} +10 -5
- package/eventcatalog/src/enterprise/custom-documentation/utils/custom-docs.ts +6 -3
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +4 -4
- package/eventcatalog/src/utils/collections/icons.ts +29 -0
- package/eventcatalog/src/utils/collections/services.ts +4 -4
- package/package.json +1 -1
- package/eventcatalog/src/components/SideNav/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -11
- package/eventcatalog/src/components/SideNav/CustomDocsNav/components/NestedItem.tsx +0 -183
- package/eventcatalog/src/components/SideNav/CustomDocsNav/components/NoResultsFound.tsx +0 -21
- package/eventcatalog/src/components/SideNav/CustomDocsNav/index.tsx +0 -250
- package/eventcatalog/src/components/SideNav/CustomDocsNav/types.ts +0 -29
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
-
import { buildUrl } from '@utils/url-builder';
|
|
3
|
-
import type { CustomDocsNavProps, SidebarSection, SidebarItem } from './types';
|
|
4
|
-
import NestedItem from './components/NestedItem';
|
|
5
|
-
import NoResultsFound from './components/NoResultsFound';
|
|
6
|
-
|
|
7
|
-
const STORAGE_KEY = 'EventCatalog:customDocsSidebarCollapsedGroups';
|
|
8
|
-
const DEBOUNCE_DELAY = 300; // 300ms debounce delay
|
|
9
|
-
|
|
10
|
-
const CustomDocsNav: React.FC<CustomDocsNavProps> = ({ sidebarItems, currentPath }) => {
|
|
11
|
-
const navRef = useRef<HTMLElement>(null);
|
|
12
|
-
const [searchTerm, setSearchTerm] = useState('');
|
|
13
|
-
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('');
|
|
14
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
15
|
-
const [collapsedGroups, setCollapsedGroups] = useState<{ [key: string]: boolean }>(() => {
|
|
16
|
-
if (typeof window !== 'undefined') {
|
|
17
|
-
const saved = window.localStorage.getItem(STORAGE_KEY);
|
|
18
|
-
setIsInitialized(true);
|
|
19
|
-
return saved ? JSON.parse(saved) : {};
|
|
20
|
-
}
|
|
21
|
-
return {};
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// Set up debounced search
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
const timer = setTimeout(() => {
|
|
27
|
-
setDebouncedSearchTerm(searchTerm.toLowerCase());
|
|
28
|
-
}, DEBOUNCE_DELAY);
|
|
29
|
-
|
|
30
|
-
return () => clearTimeout(timer);
|
|
31
|
-
}, [searchTerm]);
|
|
32
|
-
|
|
33
|
-
// Filter sidebar items based on search term
|
|
34
|
-
const filteredSidebarItems = useMemo(() => {
|
|
35
|
-
if (!debouncedSearchTerm) return sidebarItems;
|
|
36
|
-
|
|
37
|
-
const matchesSearchTerm = (text: string) => text.toLowerCase().includes(debouncedSearchTerm);
|
|
38
|
-
|
|
39
|
-
// Helper function to check if an item or any of its nested items match the search term
|
|
40
|
-
const itemContainsSearchTerm = (item: SidebarItem): boolean => {
|
|
41
|
-
if (matchesSearchTerm(item.label)) return true;
|
|
42
|
-
|
|
43
|
-
if (item.items && item.items.length > 0) {
|
|
44
|
-
return item.items.some(itemContainsSearchTerm);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return false;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
return sidebarItems
|
|
51
|
-
.map((section) => {
|
|
52
|
-
if (!section.items) {
|
|
53
|
-
return matchesSearchTerm(section.label) ? section : null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const filteredItems = section.items.filter(itemContainsSearchTerm);
|
|
57
|
-
|
|
58
|
-
if (filteredItems.length > 0 || matchesSearchTerm(section.label)) {
|
|
59
|
-
return {
|
|
60
|
-
...section,
|
|
61
|
-
items: filteredItems,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
})
|
|
67
|
-
.filter(Boolean) as SidebarSection[];
|
|
68
|
-
}, [sidebarItems, debouncedSearchTerm]);
|
|
69
|
-
|
|
70
|
-
// Auto-expand groups when searching
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
if (debouncedSearchTerm) {
|
|
73
|
-
// Expand all groups when searching
|
|
74
|
-
const newCollapsedState = { ...collapsedGroups };
|
|
75
|
-
Object.keys(newCollapsedState).forEach((key) => {
|
|
76
|
-
newCollapsedState[key] = false;
|
|
77
|
-
});
|
|
78
|
-
setCollapsedGroups(newCollapsedState);
|
|
79
|
-
}
|
|
80
|
-
}, [debouncedSearchTerm]);
|
|
81
|
-
|
|
82
|
-
// Store collapsed groups in local storage
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
if (typeof window !== 'undefined' && isInitialized) {
|
|
85
|
-
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(collapsedGroups));
|
|
86
|
-
}
|
|
87
|
-
}, [collapsedGroups, isInitialized]);
|
|
88
|
-
|
|
89
|
-
// Initialize collapsed state from section config
|
|
90
|
-
useEffect(() => {
|
|
91
|
-
if (isInitialized && sidebarItems && sidebarItems.length > 0) {
|
|
92
|
-
const initialState = { ...collapsedGroups };
|
|
93
|
-
|
|
94
|
-
sidebarItems.forEach((section, index) => {
|
|
95
|
-
const sectionKey = `section-${index}`;
|
|
96
|
-
if (section.collapsed !== undefined && initialState[sectionKey] === undefined) {
|
|
97
|
-
initialState[sectionKey] = section.collapsed;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
setCollapsedGroups(initialState);
|
|
102
|
-
}
|
|
103
|
-
}, [sidebarItems, isInitialized]);
|
|
104
|
-
|
|
105
|
-
// If we find a data-active element, scroll to it on mount
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
const activeElement = document.querySelector('[data-active="true"]');
|
|
108
|
-
if (activeElement) {
|
|
109
|
-
// Add y offset to the scroll position
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
activeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
112
|
-
}, 300);
|
|
113
|
-
}
|
|
114
|
-
}, []);
|
|
115
|
-
|
|
116
|
-
const toggleGroupCollapse = useCallback((group: string) => {
|
|
117
|
-
setCollapsedGroups((prev) => ({
|
|
118
|
-
...prev,
|
|
119
|
-
[group]: !prev[group],
|
|
120
|
-
}));
|
|
121
|
-
}, []);
|
|
122
|
-
|
|
123
|
-
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
124
|
-
setSearchTerm(e.target.value);
|
|
125
|
-
}, []);
|
|
126
|
-
|
|
127
|
-
if (!isInitialized) return null;
|
|
128
|
-
|
|
129
|
-
const hasNoResults = debouncedSearchTerm && filteredSidebarItems.length === 0;
|
|
130
|
-
|
|
131
|
-
return (
|
|
132
|
-
<nav ref={navRef} className="h-full text-gray-800 pt-2">
|
|
133
|
-
<div className="mb-2 px-4">
|
|
134
|
-
<input
|
|
135
|
-
type="text"
|
|
136
|
-
value={searchTerm}
|
|
137
|
-
onChange={handleSearchChange}
|
|
138
|
-
placeholder="Quick search..."
|
|
139
|
-
className="w-full p-2 text-sm rounded-md border border-gray-200 h-[30px]"
|
|
140
|
-
/>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div className="space-y-2 divide-y divide-gray-100/40">
|
|
144
|
-
{hasNoResults ? (
|
|
145
|
-
<NoResultsFound searchTerm={debouncedSearchTerm} />
|
|
146
|
-
) : (
|
|
147
|
-
filteredSidebarItems.map((section: SidebarSection, index: number) => (
|
|
148
|
-
<div className="pt-2 pb-2 px-4" key={`section-${index}`}>
|
|
149
|
-
<div className="space-y-0" data-section={`section-${index}`}>
|
|
150
|
-
{section.items ? (
|
|
151
|
-
<div className="flex items-center">
|
|
152
|
-
<button
|
|
153
|
-
className="p-1 hover:bg-gray-100 rounded-md"
|
|
154
|
-
onClick={(e) => {
|
|
155
|
-
e.stopPropagation();
|
|
156
|
-
toggleGroupCollapse(`section-${index}`);
|
|
157
|
-
}}
|
|
158
|
-
>
|
|
159
|
-
<div
|
|
160
|
-
className={`transition-transform duration-150 ${collapsedGroups[`section-${index}`] ? '' : 'rotate-180'}`}
|
|
161
|
-
>
|
|
162
|
-
<svg
|
|
163
|
-
className="h-3 w-3 text-gray-500"
|
|
164
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
165
|
-
width="16"
|
|
166
|
-
height="16"
|
|
167
|
-
viewBox="0 0 24 24"
|
|
168
|
-
fill="none"
|
|
169
|
-
stroke="currentColor"
|
|
170
|
-
strokeWidth="2"
|
|
171
|
-
strokeLinecap="round"
|
|
172
|
-
strokeLinejoin="round"
|
|
173
|
-
>
|
|
174
|
-
<polyline points="6 9 12 15 18 9" />
|
|
175
|
-
</svg>
|
|
176
|
-
</div>
|
|
177
|
-
</button>
|
|
178
|
-
<button
|
|
179
|
-
className="flex-grow flex items-center justify-between px-2 py-0.5 text-xs font-bold rounded-md hover:bg-purple-50"
|
|
180
|
-
onClick={(e) => {
|
|
181
|
-
e.stopPropagation();
|
|
182
|
-
toggleGroupCollapse(`section-${index}`);
|
|
183
|
-
}}
|
|
184
|
-
>
|
|
185
|
-
<span className="truncate">{section.label}</span>
|
|
186
|
-
{section.badge && section?.badge?.text && (
|
|
187
|
-
<span
|
|
188
|
-
className={`text-${section.badge.color || 'purple'}-600 ml-2 text-[10px] font-medium bg-${section.badge.color || 'purple'}-50 px-2 py-0.5 rounded uppercase`}
|
|
189
|
-
>
|
|
190
|
-
{section.badge.text}
|
|
191
|
-
</span>
|
|
192
|
-
)}
|
|
193
|
-
</button>
|
|
194
|
-
</div>
|
|
195
|
-
) : (
|
|
196
|
-
<div className="flex items-center">
|
|
197
|
-
<span className="flex-grow flex items-center justify-between px-2 py-0.5 text-xs font-bold rounded-md">
|
|
198
|
-
<span className="truncate">{section.label}</span>
|
|
199
|
-
<span className="text-purple-600 ml-2 text-[10px] font-medium bg-purple-50 px-2 py-0.5 rounded uppercase">
|
|
200
|
-
Section
|
|
201
|
-
</span>
|
|
202
|
-
</span>
|
|
203
|
-
</div>
|
|
204
|
-
)}
|
|
205
|
-
|
|
206
|
-
{section.items && (
|
|
207
|
-
<div
|
|
208
|
-
className={`overflow-hidden transition-[height] duration-150 ease-out ${
|
|
209
|
-
collapsedGroups[`section-${index}`] ? 'h-0' : 'h-auto'
|
|
210
|
-
}`}
|
|
211
|
-
>
|
|
212
|
-
<div className="space-y-0.5 border-gray-200/80 border-l pl-4 ml-[9px] mt-1">
|
|
213
|
-
{section.items.map((item: SidebarItem, itemIndex: number) => (
|
|
214
|
-
<NestedItem
|
|
215
|
-
key={`item-${index}-${itemIndex}`}
|
|
216
|
-
item={item}
|
|
217
|
-
currentPath={currentPath}
|
|
218
|
-
parentId={`${index}`}
|
|
219
|
-
itemIndex={itemIndex}
|
|
220
|
-
collapsedGroups={collapsedGroups}
|
|
221
|
-
toggleGroupCollapse={toggleGroupCollapse}
|
|
222
|
-
/>
|
|
223
|
-
))}
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
)}
|
|
227
|
-
|
|
228
|
-
{section.slug && !section.items && (
|
|
229
|
-
<a
|
|
230
|
-
href={buildUrl(`/docs/custom/${section.slug}`)}
|
|
231
|
-
className={`flex items-center px-2 py-1.5 text-xs ${
|
|
232
|
-
currentPath.endsWith(`/${section.slug}`)
|
|
233
|
-
? 'bg-purple-100 text-purple-900 font-medium'
|
|
234
|
-
: 'text-gray-600 hover:bg-purple-100'
|
|
235
|
-
} rounded-md ml-6`}
|
|
236
|
-
data-active={currentPath.endsWith(`/${section.slug}`)}
|
|
237
|
-
>
|
|
238
|
-
<span className="truncate">{section.label}</span>
|
|
239
|
-
</a>
|
|
240
|
-
)}
|
|
241
|
-
</div>
|
|
242
|
-
</div>
|
|
243
|
-
))
|
|
244
|
-
)}
|
|
245
|
-
</div>
|
|
246
|
-
</nav>
|
|
247
|
-
);
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
export default React.memo(CustomDocsNav);
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export interface SidebarItem {
|
|
2
|
-
label: string;
|
|
3
|
-
slug?: string;
|
|
4
|
-
items?: SidebarItem[];
|
|
5
|
-
badge?: {
|
|
6
|
-
text: string;
|
|
7
|
-
color: string;
|
|
8
|
-
};
|
|
9
|
-
collapsed?: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface SidebarSection {
|
|
13
|
-
label: string;
|
|
14
|
-
items?: SidebarItem[];
|
|
15
|
-
slug?: string;
|
|
16
|
-
autogenerated?: {
|
|
17
|
-
directory: string;
|
|
18
|
-
};
|
|
19
|
-
badge?: {
|
|
20
|
-
text: string;
|
|
21
|
-
color: string;
|
|
22
|
-
};
|
|
23
|
-
collapsed?: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface CustomDocsNavProps {
|
|
27
|
-
sidebarItems: SidebarSection[];
|
|
28
|
-
currentPath: string;
|
|
29
|
-
}
|