@eventcatalog/core 3.30.0 → 3.31.2
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-Z26P4PCB.js → chunk-5VANHNV3.js} +1 -1
- package/dist/{chunk-RRBDF4MM.js → chunk-7FECQ5B3.js} +1 -1
- package/dist/{chunk-MVZKHUX2.js → chunk-DL3PF5MS.js} +1 -1
- package/dist/{chunk-6UG4JMUV.js → chunk-IPGFRHRL.js} +1 -1
- package/dist/{chunk-ATRBVTJ6.js → chunk-UOKUSIKW.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 +5 -5
- 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/astro.config.mjs +10 -6
- package/eventcatalog/public/logo.png +0 -0
- package/eventcatalog/src/components/CopyAsMarkdown.tsx +29 -24
- package/eventcatalog/src/components/MDX/Design/Design.astro +1 -1
- package/eventcatalog/src/components/MDX/Tiles/Tile.astro +11 -8
- package/eventcatalog/src/components/SchemaExplorer/AvroSchemaViewer.tsx +25 -18
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +218 -0
- package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +265 -0
- package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +371 -0
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +183 -0
- package/eventcatalog/src/components/Settings/LogoUpload.tsx +137 -0
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +91 -0
- package/eventcatalog/src/components/Settings/ReadOnlyBanner.tsx +18 -0
- package/eventcatalog/src/components/Settings/Row.tsx +59 -0
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +176 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +17 -18
- package/eventcatalog/src/components/Tables/Discover/DiscoverTable.tsx +45 -16
- package/eventcatalog/src/components/Tables/Discover/FilterComponents.tsx +2 -2
- package/eventcatalog/src/content.config.ts +1 -1
- package/eventcatalog/src/enterprise/auth/middleware/middleware-auth.ts +11 -7
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +4 -4
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +70 -57
- package/eventcatalog/src/enterprise/feature.ts +2 -1
- package/eventcatalog/src/layouts/SettingsLayout.astro +116 -0
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +62 -23
- package/eventcatalog/src/pages/_index.astro +250 -255
- package/eventcatalog/src/pages/api/settings/ai.ts +57 -0
- package/eventcatalog/src/pages/api/settings/general.ts +71 -0
- package/eventcatalog/src/pages/api/settings/logo.ts +113 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +26 -32
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +40 -31
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +2 -26
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +5 -1
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -1
- package/eventcatalog/src/pages/settings/assistant.astro +37 -0
- package/eventcatalog/src/pages/settings/billing.astro +17 -0
- package/eventcatalog/src/pages/settings/general.astro +32 -0
- package/eventcatalog/src/pages/settings/index.astro +21 -0
- package/eventcatalog/src/pages/settings/llm-access.astro +34 -0
- package/eventcatalog/src/pages/settings/mcp.astro +14 -0
- package/eventcatalog/src/styles/theme.css +38 -29
- package/eventcatalog/src/styles/themes/forest.css +17 -9
- package/eventcatalog/src/styles/themes/ocean.css +10 -2
- package/eventcatalog/src/styles/themes/sapphire.css +10 -2
- package/eventcatalog/src/styles/themes/sunset.css +25 -17
- package/eventcatalog/src/utils/eventcatalog-config/config-schema.ts +49 -0
- package/eventcatalog/src/utils/eventcatalog-config/config-writer.ts +149 -0
- package/eventcatalog/src/utils/url-builder.ts +4 -2
- package/package.json +7 -5
- package/eventcatalog/src/pages/docs/llm/llms-services.txt.ts +0 -81
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { ExternalLink, Server, ServerCog } from 'lucide-react';
|
|
2
|
+
import { Row } from './Row';
|
|
3
|
+
import { LiveCard, MCP_DOCS_URL, UpgradeRequired, UrlPanel } from './SettingsShared';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
hasScalePlan: boolean;
|
|
7
|
+
inSSR: boolean;
|
|
8
|
+
mcpUrl: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const McpSettingsForm = ({ hasScalePlan, inSSR, mcpUrl }: Props) => {
|
|
12
|
+
const mcpAvailable = hasScalePlan && inSSR;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="divide-y divide-[rgb(var(--ec-page-border))]">
|
|
16
|
+
<Row
|
|
17
|
+
title="MCP Server"
|
|
18
|
+
description="Expose your catalog over the Model Context Protocol so AI agents (Claude Desktop, Cursor, etc.) can query your architecture as a live data source."
|
|
19
|
+
canEdit={false}
|
|
20
|
+
dirty={false}
|
|
21
|
+
>
|
|
22
|
+
{mcpAvailable ? (
|
|
23
|
+
<McpAvailable url={mcpUrl} />
|
|
24
|
+
) : !hasScalePlan ? (
|
|
25
|
+
<UpgradeRequired
|
|
26
|
+
tier="Scale"
|
|
27
|
+
blurb="The MCP Server is a Scale-plan feature. Upgrade to expose your catalog to AI agents over the Model Context Protocol."
|
|
28
|
+
docsUrl={MCP_DOCS_URL}
|
|
29
|
+
/>
|
|
30
|
+
) : (
|
|
31
|
+
<McpNeedsSSR />
|
|
32
|
+
)}
|
|
33
|
+
</Row>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const McpAvailable = ({ url }: { url: string }) => (
|
|
39
|
+
<div className="space-y-3">
|
|
40
|
+
<LiveCard
|
|
41
|
+
icon={<Server className="h-4 w-4" aria-hidden />}
|
|
42
|
+
title="MCP server is live"
|
|
43
|
+
description="Point Claude Desktop, Cursor, or any MCP-aware client at the endpoint below."
|
|
44
|
+
/>
|
|
45
|
+
<div className="rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.4)] px-4 py-3">
|
|
46
|
+
<p className="text-[12px] font-medium text-[rgb(var(--ec-page-text))]">Endpoint</p>
|
|
47
|
+
<UrlPanel url={url} />
|
|
48
|
+
<a
|
|
49
|
+
href={MCP_DOCS_URL}
|
|
50
|
+
target="_blank"
|
|
51
|
+
rel="noreferrer"
|
|
52
|
+
className="mt-3 inline-flex items-center gap-1 text-[12px] font-medium text-[rgb(var(--ec-accent))] hover:underline"
|
|
53
|
+
>
|
|
54
|
+
Connect a client
|
|
55
|
+
<ExternalLink className="h-3 w-3" aria-hidden />
|
|
56
|
+
</a>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const McpNeedsSSR = () => (
|
|
62
|
+
<div className="overflow-hidden rounded-lg border border-[rgb(var(--ec-accent)/0.4)] bg-gradient-to-br from-[rgb(var(--ec-accent)/0.1)] via-[rgb(var(--ec-accent)/0.05)] to-transparent">
|
|
63
|
+
<div className="flex items-start gap-3 px-4 py-3.5">
|
|
64
|
+
<span className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-[rgb(var(--ec-accent)/0.4)] bg-[rgb(var(--ec-accent)/0.1)] text-[rgb(var(--ec-accent))]">
|
|
65
|
+
<ServerCog className="h-4 w-4" aria-hidden />
|
|
66
|
+
</span>
|
|
67
|
+
<div className="flex-1 min-w-0">
|
|
68
|
+
<div className="flex items-center gap-2">
|
|
69
|
+
<p className="text-[13px] font-semibold text-[rgb(var(--ec-page-text))]">Server output mode required</p>
|
|
70
|
+
<span className="inline-flex items-center gap-1 rounded-full border border-[rgb(var(--ec-accent)/0.4)] bg-[rgb(var(--ec-accent)/0.1)] px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-[rgb(var(--ec-accent))]">
|
|
71
|
+
SSR
|
|
72
|
+
</span>
|
|
73
|
+
</div>
|
|
74
|
+
<p className="mt-1 text-[12px] leading-snug text-[rgb(var(--ec-page-text-muted))]">
|
|
75
|
+
The MCP Server requires your catalog to run in server (SSR) mode. Follow the setup guide to switch.
|
|
76
|
+
</p>
|
|
77
|
+
<div className="mt-3 flex flex-wrap items-center gap-3">
|
|
78
|
+
<a
|
|
79
|
+
href={MCP_DOCS_URL}
|
|
80
|
+
target="_blank"
|
|
81
|
+
rel="noreferrer"
|
|
82
|
+
className="inline-flex items-center gap-1 rounded-md bg-[rgb(var(--ec-accent))] px-3 py-1.5 text-[12px] font-semibold text-white shadow-sm transition-colors hover:bg-[rgb(var(--ec-accent-hover))]"
|
|
83
|
+
>
|
|
84
|
+
MCP setup guide
|
|
85
|
+
<ExternalLink className="h-3 w-3" aria-hidden />
|
|
86
|
+
</a>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Lock } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
export const ReadOnlyBanner = () => (
|
|
4
|
+
<div
|
|
5
|
+
role="status"
|
|
6
|
+
className="mb-6 flex items-start gap-3 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] p-4 text-sm text-[rgb(var(--ec-page-text))]"
|
|
7
|
+
>
|
|
8
|
+
<Lock className="mt-0.5 h-4 w-4 flex-shrink-0 text-[rgb(var(--ec-page-text-muted))]" aria-hidden />
|
|
9
|
+
<div className="space-y-1">
|
|
10
|
+
<p className="font-medium">Read-only</p>
|
|
11
|
+
<p className="text-[rgb(var(--ec-page-text-muted))]">
|
|
12
|
+
To edit these settings, run EventCatalog locally or update them in your{' '}
|
|
13
|
+
<code className="rounded bg-[rgb(var(--ec-page-bg)/0.78)] px-1 py-0.5 font-mono text-xs">eventcatalog.config.js</code>{' '}
|
|
14
|
+
file.
|
|
15
|
+
</p>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AlertCircle } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
export const cn = (...parts: Array<string | false | undefined | null>): string => parts.filter(Boolean).join(' ');
|
|
4
|
+
|
|
5
|
+
export const inputBase =
|
|
6
|
+
'block w-full rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg,var(--ec-page-bg)))] px-3 py-2 text-[13px] text-[rgb(var(--ec-page-text))] placeholder:text-[rgb(var(--ec-page-text-muted)/0.7)] transition-colors focus:border-[rgb(var(--ec-accent)/0.6)] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent)/0.25)] disabled:cursor-not-allowed disabled:opacity-60';
|
|
7
|
+
|
|
8
|
+
export const monoInput = 'font-mono text-[12.5px] tracking-tight';
|
|
9
|
+
|
|
10
|
+
export const inputError = 'border-red-500/70 focus:border-red-500 focus:ring-red-500/20';
|
|
11
|
+
|
|
12
|
+
interface RowProps {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
canEdit: boolean;
|
|
16
|
+
dirty: boolean;
|
|
17
|
+
saving?: boolean;
|
|
18
|
+
onSave?: () => void;
|
|
19
|
+
error?: string;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const Row = ({ title, description, canEdit, dirty, saving, onSave, error, children }: RowProps) => (
|
|
24
|
+
<section className="grid grid-cols-1 gap-6 py-8 md:grid-cols-[minmax(0,_18rem)_minmax(0,_1fr)] md:gap-12">
|
|
25
|
+
<header className="space-y-1.5">
|
|
26
|
+
<h3 className="text-[14px] font-semibold tracking-tight text-[rgb(var(--ec-page-text))]">{title}</h3>
|
|
27
|
+
<p className="text-[13px] leading-relaxed text-[rgb(var(--ec-content-text-muted,var(--ec-page-text-muted)))]">
|
|
28
|
+
{description}
|
|
29
|
+
</p>
|
|
30
|
+
</header>
|
|
31
|
+
<div className="space-y-2.5">
|
|
32
|
+
{children}
|
|
33
|
+
{error && (
|
|
34
|
+
<p className="flex items-center gap-1.5 text-[12px] text-red-500">
|
|
35
|
+
<AlertCircle className="h-3 w-3 flex-shrink-0" aria-hidden />
|
|
36
|
+
{error}
|
|
37
|
+
</p>
|
|
38
|
+
)}
|
|
39
|
+
{onSave && canEdit && (
|
|
40
|
+
<div className="pt-1">
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
onClick={onSave}
|
|
44
|
+
disabled={!dirty || saving}
|
|
45
|
+
className={cn(
|
|
46
|
+
'inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-[12px] font-medium transition-colors',
|
|
47
|
+
dirty && !saving
|
|
48
|
+
? 'border-[rgb(var(--ec-accent)/0.5)] bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.8)]'
|
|
49
|
+
: 'border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))]',
|
|
50
|
+
'disabled:cursor-not-allowed disabled:opacity-60'
|
|
51
|
+
)}
|
|
52
|
+
>
|
|
53
|
+
{saving ? 'Saving…' : 'Save changes'}
|
|
54
|
+
</button>
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
</section>
|
|
59
|
+
);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { toast } from 'sonner';
|
|
3
|
+
import { ExternalLink, Lock, Sparkles, Copy, Check as CheckIcon } from 'lucide-react';
|
|
4
|
+
import { cn } from './Row';
|
|
5
|
+
|
|
6
|
+
export const ASSISTANT_DOCS_URL =
|
|
7
|
+
'https://www.eventcatalog.dev/docs/development/ask-your-architecture/eventcatalog-assistant/what-is-eventcatalog-assistant';
|
|
8
|
+
export const ASSISTANT_CONFIGURATION_DOCS_URL =
|
|
9
|
+
'https://www.eventcatalog.dev/docs/development/ask-your-architecture/eventcatalog-assistant/configuration';
|
|
10
|
+
export const MCP_DOCS_URL = 'https://www.eventcatalog.dev/docs/development/ask-your-architecture/mcp-server/getting-started';
|
|
11
|
+
export const PRICING_URL = 'https://www.eventcatalog.dev/pricing';
|
|
12
|
+
|
|
13
|
+
interface UpgradeRequiredProps {
|
|
14
|
+
tier: string;
|
|
15
|
+
blurb: string;
|
|
16
|
+
docsUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const UpgradeRequired = ({ tier, blurb, docsUrl }: UpgradeRequiredProps) => (
|
|
20
|
+
<div className="overflow-hidden rounded-lg border border-amber-500/40 bg-gradient-to-br from-amber-500/10 via-amber-500/5 to-transparent">
|
|
21
|
+
<div className="flex items-start gap-3 px-4 py-3.5">
|
|
22
|
+
<span className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-amber-500/40 bg-amber-500/10 text-amber-500">
|
|
23
|
+
<Lock className="h-4 w-4" aria-hidden />
|
|
24
|
+
</span>
|
|
25
|
+
<div className="flex-1 min-w-0">
|
|
26
|
+
<div className="flex items-center gap-2">
|
|
27
|
+
<p className="text-[13px] font-semibold text-[rgb(var(--ec-page-text))]">Available on {tier}</p>
|
|
28
|
+
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/40 bg-amber-500/10 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-500">
|
|
29
|
+
<Sparkles className="h-2.5 w-2.5" aria-hidden />
|
|
30
|
+
Upgrade
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
<p className="mt-1 text-[12px] leading-snug text-[rgb(var(--ec-page-text-muted))]">{blurb}</p>
|
|
34
|
+
<div className="mt-3 flex flex-wrap items-center gap-3">
|
|
35
|
+
<a
|
|
36
|
+
href={PRICING_URL}
|
|
37
|
+
target="_blank"
|
|
38
|
+
rel="noreferrer"
|
|
39
|
+
className="inline-flex items-center gap-1 rounded-md bg-amber-500 px-3 py-1.5 text-[12px] font-semibold text-white shadow-sm transition-colors hover:bg-amber-600"
|
|
40
|
+
>
|
|
41
|
+
View plans
|
|
42
|
+
<ExternalLink className="h-3 w-3" aria-hidden />
|
|
43
|
+
</a>
|
|
44
|
+
{docsUrl && (
|
|
45
|
+
<a
|
|
46
|
+
href={docsUrl}
|
|
47
|
+
target="_blank"
|
|
48
|
+
rel="noreferrer"
|
|
49
|
+
className="inline-flex items-center gap-1 text-[12px] font-medium text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))]"
|
|
50
|
+
>
|
|
51
|
+
Learn more
|
|
52
|
+
<ExternalLink className="h-3 w-3" aria-hidden />
|
|
53
|
+
</a>
|
|
54
|
+
)}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
interface UrlPanelProps {
|
|
62
|
+
url: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const UrlPanel = ({ url }: UrlPanelProps) => {
|
|
66
|
+
const [copied, setCopied] = useState(false);
|
|
67
|
+
const copy = async () => {
|
|
68
|
+
try {
|
|
69
|
+
await navigator.clipboard.writeText(new URL(url, window.location.origin).href);
|
|
70
|
+
setCopied(true);
|
|
71
|
+
setTimeout(() => setCopied(false), 1600);
|
|
72
|
+
} catch {
|
|
73
|
+
toast.error('Could not copy URL');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return (
|
|
77
|
+
<div className="mt-2 flex items-center gap-2">
|
|
78
|
+
<a
|
|
79
|
+
href={url}
|
|
80
|
+
target="_blank"
|
|
81
|
+
rel="noreferrer"
|
|
82
|
+
className="flex-1 truncate rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] px-2.5 py-1.5 font-mono text-[12px] text-[rgb(var(--ec-page-text))] transition-colors hover:border-[rgb(var(--ec-accent)/0.5)] hover:text-[rgb(var(--ec-accent))]"
|
|
83
|
+
>
|
|
84
|
+
{url}
|
|
85
|
+
</a>
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
onClick={copy}
|
|
89
|
+
aria-label="Copy URL"
|
|
90
|
+
className="inline-flex h-7 w-7 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))] transition-colors hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]"
|
|
91
|
+
>
|
|
92
|
+
{copied ? <CheckIcon className="h-3.5 w-3.5 text-green-500" aria-hidden /> : <Copy className="h-3.5 w-3.5" aria-hidden />}
|
|
93
|
+
</button>
|
|
94
|
+
<a
|
|
95
|
+
href={url}
|
|
96
|
+
target="_blank"
|
|
97
|
+
rel="noreferrer"
|
|
98
|
+
aria-label="Open in new tab"
|
|
99
|
+
className="inline-flex h-7 w-7 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))] transition-colors hover:bg-[rgb(var(--ec-page-bg)/0.78)] hover:text-[rgb(var(--ec-page-text))]"
|
|
100
|
+
>
|
|
101
|
+
<ExternalLink className="h-3.5 w-3.5" aria-hidden />
|
|
102
|
+
</a>
|
|
103
|
+
</div>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
interface LiveCardProps {
|
|
108
|
+
icon: React.ReactNode;
|
|
109
|
+
title: string;
|
|
110
|
+
description: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const LiveCard = ({ icon, title, description }: LiveCardProps) => (
|
|
114
|
+
<div className="flex items-center gap-3 rounded-lg border border-emerald-500/30 bg-emerald-500/5 px-4 py-3">
|
|
115
|
+
<span className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-emerald-500/30 bg-emerald-500/10 text-emerald-500">
|
|
116
|
+
{icon}
|
|
117
|
+
</span>
|
|
118
|
+
<div className="flex-1 min-w-0">
|
|
119
|
+
<p className="text-[13px] font-medium text-[rgb(var(--ec-page-text))]">{title}</p>
|
|
120
|
+
<p className="text-[12px] leading-snug text-[rgb(var(--ec-page-text-muted))]">{description}</p>
|
|
121
|
+
</div>
|
|
122
|
+
<span className="flex-shrink-0 rounded-full border border-emerald-500/30 bg-emerald-500/10 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-emerald-500">
|
|
123
|
+
Live
|
|
124
|
+
</span>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
interface ToggleProps {
|
|
129
|
+
checked: boolean;
|
|
130
|
+
disabled?: boolean;
|
|
131
|
+
onChange: (v: boolean) => void;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const Toggle = ({ checked, disabled, onChange }: ToggleProps) => (
|
|
135
|
+
<button
|
|
136
|
+
type="button"
|
|
137
|
+
role="switch"
|
|
138
|
+
aria-checked={checked}
|
|
139
|
+
disabled={disabled}
|
|
140
|
+
onClick={() => onChange(!checked)}
|
|
141
|
+
className={cn(
|
|
142
|
+
'relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer items-center rounded-full transition-colors',
|
|
143
|
+
checked ? 'bg-[rgb(var(--ec-accent))]' : 'bg-[rgb(var(--ec-page-text-muted)/0.35)]',
|
|
144
|
+
disabled && 'cursor-not-allowed opacity-50'
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
147
|
+
<span
|
|
148
|
+
className={cn(
|
|
149
|
+
'inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow-sm transition-transform',
|
|
150
|
+
checked ? 'translate-x-[1.125rem]' : 'translate-x-[0.1875rem]'
|
|
151
|
+
)}
|
|
152
|
+
/>
|
|
153
|
+
</button>
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
interface ToggleRowProps {
|
|
157
|
+
icon: React.ReactNode;
|
|
158
|
+
label: string;
|
|
159
|
+
hint: string;
|
|
160
|
+
checked: boolean;
|
|
161
|
+
disabled?: boolean;
|
|
162
|
+
onChange: (v: boolean) => void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const ToggleRow = ({ icon, label, hint, checked, disabled, onChange }: ToggleRowProps) => (
|
|
166
|
+
<div className="flex items-center gap-3 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg,var(--ec-page-bg)))] px-4 py-3">
|
|
167
|
+
<span className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))]">
|
|
168
|
+
{icon}
|
|
169
|
+
</span>
|
|
170
|
+
<div className="flex-1 min-w-0">
|
|
171
|
+
<p className="text-[13px] font-medium text-[rgb(var(--ec-page-text))]">{label}</p>
|
|
172
|
+
<p className="text-[12px] leading-snug text-[rgb(var(--ec-page-text-muted))]">{hint}</p>
|
|
173
|
+
</div>
|
|
174
|
+
<Toggle checked={checked} disabled={disabled} onChange={onChange} />
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
@@ -501,9 +501,9 @@ export default function NestedSideBar() {
|
|
|
501
501
|
// Show loading state if no data yet
|
|
502
502
|
if (!data || roots.length === 0) {
|
|
503
503
|
return (
|
|
504
|
-
<aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-
|
|
504
|
+
<aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-rail-bg))]">
|
|
505
505
|
{/* Search skeleton */}
|
|
506
|
-
<div className="px-4 py-3 border-b border-[rgb(var(--ec-content-border))] bg-[rgb(var(--ec-
|
|
506
|
+
<div className="px-4 py-3 border-b border-[rgb(var(--ec-content-border))] bg-[rgb(var(--ec-rail-bg))]">
|
|
507
507
|
<div className="h-10 bg-[rgb(var(--ec-content-hover))] rounded-xl animate-pulse" />
|
|
508
508
|
</div>
|
|
509
509
|
{/* Content skeleton */}
|
|
@@ -749,10 +749,9 @@ export default function NestedSideBar() {
|
|
|
749
749
|
)}
|
|
750
750
|
<span
|
|
751
751
|
className={cn(
|
|
752
|
-
'tracking-tight',
|
|
753
752
|
isSubtleGroup
|
|
754
|
-
? 'text-[
|
|
755
|
-
: 'text-[12px] text-[rgb(var(--ec-content-text))]
|
|
753
|
+
? 'text-[10px] font-semibold uppercase tracking-[0.12em] text-[rgb(var(--ec-content-text-muted))]'
|
|
754
|
+
: 'text-[12px] font-semibold tracking-tight text-[rgb(var(--ec-content-text))]'
|
|
756
755
|
)}
|
|
757
756
|
>
|
|
758
757
|
{group.title}
|
|
@@ -771,7 +770,7 @@ export default function NestedSideBar() {
|
|
|
771
770
|
);
|
|
772
771
|
|
|
773
772
|
return (
|
|
774
|
-
<div key={`group-${groupKey || index}`} className={cn(isSubtleGroup ? 'mb-
|
|
773
|
+
<div key={`group-${groupKey || index}`} className={cn(isSubtleGroup ? 'mb-2 last:mb-1' : 'mb-5 last:mb-2')}>
|
|
775
774
|
{canCollapse ? (
|
|
776
775
|
<button
|
|
777
776
|
onClick={() => toggleSectionCollapse(groupId)}
|
|
@@ -793,7 +792,7 @@ export default function NestedSideBar() {
|
|
|
793
792
|
<div
|
|
794
793
|
className={cn(
|
|
795
794
|
'flex flex-col gap-0.5 border-[rgb(var(--ec-content-border))]',
|
|
796
|
-
isSubtleGroup ? '
|
|
795
|
+
isSubtleGroup ? 'mt-0.5' : shouldFlattenSubtleChildren ? 'mt-1' : 'border-l ml-4 mt-1'
|
|
797
796
|
)}
|
|
798
797
|
>
|
|
799
798
|
{visibleChildren.map((childRef, childIndex) => {
|
|
@@ -896,11 +895,9 @@ export default function NestedSideBar() {
|
|
|
896
895
|
);
|
|
897
896
|
|
|
898
897
|
const baseClasses =
|
|
899
|
-
'group flex items-center justify-between w-full px-3 py-
|
|
898
|
+
'group flex items-center justify-between w-full px-3 py-1.5 border border-transparent cursor-pointer text-left transition-colors hover:bg-[rgb(var(--ec-content-hover))] active:bg-[rgb(var(--ec-content-hover))]';
|
|
900
899
|
const parentClasses = itemHasChildren ? 'font-medium' : '';
|
|
901
|
-
const activeClasses = isActive
|
|
902
|
-
? 'border-[rgb(var(--ec-accent)/0.16)] bg-[rgb(var(--ec-accent-subtle))] hover:bg-[rgb(var(--ec-accent-subtle))] shadow-sm'
|
|
903
|
-
: '';
|
|
900
|
+
const activeClasses = isActive ? 'bg-[rgb(var(--ec-rail-active-bg))] hover:bg-[rgb(var(--ec-rail-active-bg))]' : '';
|
|
904
901
|
|
|
905
902
|
// Leaf item with href → render as link
|
|
906
903
|
if (item.href && !itemHasChildren) {
|
|
@@ -938,18 +935,18 @@ export default function NestedSideBar() {
|
|
|
938
935
|
};
|
|
939
936
|
|
|
940
937
|
return (
|
|
941
|
-
<aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-
|
|
938
|
+
<aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-rail-bg))]">
|
|
942
939
|
{isTopLevel && (
|
|
943
|
-
<div className="
|
|
944
|
-
<
|
|
945
|
-
|
|
946
|
-
</
|
|
940
|
+
<div className="flex h-[60px] items-center px-6 bg-[rgb(var(--ec-rail-bg)/0.98)] backdrop-blur-sm border-b border-[rgb(var(--ec-content-border))] sticky top-0 z-10">
|
|
941
|
+
<span className="text-[0.65rem] font-semibold uppercase tracking-[0.18em] text-[rgb(var(--ec-sidebar-text)/0.5)] truncate">
|
|
942
|
+
All resources
|
|
943
|
+
</span>
|
|
947
944
|
</div>
|
|
948
945
|
)}
|
|
949
946
|
|
|
950
947
|
{!isTopLevel && (
|
|
951
948
|
<div
|
|
952
|
-
className="
|
|
949
|
+
className="flex h-[60px] items-center px-4 bg-[rgb(var(--ec-rail-bg)/0.98)] backdrop-blur-sm border-b border-[rgb(var(--ec-content-border))] sticky top-0 z-10"
|
|
953
950
|
onMouseEnter={() => !isTopLevel && setShowPathPreview(true)}
|
|
954
951
|
onMouseLeave={() => {
|
|
955
952
|
setShowPathPreview(false);
|
|
@@ -974,7 +971,9 @@ export default function NestedSideBar() {
|
|
|
974
971
|
>
|
|
975
972
|
<ChevronLeft className="w-4 h-4" />
|
|
976
973
|
</span>
|
|
977
|
-
<span className="text-[
|
|
974
|
+
<span className="text-[0.65rem] font-semibold uppercase tracking-[0.18em] text-[rgb(var(--ec-sidebar-text))] truncate">
|
|
975
|
+
{currentLevel.title}
|
|
976
|
+
</span>
|
|
978
977
|
{currentLevel.badge && (
|
|
979
978
|
<span
|
|
980
979
|
className={cn(
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '@tanstack/react-table';
|
|
12
12
|
import { ChevronLeft, ChevronRight, SearchX, X, Search, Users } from 'lucide-react';
|
|
13
13
|
import { UserIcon } from '@heroicons/react/24/outline';
|
|
14
|
-
import { useMemo, useState } from 'react';
|
|
14
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
15
15
|
import type { TableConfiguration } from '@types';
|
|
16
16
|
import { isSameVersion } from '@utils/collections/version-compare';
|
|
17
17
|
import { FilterDropdown, CheckboxItem } from './FilterComponents';
|
|
@@ -110,6 +110,18 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
110
110
|
);
|
|
111
111
|
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
112
112
|
const [tableFilter, setTableFilter] = useState('');
|
|
113
|
+
const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
|
|
114
|
+
const PAGE_SIZE_STORAGE_KEY = 'eventcatalog-discover-page-size';
|
|
115
|
+
const [pageSize, setPageSize] = useState<number>(() => {
|
|
116
|
+
if (typeof window === 'undefined') return 10;
|
|
117
|
+
const stored = Number(window.localStorage.getItem(PAGE_SIZE_STORAGE_KEY));
|
|
118
|
+
return PAGE_SIZE_OPTIONS.includes(stored) ? stored : 10;
|
|
119
|
+
});
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (typeof window !== 'undefined') {
|
|
122
|
+
window.localStorage.setItem(PAGE_SIZE_STORAGE_KEY, String(pageSize));
|
|
123
|
+
}
|
|
124
|
+
}, [pageSize]);
|
|
113
125
|
const [showOnlyLatest, setShowOnlyLatest] = useState(true);
|
|
114
126
|
const [onlyShowDrafts, setOnlyShowDrafts] = useState(false);
|
|
115
127
|
const [selectedDomains, setSelectedDomains] = useState<string[]>([]);
|
|
@@ -304,8 +316,15 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
304
316
|
columnFilters,
|
|
305
317
|
columnVisibility,
|
|
306
318
|
},
|
|
319
|
+
initialState: {
|
|
320
|
+
pagination: { pageIndex: 0, pageSize },
|
|
321
|
+
},
|
|
307
322
|
});
|
|
308
323
|
|
|
324
|
+
useEffect(() => {
|
|
325
|
+
table.setPageSize(pageSize);
|
|
326
|
+
}, [pageSize, table]);
|
|
327
|
+
|
|
309
328
|
const totalResults = table.getPrePaginationRowModel().rows.length;
|
|
310
329
|
const hasResults = table.getRowModel().rows.length > 0;
|
|
311
330
|
|
|
@@ -433,11 +452,13 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
433
452
|
<div className="flex h-full min-h-0" style={{ ['--ec-discover-sidebar-width' as any]: '320px' }}>
|
|
434
453
|
{/* Filter Sidebar */}
|
|
435
454
|
<div
|
|
436
|
-
className="fixed left-[var(--ec-vertical-nav-width)] top-0 z-20 flex h-screen w-[320px] flex-shrink-0 flex-col border-r border-[rgb(var(--ec-content-border))] bg-[rgb(var(--ec-
|
|
455
|
+
className="fixed left-[var(--ec-vertical-nav-width)] top-0 z-20 flex h-screen w-[320px] flex-shrink-0 flex-col border-r border-[rgb(var(--ec-content-border))] bg-[rgb(var(--ec-rail-bg))]"
|
|
437
456
|
style={{ width: 'var(--ec-discover-sidebar-width, 320px)' }}
|
|
438
457
|
>
|
|
439
458
|
<div className="flex h-[60px] flex-shrink-0 items-center border-b border-[rgb(var(--ec-page-border))] px-4">
|
|
440
|
-
<h2 className="text-[
|
|
459
|
+
<h2 className="text-[0.65rem] font-semibold uppercase tracking-[0.18em] text-[rgb(var(--ec-sidebar-text)/0.5)]">
|
|
460
|
+
{collectionLabel} Filters
|
|
461
|
+
</h2>
|
|
441
462
|
</div>
|
|
442
463
|
|
|
443
464
|
{/* Filter sections */}
|
|
@@ -445,10 +466,6 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
445
466
|
{/* Message Filters Section */}
|
|
446
467
|
{(showProducersFilter || showConsumersFilter) && (filteredProducers.length > 0 || filteredConsumers.length > 0) && (
|
|
447
468
|
<div className="space-y-3">
|
|
448
|
-
<h3 className="text-[11px] font-bold uppercase tracking-widest text-[rgb(var(--ec-page-text))] pb-2">
|
|
449
|
-
Message Filters
|
|
450
|
-
</h3>
|
|
451
|
-
|
|
452
469
|
{/* Producers Filter */}
|
|
453
470
|
{showProducersFilter && filteredProducers.length > 0 && (
|
|
454
471
|
<div>
|
|
@@ -679,10 +696,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
679
696
|
{/* Table Header */}
|
|
680
697
|
<div className="flex items-end justify-between gap-6 px-6 py-5">
|
|
681
698
|
<div className="min-w-0">
|
|
682
|
-
<h2 className="text-2xl font-semibold text-[rgb(var(--ec-page-text))] md:text-4xl">
|
|
683
|
-
{collectionLabel}{' '}
|
|
684
|
-
<span className="ml-1 text-lg font-normal text-[rgb(var(--ec-page-text-muted))] md:text-3xl">({totalResults})</span>
|
|
685
|
-
</h2>
|
|
699
|
+
<h2 className="text-2xl font-semibold text-[rgb(var(--ec-page-text))] md:text-4xl">{collectionLabel}</h2>
|
|
686
700
|
{collectionDescription && (
|
|
687
701
|
<p className="max-w-3xl pt-2 text-base font-light text-[rgb(var(--ec-page-text-muted))]">{collectionDescription}</p>
|
|
688
702
|
)}
|
|
@@ -694,7 +708,7 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
694
708
|
value={tableFilter}
|
|
695
709
|
onChange={(e) => setTableFilter(e.target.value)}
|
|
696
710
|
placeholder="Filter..."
|
|
697
|
-
className="w-64 rounded-
|
|
711
|
+
className="w-64 rounded-md border-0 bg-[rgb(var(--ec-page-bg))] py-1.5 pl-9 pr-3 text-sm font-light text-[rgb(var(--ec-header-text))] shadow-xs ring-1 ring-inset ring-[rgb(var(--ec-dropdown-border))] placeholder:text-[rgb(var(--ec-icon-color))] focus:outline-hidden focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
|
|
698
712
|
/>
|
|
699
713
|
{tableFilter && (
|
|
700
714
|
<button
|
|
@@ -766,14 +780,29 @@ export function DiscoverTable<T extends DiscoverTableData>({
|
|
|
766
780
|
|
|
767
781
|
{/* Pagination */}
|
|
768
782
|
<div className="flex-shrink-0 flex items-center justify-between px-6 py-3 border-t border-[rgb(var(--ec-page-border))]">
|
|
769
|
-
<
|
|
783
|
+
<div className="flex items-center gap-3 text-xs text-[rgb(var(--ec-page-text-muted))]">
|
|
770
784
|
{totalResults > 0 && (
|
|
771
|
-
|
|
785
|
+
<span>
|
|
772
786
|
<span className="font-medium text-[rgb(var(--ec-page-text))]">{table.getRowModel().rows.length}</span> of{' '}
|
|
773
787
|
<span className="font-medium text-[rgb(var(--ec-page-text))]">{totalResults}</span> results
|
|
774
|
-
|
|
788
|
+
</span>
|
|
775
789
|
)}
|
|
776
|
-
|
|
790
|
+
{totalResults > 0 && <span aria-hidden className="h-3 w-px bg-[rgb(var(--ec-page-border))]" />}
|
|
791
|
+
<label className="flex items-center gap-1.5">
|
|
792
|
+
<span>Per page</span>
|
|
793
|
+
<select
|
|
794
|
+
value={pageSize}
|
|
795
|
+
onChange={(e) => setPageSize(Number(e.target.value))}
|
|
796
|
+
className="cursor-pointer rounded bg-transparent px-1 py-0.5 font-medium text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))] focus:bg-[rgb(var(--ec-content-hover))] focus:outline-none"
|
|
797
|
+
>
|
|
798
|
+
{PAGE_SIZE_OPTIONS.map((size) => (
|
|
799
|
+
<option key={size} value={size}>
|
|
800
|
+
{size}
|
|
801
|
+
</option>
|
|
802
|
+
))}
|
|
803
|
+
</select>
|
|
804
|
+
</label>
|
|
805
|
+
</div>
|
|
777
806
|
<div className="flex items-center gap-1.5">
|
|
778
807
|
<button
|
|
779
808
|
className="p-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
|
|
@@ -45,7 +45,7 @@ export const FilterDropdown = ({ label, selectedItems, onClear, onRemoveItem, ch
|
|
|
45
45
|
setIsOpen(!isOpen);
|
|
46
46
|
}
|
|
47
47
|
}}
|
|
48
|
-
className={`w-full flex items-center justify-between px-3 py-2 text-
|
|
48
|
+
className={`w-full flex items-center justify-between px-3 py-2 text-xs rounded-lg border transition-colors cursor-pointer ${
|
|
49
49
|
hasSelection || isOpen
|
|
50
50
|
? 'border-[rgb(var(--ec-accent))] bg-[rgb(var(--ec-accent)/0.05)]'
|
|
51
51
|
: 'border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg))] hover:border-[rgb(var(--ec-icon-color))]'
|
|
@@ -152,7 +152,7 @@ export const CheckboxItem = ({ label, checked, onChange, count, icon }: Checkbox
|
|
|
152
152
|
</div>
|
|
153
153
|
{icon && <span className="flex-shrink-0 text-[rgb(var(--ec-icon-color))]">{icon}</span>}
|
|
154
154
|
<span
|
|
155
|
-
className={`text-
|
|
155
|
+
className={`text-xs flex-1 truncate ${checked ? 'font-medium text-[rgb(var(--ec-page-text))]' : 'text-[rgb(var(--ec-page-text))]'}`}
|
|
156
156
|
>
|
|
157
157
|
{label}
|
|
158
158
|
</span>
|
|
@@ -32,7 +32,7 @@ export const projectDirBase = (() => {
|
|
|
32
32
|
|
|
33
33
|
const withIgnoredBuildArtifacts = (patterns: string | string[]) => {
|
|
34
34
|
if (process.env.IGNORE_BUILD_ARTIFACTS === 'true') {
|
|
35
|
-
return [...patterns, '!dist/**'];
|
|
35
|
+
return Array.isArray(patterns) ? [...patterns, '!dist/**'] : [patterns, '!dist/**'];
|
|
36
36
|
}
|
|
37
37
|
return patterns;
|
|
38
38
|
};
|
|
@@ -80,6 +80,16 @@ export function findMatchingRule(rules: Record<string, () => boolean>, pathname:
|
|
|
80
80
|
return matches.length > 0 ? matches[0].rule : null;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export function getPublicRoutes(isLLMSTextEnabled: boolean) {
|
|
84
|
+
const publicRoutes = ['/auth/login', '/auth/signout', '/auth/error', '/api/auth'];
|
|
85
|
+
|
|
86
|
+
if (!isLLMSTextEnabled) {
|
|
87
|
+
return publicRoutes;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return [...publicRoutes, '/docs/llm/llms.txt', '/docs/llm/llms-full.txt', '/docs/llm/schemas.txt'];
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
export const authMiddleware: MiddlewareHandler = async (context, next) => {
|
|
84
94
|
const { request, redirect, locals } = context;
|
|
85
95
|
const url = new URL(request.url);
|
|
@@ -97,13 +107,7 @@ export const authMiddleware: MiddlewareHandler = async (context, next) => {
|
|
|
97
107
|
|
|
98
108
|
// Skip system/browser requests
|
|
99
109
|
const systemRoutes = ['/.well-known/', '/favicon.ico', '/robots.txt', '/sitemap.xml', '/_astro/', '/__astro'];
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const llmsRoutes = ['/docs/llm/llms.txt', '/docs/llm/llms-services.txt', '/docs/llm/llms-full.txt'];
|
|
103
|
-
|
|
104
|
-
if (isLLMSTextEnabled) {
|
|
105
|
-
publicRoutes = [...publicRoutes, ...llmsRoutes];
|
|
106
|
-
}
|
|
110
|
+
const publicRoutes = getPublicRoutes(isLLMSTextEnabled);
|
|
107
111
|
|
|
108
112
|
if (
|
|
109
113
|
pathname.startsWith('/_') ||
|
|
@@ -204,14 +204,14 @@ const CustomDocsNav: React.FC<CustomDocsNavProps> = ({ sidebarItems }) => {
|
|
|
204
204
|
|
|
205
205
|
return (
|
|
206
206
|
<nav ref={navRef} className="flex h-full min-h-0 flex-col text-[rgb(var(--ec-page-text))]">
|
|
207
|
-
<div className="flex-shrink-0 border-b border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-
|
|
208
|
-
<div className="flex gap-2">
|
|
207
|
+
<div className="flex h-[60px] flex-shrink-0 items-center border-b border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-rail-bg))] px-3">
|
|
208
|
+
<div className="flex w-full gap-2">
|
|
209
209
|
<input
|
|
210
210
|
type="text"
|
|
211
211
|
value={searchTerm}
|
|
212
212
|
onChange={handleSearchChange}
|
|
213
213
|
placeholder="Quick search..."
|
|
214
|
-
className="flex-1 p-2 px-2 text-sm rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-
|
|
214
|
+
className="flex-1 min-w-0 p-2 px-2 text-sm rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-icon-color))] h-[30px] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))] focus:border-[rgb(var(--ec-accent))]"
|
|
215
215
|
/>
|
|
216
216
|
<button
|
|
217
217
|
onClick={toggleExpandCollapse}
|
|
@@ -228,7 +228,7 @@ const CustomDocsNav: React.FC<CustomDocsNavProps> = ({ sidebarItems }) => {
|
|
|
228
228
|
</div>
|
|
229
229
|
|
|
230
230
|
<div className="min-h-0 flex-1 overflow-y-auto">
|
|
231
|
-
<div className="space-y-2
|
|
231
|
+
<div className="space-y-2 pb-4 pt-2">
|
|
232
232
|
{hasNoResults ? (
|
|
233
233
|
<NoResultsFound searchTerm={debouncedSearchTerm} />
|
|
234
234
|
) : (
|