@eventcatalog/core 4.10.12 → 4.10.14
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-7URQ754Q.js → chunk-HERAHLM2.js} +1 -1
- package/dist/{chunk-Y5XU3YLT.js → chunk-LITOQH56.js} +1 -1
- package/dist/{chunk-S4LLGOO4.js → chunk-LUW6RDA7.js} +1 -1
- package/dist/{chunk-VFSEVDCQ.js → chunk-ONDFEA5R.js} +1 -1
- package/dist/{chunk-A53VCEEA.js → chunk-V2SKOQYF.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +55 -1
- package/dist/docs/development/authentication/providers/03-setting-up-github.md +29 -0
- package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +2 -2
- package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +17 -0
- package/dist/docs/development/components/07-resource-references.md +7 -1
- package/dist/docs/development/components/components/05-architecture-graph.md +65 -0
- package/dist/docs/development/components/components/{05-attachments.md → 06-attachments.md} +1 -1
- package/dist/docs/development/components/components/{06-channel-information.md → 07-channel-information.md} +1 -1
- package/dist/docs/development/components/components/{07-custom-properties.md → 08-custom-properties.md} +1 -1
- package/dist/docs/development/components/components/{08-design.md → 09-design.md} +1 -1
- package/dist/docs/development/components/components/{09-entitymap.md → 10-entitymap.md} +1 -1
- package/dist/docs/development/components/components/{10-flow.md → 11-flow.md} +1 -1
- package/dist/docs/development/components/components/{11-link.md → 12-link.md} +1 -1
- package/dist/docs/development/components/components/{12-mermaid-file-loader.md → 13-mermaid-file-loader.md} +1 -1
- package/dist/docs/development/components/components/{13-message-table.md → 14-message-table.md} +1 -1
- package/dist/docs/development/components/components/{14-nodegraph.md → 15-nodegraph.md} +1 -1
- package/dist/docs/development/components/components/{15-openapi.md → 16-openapi.md} +1 -1
- package/dist/docs/development/components/components/{16-prompt.md → 17-prompt.md} +1 -1
- package/dist/docs/development/components/components/{17-remote-schema.md → 18-remote-schema.md} +1 -1
- package/dist/docs/development/components/components/{18-resource-group-table.md → 19-resource-group-table.md} +1 -1
- package/dist/docs/development/components/components/{19-resource-link.md → 20-resource-link.md} +1 -1
- package/dist/docs/development/components/components/{20-schema.md → 21-schema.md} +1 -1
- package/dist/docs/development/components/components/{21-schema-viewer.md → 22-schema-viewer.md} +1 -1
- package/dist/docs/development/components/components/{22-steps.md → 23-steps.md} +1 -1
- package/dist/docs/development/components/components/{23-tabs.md → 24-tabs.md} +1 -1
- package/dist/docs/development/components/components/{24-tiles.md → 25-tiles.md} +1 -1
- package/dist/docs/development/components/components/{25-visibility.md → 26-visibility.md} +1 -1
- package/dist/docs/development/customization/04-documentation-sidebar.md +3 -3
- package/dist/docs/development/customization/05-resource-sidebar.md +235 -0
- package/dist/docs/development/customization/09-embed-eventcatalog.md +179 -0
- package/dist/docs/development/customization/_category_.json +1 -1
- package/dist/docs/development/deployment/build-and-deploy.md +4 -0
- package/dist/docs/development/deployment/hosting-options.md +1 -1
- package/dist/docs/development/deployment/link-validation.md +105 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/00-overview.md +76 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/01-setup.md +144 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/_category_.json +10 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/01-configure-rules.md +130 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/02-run-in-ci.md +93 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/03-use-custom-frontmatter.md +81 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/04-reference-external-catalogs.md +51 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +120 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/_category_.json +12 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/01-cli.md +109 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/02-configuration.md +120 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +287 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/04-versions.md +77 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +75 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/_category_.json +12 -0
- package/dist/docs/development/guides/97-architecture-graph.md +78 -0
- package/dist/docs/development/guides/domains/02-create-domain.md +1 -1
- package/dist/docs/development/guides/domains/03-ownership-and-language/02-adding-ubiquitous-language.md +29 -0
- package/dist/docs/development/guides/domains/09-reference.md +10 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/02-adding-channels.md +2 -2
- package/dist/docs/development/guides/resources/messages/04-message-channels/04-adding-messages-to-services.md +8 -0
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/01-add-openapi-specifications.md +2 -2
- package/dist/docs/development/guides/resources/schemas/03-add-specifications-to-services/02-add-asyncapi-specifications.md +3 -3
- package/dist/docs/development/guides/systems/05-system-context-maps.md +2 -0
- package/dist/docs/development/license-keys/license-validation.md +7 -3
- package/dist/docs/development/license-keys/overview.md +7 -3
- package/dist/docs/development/upgrading/upgrading.md +3 -3
- package/dist/docs/development/upgrading/v2.md +3 -3
- package/dist/docs/federation/00-overview.md +158 -0
- package/dist/docs/federation/01-first-federation.md +199 -0
- package/dist/docs/federation/_category_.json +12 -0
- package/dist/docs/federation/explanation/_category_.json +12 -0
- package/dist/docs/federation/explanation/how-it-works.md +129 -0
- package/dist/docs/federation/explanation/lockfile-and-cache.md +134 -0
- package/dist/docs/federation/explanation/mvp-status-and-feedback.md +86 -0
- package/dist/docs/federation/explanation/ownership-and-references.md +134 -0
- package/dist/docs/federation/how-to/_category_.json +12 -0
- package/dist/docs/federation/how-to/configure-github-sources.md +156 -0
- package/dist/docs/federation/how-to/configure-validation-rules.md +127 -0
- package/dist/docs/federation/how-to/run-in-ci.md +138 -0
- package/dist/docs/federation/how-to/share-assets-and-components.md +125 -0
- package/dist/docs/federation/how-to/use-local-sources.md +138 -0
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/00-introduction.md +11 -2
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/01-installation.md +11 -3
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/02-plugin-configuration.md +11 -2
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/03-examples.md +11 -1
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/04-configuration.md +11 -1
- package/dist/docs/{plugins/eventcatalog-federation → federation/legacy-federation}/05-setup-team-catalog.md +11 -2
- package/dist/docs/federation/legacy-federation/_category_.json +12 -0
- package/dist/docs/federation/reference/_category_.json +12 -0
- package/dist/docs/federation/reference/cli.md +122 -0
- package/dist/docs/federation/reference/configuration.md +192 -0
- package/dist/docs/federation/reference/diagnostic-rules.md +173 -0
- package/dist/docs/federation/reference/generated-output.md +118 -0
- package/dist/docs/federation/reference/supported-content.md +86 -0
- package/dist/docs/federation/reference/troubleshooting.md +208 -0
- package/dist/docs/plugins/01-intro.md +3 -3
- package/dist/docs/plugins/03-all-plugins.md +2 -2
- package/dist/docs/plugins/asyncapi/00-intro.md +4 -4
- package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +4 -4
- package/dist/docs/plugins/backstage/00-overview.md +53 -0
- package/dist/docs/plugins/backstage/01-get-started.md +95 -0
- package/dist/docs/plugins/backstage/02-embed-entity-tabs.md +109 -0
- package/dist/docs/plugins/backstage/03-add-overview-cards.md +79 -0
- package/dist/docs/plugins/backstage/04-control-theme-and-size.md +54 -0
- package/dist/docs/plugins/backstage/05-migrate-to-annotations.md +49 -0
- package/dist/docs/plugins/backstage/06-configuration.md +85 -0
- package/dist/docs/plugins/backstage/07-components.md +129 -0
- package/dist/docs/plugins/backstage/08-how-embeds-work.md +52 -0
- package/dist/docs/plugins/backstage/_category_.json +4 -3
- package/dist/docs/plugins/eventbridge/00-intro.md +5 -5
- package/dist/docs/plugins/eventbridge/03-api.md +3 -3
- package/dist/docs/plugins/graphql/00-intro.md +2 -2
- package/dist/docs/plugins/graphql/02-plugin-configuration.md +2 -2
- package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
- package/dist/docs/plugins/openapi/00-intro.md +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/src/components/ChatPanel/ChatPanel.tsx +208 -119
- package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +28 -8
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +45 -0
- package/eventcatalog/src/components/Header.astro +11 -6
- package/eventcatalog/src/components/MDX/Design/Design.astro +2 -2
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -2
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -2
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +2 -2
- package/eventcatalog/src/components/SchemaExplorer/AvroSchemaViewer.tsx +21 -19
- package/eventcatalog/src/components/SchemaExplorer/JSONSchemaViewer.tsx +79 -77
- package/eventcatalog/src/components/SchemaExplorer/ProtobufSchemaViewer.test.tsx +91 -0
- package/eventcatalog/src/components/SchemaExplorer/ProtobufSchemaViewer.tsx +115 -33
- package/eventcatalog/src/components/SchemaExplorer/SchemaViewerHover.test.tsx +33 -0
- package/eventcatalog/src/components/SchemaExplorer/protobuf-validation.test.ts +84 -0
- package/eventcatalog/src/components/SchemaExplorer/protobuf-validation.ts +149 -0
- package/eventcatalog/src/components/Search/Search.astro +11 -4
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +29 -24
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +3 -3
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +5 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +10 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +2 -2
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +3 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +2 -2
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -2
- package/eventcatalog/src/utils/feature.ts +1 -0
- package/eventcatalog/src/utils/protobuf-schema.ts +211 -16
- package/package.json +3 -3
- package/dist/docs/cli/channels.md +0 -180
- package/dist/docs/cli/commands.md +0 -183
- package/dist/docs/cli/custom-docs.md +0 -78
- package/dist/docs/cli/data-products.md +0 -177
- package/dist/docs/cli/data-stores.md +0 -166
- package/dist/docs/cli/diagrams.md +0 -147
- package/dist/docs/cli/domains.md +0 -280
- package/dist/docs/cli/entities.md +0 -138
- package/dist/docs/cli/events.md +0 -186
- package/dist/docs/cli/export.md +0 -27
- package/dist/docs/cli/governance.md +0 -24
- package/dist/docs/cli/messages.md +0 -69
- package/dist/docs/cli/queries.md +0 -183
- package/dist/docs/cli/services.md +0 -266
- package/dist/docs/cli/snapshots.md +0 -44
- package/dist/docs/cli/teams.md +0 -75
- package/dist/docs/cli/users.md +0 -75
- package/dist/docs/cli/utilities.md +0 -43
- package/dist/docs/development/developer-tools/eventcatalog-linter.md +0 -732
- package/dist/docs/plugins/backstage/00-intro.md +0 -67
- package/dist/docs/plugins/backstage/01-installation.md +0 -242
- package/dist/docs/plugins/backstage/02-api.md +0 -51
- package/dist/docs/plugins/backstage/03-examples.md +0 -12
- package/dist/docs/plugins/eventcatalog-federation/_category_.json +0 -11
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
2
2
|
import type { ProtobufSchema, ProtobufMessage, ProtobufEnum, ProtobufField } from '@utils/protobuf-schema';
|
|
3
|
+
import {
|
|
4
|
+
formatProtobufOptionValue,
|
|
5
|
+
formatProtovalidateRule,
|
|
6
|
+
getCustomFieldAnnotations,
|
|
7
|
+
getProtovalidateRules,
|
|
8
|
+
isProtovalidateRequired,
|
|
9
|
+
} from './protobuf-validation';
|
|
3
10
|
|
|
4
11
|
interface ProtobufSchemaViewerProps {
|
|
5
12
|
schema: ProtobufSchema;
|
|
@@ -63,9 +70,21 @@ function lookupType<T>(map: Map<string, T>, typeName: string, packageName?: stri
|
|
|
63
70
|
return undefined;
|
|
64
71
|
}
|
|
65
72
|
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
return
|
|
73
|
+
function compactTypeName(typeName: string): string {
|
|
74
|
+
const normalized = typeName.startsWith('.') ? typeName.slice(1) : typeName;
|
|
75
|
+
return normalized.split('.').pop() ?? normalized;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function formatProtobufType(field: ProtobufField, compact = false): string {
|
|
79
|
+
const type = field.map
|
|
80
|
+
? compact
|
|
81
|
+
? `map<${field.map.keyType}, ${compactTypeName(field.map.valueType)}>`
|
|
82
|
+
: field.type
|
|
83
|
+
: compact
|
|
84
|
+
? compactTypeName(field.type)
|
|
85
|
+
: field.type;
|
|
86
|
+
|
|
87
|
+
return field.label ? `${field.label} ${type}` : type;
|
|
69
88
|
}
|
|
70
89
|
|
|
71
90
|
function countFields(messages: ProtobufMessage[]): number {
|
|
@@ -92,7 +111,27 @@ const ProtobufFieldRow = ({ field, level, expand, showRequired, registry, packag
|
|
|
92
111
|
const nestedEnum = nestedMessage ? undefined : lookupType(registry.enums, targetTypeName, packageName);
|
|
93
112
|
const isCyclic = nestedMessage ? ancestors.includes(nestedMessage.name) : false;
|
|
94
113
|
const hasNested = !!nestedMessage && nestedMessage.fields.length > 0 && !isCyclic;
|
|
95
|
-
const
|
|
114
|
+
const hasRequiredAnnotation = isProtovalidateRequired(field);
|
|
115
|
+
const isRequired = hasRequiredAnnotation || field.label === 'required';
|
|
116
|
+
const validationRules = getProtovalidateRules(field).filter((rule) => rule.path !== 'required');
|
|
117
|
+
const customAnnotations = getCustomFieldAnnotations(field);
|
|
118
|
+
const fullType = formatProtobufType(field);
|
|
119
|
+
const displayType = formatProtobufType(field, true);
|
|
120
|
+
const enumRuleScope = field.map ? 'map.values.enum' : field.label === 'repeated' ? 'repeated.items.enum' : 'enum';
|
|
121
|
+
const enumConstant = validationRules.find((rule) => rule.path === `${enumRuleScope}.const`);
|
|
122
|
+
const enumIncludes = validationRules.find((rule) => rule.path === `${enumRuleScope}.in`);
|
|
123
|
+
const enumExcludes = validationRules.find((rule) => rule.path === `${enumRuleScope}.not_in`);
|
|
124
|
+
const normalizeRuleValues = (value: unknown) => (Array.isArray(value) ? value : value === undefined ? [] : [value]);
|
|
125
|
+
const includedEnumValues = normalizeRuleValues(enumIncludes?.value);
|
|
126
|
+
const excludedEnumValues = normalizeRuleValues(enumExcludes?.value);
|
|
127
|
+
const displayedEnumValues = nestedEnum?.values.filter((value) => {
|
|
128
|
+
const matches = (candidate: unknown) => String(candidate) === String(value.value) || candidate === value.name;
|
|
129
|
+
return (
|
|
130
|
+
(!enumConstant || matches(enumConstant.value)) &&
|
|
131
|
+
(includedEnumValues.length === 0 || includedEnumValues.some(matches)) &&
|
|
132
|
+
!excludedEnumValues.some(matches)
|
|
133
|
+
);
|
|
134
|
+
});
|
|
96
135
|
|
|
97
136
|
useEffect(() => {
|
|
98
137
|
setIsExpanded(expand);
|
|
@@ -116,40 +155,83 @@ const ProtobufFieldRow = ({ field, level, expand, showRequired, registry, packag
|
|
|
116
155
|
)}
|
|
117
156
|
|
|
118
157
|
<div className="flex-grow">
|
|
119
|
-
<div className="
|
|
120
|
-
<div>
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
oneof {field.oneof}
|
|
158
|
+
<div className="-mx-1 rounded px-1 transition-colors hover:bg-[rgb(var(--ec-content-hover))]">
|
|
159
|
+
<div className="flex justify-between items-baseline">
|
|
160
|
+
<div>
|
|
161
|
+
<span className="proto-field-name font-semibold text-[rgb(var(--ec-page-text))] text-sm">{field.name}</span>
|
|
162
|
+
<span
|
|
163
|
+
className="ml-1.5 text-[rgb(var(--ec-accent))] font-mono text-xs"
|
|
164
|
+
title={displayType === fullType ? undefined : fullType}
|
|
165
|
+
>
|
|
166
|
+
{displayType}
|
|
129
167
|
</span>
|
|
168
|
+
{field.number !== undefined && (
|
|
169
|
+
<span className="ml-1.5 text-[rgb(var(--ec-page-text-muted))] font-mono text-xs">= {field.number}</span>
|
|
170
|
+
)}
|
|
171
|
+
{field.oneof && (
|
|
172
|
+
<span className="ml-1.5 text-[rgb(var(--ec-page-text-muted))] text-xs bg-[rgb(var(--ec-content-hover))] px-1 rounded">
|
|
173
|
+
oneof {field.oneof}
|
|
174
|
+
</span>
|
|
175
|
+
)}
|
|
176
|
+
</div>
|
|
177
|
+
{(hasRequiredAnnotation || (showRequired && isRequired)) && (
|
|
178
|
+
<span className="text-red-600 dark:text-red-400 text-xs ml-3 flex-shrink-0">required</span>
|
|
130
179
|
)}
|
|
131
180
|
</div>
|
|
132
|
-
|
|
133
|
-
|
|
181
|
+
|
|
182
|
+
{field.doc && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5">{field.doc}</p>}
|
|
183
|
+
|
|
184
|
+
{validationRules.length > 0 && (
|
|
185
|
+
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-0.5 space-y-0">
|
|
186
|
+
{validationRules.map((rule, index) => {
|
|
187
|
+
const display = formatProtovalidateRule(rule);
|
|
188
|
+
return (
|
|
189
|
+
<div key={`${rule.path}-${index}`}>
|
|
190
|
+
{display.label}
|
|
191
|
+
{display.value !== undefined && (
|
|
192
|
+
<>
|
|
193
|
+
:{' '}
|
|
194
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
195
|
+
{display.value}
|
|
196
|
+
</code>
|
|
197
|
+
</>
|
|
198
|
+
)}
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
})}
|
|
202
|
+
</div>
|
|
134
203
|
)}
|
|
135
|
-
</div>
|
|
136
204
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
205
|
+
{customAnnotations.length > 0 && (
|
|
206
|
+
<div className="mt-0.5 space-y-0 text-xs text-gray-400 dark:text-gray-500">
|
|
207
|
+
{customAnnotations.map((annotation, index) => (
|
|
208
|
+
<div key={`${annotation.name}-${index}`} className="flex max-w-full flex-wrap items-baseline gap-x-1">
|
|
209
|
+
<span>Annotation:</span>
|
|
210
|
+
<code className="break-all font-mono text-gray-500 dark:text-gray-400">{annotation.name}</code>
|
|
211
|
+
<span>=</span>
|
|
212
|
+
<code className="font-medium text-gray-500 dark:text-gray-400">
|
|
213
|
+
{formatProtobufOptionValue(annotation.value)}
|
|
214
|
+
</code>
|
|
215
|
+
</div>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
|
|
220
|
+
{/* Show enum values if the field type resolves to an enum */}
|
|
221
|
+
{nestedEnum && displayedEnumValues && displayedEnumValues.length > 0 && (
|
|
222
|
+
<div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-0.5">
|
|
223
|
+
<span className="text-xs inline-block">Allowed values:</span>
|
|
224
|
+
{displayedEnumValues.map((value) => (
|
|
225
|
+
<span key={value.name} className="text-xs">
|
|
226
|
+
{' '}
|
|
227
|
+
<code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
|
|
228
|
+
{value.name}
|
|
229
|
+
</code>
|
|
230
|
+
</span>
|
|
231
|
+
))}
|
|
232
|
+
</div>
|
|
233
|
+
)}
|
|
234
|
+
</div>
|
|
153
235
|
|
|
154
236
|
{/* Nested fields for message types */}
|
|
155
237
|
{hasNested && nestedMessage && (
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { parseProtobufSchema } from '@utils/protobuf-schema';
|
|
4
|
+
import AvroSchemaViewer from './AvroSchemaViewer';
|
|
5
|
+
import JSONSchemaViewer from './JSONSchemaViewer';
|
|
6
|
+
import ProtobufSchemaViewer from './ProtobufSchemaViewer';
|
|
7
|
+
|
|
8
|
+
const PROPERTY_HOVER_CLASS = 'hover:bg-[rgb(var(--ec-content-hover))]';
|
|
9
|
+
|
|
10
|
+
describe('schema viewer property hover states', () => {
|
|
11
|
+
it('adds a hover background to JSON Schema properties', () => {
|
|
12
|
+
const html = renderToStaticMarkup(
|
|
13
|
+
<JSONSchemaViewer schema={{ type: 'object', properties: { id: { type: 'string' } } }} search={false} />
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(html).toContain(PROPERTY_HOVER_CLASS);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('adds a hover background to Avro fields', () => {
|
|
20
|
+
const html = renderToStaticMarkup(
|
|
21
|
+
<AvroSchemaViewer schema={{ type: 'record', name: 'Example', fields: [{ name: 'id', type: 'string' }] }} search={false} />
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
expect(html).toContain(PROPERTY_HOVER_CLASS);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('adds a hover background to Protobuf fields', () => {
|
|
28
|
+
const schema = parseProtobufSchema('syntax = "proto3"; message Example { string id = 1; }');
|
|
29
|
+
const html = renderToStaticMarkup(<ProtobufSchemaViewer schema={schema} search={false} />);
|
|
30
|
+
|
|
31
|
+
expect(html).toContain(PROPERTY_HOVER_CLASS);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import type { ProtobufField } from '@utils/protobuf-schema';
|
|
3
|
+
import {
|
|
4
|
+
formatProtobufOptionValue,
|
|
5
|
+
formatProtovalidateRule,
|
|
6
|
+
getCustomFieldAnnotations,
|
|
7
|
+
getProtovalidateRules,
|
|
8
|
+
isProtovalidateRequired,
|
|
9
|
+
} from './protobuf-validation';
|
|
10
|
+
|
|
11
|
+
describe('protobuf validation helpers', () => {
|
|
12
|
+
it('flattens direct and aggregate Protovalidate options', () => {
|
|
13
|
+
const field: ProtobufField = {
|
|
14
|
+
name: 'status',
|
|
15
|
+
type: 'Status',
|
|
16
|
+
options: [
|
|
17
|
+
{ name: '(buf.validate.field).required', value: true },
|
|
18
|
+
{
|
|
19
|
+
name: '(buf.validate.field).enum',
|
|
20
|
+
value: { defined_only: true, not_in: [0] },
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
expect(getProtovalidateRules(field)).toEqual([
|
|
26
|
+
{ path: 'required', value: true },
|
|
27
|
+
{ path: 'enum.defined_only', value: true },
|
|
28
|
+
{ path: 'enum.not_in', value: [0] },
|
|
29
|
+
]);
|
|
30
|
+
expect(isProtovalidateRequired(field)).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('ignores non-Protovalidate custom options', () => {
|
|
34
|
+
const field: ProtobufField = {
|
|
35
|
+
name: 'description',
|
|
36
|
+
type: 'string',
|
|
37
|
+
options: [{ name: '(datahub.v1.gdpr_rule).string', value: true }],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
expect(getProtovalidateRules(field)).toEqual([]);
|
|
41
|
+
expect(isProtovalidateRequired(field)).toBe(false);
|
|
42
|
+
expect(getCustomFieldAnnotations(field)).toEqual([{ name: '(datahub.v1.gdpr_rule).string', value: true }]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('only treats extension options as custom annotations and formats aggregate values', () => {
|
|
46
|
+
const field: ProtobufField = {
|
|
47
|
+
name: 'description',
|
|
48
|
+
type: 'string',
|
|
49
|
+
options: [
|
|
50
|
+
{ name: 'deprecated', value: true },
|
|
51
|
+
{ name: '(buf.validate.field).string.min_len', value: 1 },
|
|
52
|
+
{ name: '(datahub.v1.classification)', value: { level: 'personal', encrypted: true } },
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
expect(getCustomFieldAnnotations(field)).toEqual([
|
|
57
|
+
{
|
|
58
|
+
name: '(datahub.v1.classification)',
|
|
59
|
+
value: { level: 'personal', encrypted: true },
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
expect(formatProtobufOptionValue(getCustomFieldAnnotations(field)[0].value)).toBe('{"level":"personal","encrypted":true}');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('formats common rules for display', () => {
|
|
66
|
+
expect(formatProtovalidateRule({ path: 'string.email', value: true })).toEqual({ label: 'Format', value: 'Email' });
|
|
67
|
+
expect(formatProtovalidateRule({ path: 'uint32.gte', value: 1 })).toEqual({ label: 'Minimum', value: '1' });
|
|
68
|
+
expect(formatProtovalidateRule({ path: 'enum.defined_only', value: true })).toEqual({
|
|
69
|
+
label: 'Defined enum values only',
|
|
70
|
+
});
|
|
71
|
+
expect(formatProtovalidateRule({ path: 'enum.not_in', value: [0] })).toEqual({
|
|
72
|
+
label: 'Excluded values',
|
|
73
|
+
value: '0',
|
|
74
|
+
});
|
|
75
|
+
expect(formatProtovalidateRule({ path: 'repeated.items.string.min_len', value: 3 })).toEqual({
|
|
76
|
+
label: 'Item minimum length',
|
|
77
|
+
value: '3',
|
|
78
|
+
});
|
|
79
|
+
expect(formatProtovalidateRule({ path: 'map.values.string.max_len', value: 100 })).toEqual({
|
|
80
|
+
label: 'Value maximum length',
|
|
81
|
+
value: '100',
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { ProtobufField, ProtobufOptionValue } from '@utils/protobuf-schema';
|
|
2
|
+
|
|
3
|
+
const PROTOVALIDATE_FIELD_OPTION = '(buf.validate.field)';
|
|
4
|
+
|
|
5
|
+
export interface ProtovalidateRule {
|
|
6
|
+
path: string;
|
|
7
|
+
value: ProtobufOptionValue;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ProtovalidateRuleDisplay {
|
|
11
|
+
label: string;
|
|
12
|
+
value?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProtobufCustomAnnotation {
|
|
16
|
+
name: string;
|
|
17
|
+
value: ProtobufOptionValue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const isOptionObject = (value: ProtobufOptionValue): value is { [key: string]: ProtobufOptionValue } =>
|
|
21
|
+
typeof value === 'object' && !Array.isArray(value);
|
|
22
|
+
|
|
23
|
+
const flattenOptionValue = (path: string, value: ProtobufOptionValue): ProtovalidateRule[] => {
|
|
24
|
+
if (!isOptionObject(value)) return [{ path, value }];
|
|
25
|
+
|
|
26
|
+
return Object.entries(value).flatMap(([name, nestedValue]) => flattenOptionValue(path ? `${path}.${name}` : name, nestedValue));
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getProtovalidateRules = (field: ProtobufField): ProtovalidateRule[] =>
|
|
30
|
+
(field.options ?? []).flatMap((option) => {
|
|
31
|
+
if (option.name !== PROTOVALIDATE_FIELD_OPTION && !option.name.startsWith(`${PROTOVALIDATE_FIELD_OPTION}.`)) return [];
|
|
32
|
+
|
|
33
|
+
const path = option.name.slice(PROTOVALIDATE_FIELD_OPTION.length).replace(/^\./, '');
|
|
34
|
+
return flattenOptionValue(path, option.value);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const isProtovalidateRequired = (field: ProtobufField) =>
|
|
38
|
+
getProtovalidateRules(field).some((rule) => rule.path === 'required' && rule.value === true);
|
|
39
|
+
|
|
40
|
+
export const getCustomFieldAnnotations = (field: ProtobufField): ProtobufCustomAnnotation[] =>
|
|
41
|
+
(field.options ?? [])
|
|
42
|
+
.filter(
|
|
43
|
+
(option) =>
|
|
44
|
+
option.name.startsWith('(') &&
|
|
45
|
+
option.name !== PROTOVALIDATE_FIELD_OPTION &&
|
|
46
|
+
!option.name.startsWith(`${PROTOVALIDATE_FIELD_OPTION}.`)
|
|
47
|
+
)
|
|
48
|
+
.map(({ name, value }) => ({ name, value }));
|
|
49
|
+
|
|
50
|
+
export const formatProtobufOptionValue = (value: ProtobufOptionValue): string => {
|
|
51
|
+
if (Array.isArray(value)) return value.map(formatProtobufOptionValue).join(', ');
|
|
52
|
+
if (isOptionObject(value)) return JSON.stringify(value);
|
|
53
|
+
return String(value);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const humanize = (value: string) => value.replace(/_/g, ' ').replace(/\b\w/g, (character) => character.toUpperCase());
|
|
57
|
+
|
|
58
|
+
const FORMAT_NAMES: Record<string, string> = {
|
|
59
|
+
address: 'Address',
|
|
60
|
+
email: 'Email',
|
|
61
|
+
hostname: 'Hostname',
|
|
62
|
+
ip: 'IP',
|
|
63
|
+
ipv4: 'IPv4',
|
|
64
|
+
ipv6: 'IPv6',
|
|
65
|
+
protobuf_fqn: 'Protobuf FQN',
|
|
66
|
+
tuuid: 'TUUID',
|
|
67
|
+
uri: 'URI',
|
|
68
|
+
uri_ref: 'URI reference',
|
|
69
|
+
uuid: 'UUID',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const getRuleScope = (path: string) => {
|
|
73
|
+
if (path.includes('repeated.items')) return 'Item';
|
|
74
|
+
if (path.includes('map.keys')) return 'Key';
|
|
75
|
+
if (path.includes('map.values')) return 'Value';
|
|
76
|
+
return '';
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const withScope = (scope: string, label: string) =>
|
|
80
|
+
scope ? `${scope} ${label.charAt(0).toLowerCase()}${label.slice(1)}` : label;
|
|
81
|
+
|
|
82
|
+
export const formatProtovalidateRule = ({ path, value }: ProtovalidateRule): ProtovalidateRuleDisplay => {
|
|
83
|
+
const name = path.split('.').pop() ?? path;
|
|
84
|
+
const scope = getRuleScope(path);
|
|
85
|
+
const formattedValue = formatProtobufOptionValue(value);
|
|
86
|
+
|
|
87
|
+
switch (name) {
|
|
88
|
+
case 'required':
|
|
89
|
+
return value === true ? { label: 'Required' } : { label: 'Required', value: formattedValue };
|
|
90
|
+
case 'const':
|
|
91
|
+
return { label: withScope(scope, 'Constant'), value: formattedValue };
|
|
92
|
+
case 'len':
|
|
93
|
+
return { label: withScope(scope, 'Length'), value: formattedValue };
|
|
94
|
+
case 'min_len':
|
|
95
|
+
return { label: withScope(scope, 'Minimum length'), value: formattedValue };
|
|
96
|
+
case 'max_len':
|
|
97
|
+
return { label: withScope(scope, 'Maximum length'), value: formattedValue };
|
|
98
|
+
case 'len_bytes':
|
|
99
|
+
return { label: withScope(scope, 'Byte length'), value: formattedValue };
|
|
100
|
+
case 'min_bytes':
|
|
101
|
+
return { label: withScope(scope, 'Minimum byte length'), value: formattedValue };
|
|
102
|
+
case 'max_bytes':
|
|
103
|
+
return { label: withScope(scope, 'Maximum byte length'), value: formattedValue };
|
|
104
|
+
case 'pattern':
|
|
105
|
+
return { label: withScope(scope, 'Match pattern'), value: formattedValue };
|
|
106
|
+
case 'gt':
|
|
107
|
+
return { label: withScope(scope, 'Greater than'), value: formattedValue };
|
|
108
|
+
case 'gte':
|
|
109
|
+
return { label: withScope(scope, 'Minimum'), value: formattedValue };
|
|
110
|
+
case 'lt':
|
|
111
|
+
return { label: withScope(scope, 'Less than'), value: formattedValue };
|
|
112
|
+
case 'lte':
|
|
113
|
+
return { label: withScope(scope, 'Maximum'), value: formattedValue };
|
|
114
|
+
case 'in':
|
|
115
|
+
return { label: withScope(scope, 'Allowed values'), value: formattedValue };
|
|
116
|
+
case 'not_in':
|
|
117
|
+
return { label: withScope(scope, 'Excluded values'), value: formattedValue };
|
|
118
|
+
case 'defined_only':
|
|
119
|
+
return value === true
|
|
120
|
+
? { label: 'Defined enum values only' }
|
|
121
|
+
: { label: 'Defined enum values only', value: formattedValue };
|
|
122
|
+
case 'min_items':
|
|
123
|
+
return { label: 'Minimum items', value: formattedValue };
|
|
124
|
+
case 'max_items':
|
|
125
|
+
return { label: 'Maximum items', value: formattedValue };
|
|
126
|
+
case 'unique':
|
|
127
|
+
return value === true ? { label: 'Unique items' } : { label: 'Unique items', value: formattedValue };
|
|
128
|
+
case 'min_pairs':
|
|
129
|
+
return { label: 'Minimum map entries', value: formattedValue };
|
|
130
|
+
case 'max_pairs':
|
|
131
|
+
return { label: 'Maximum map entries', value: formattedValue };
|
|
132
|
+
case 'email':
|
|
133
|
+
case 'hostname':
|
|
134
|
+
case 'ip':
|
|
135
|
+
case 'ipv4':
|
|
136
|
+
case 'ipv6':
|
|
137
|
+
case 'uri':
|
|
138
|
+
case 'uri_ref':
|
|
139
|
+
case 'address':
|
|
140
|
+
case 'uuid':
|
|
141
|
+
case 'tuuid':
|
|
142
|
+
case 'protobuf_fqn':
|
|
143
|
+
return value === true
|
|
144
|
+
? { label: withScope(scope, 'Format'), value: FORMAT_NAMES[name] }
|
|
145
|
+
: { label: withScope(scope, humanize(name)), value: formattedValue };
|
|
146
|
+
default:
|
|
147
|
+
return { label: withScope(scope, humanize(name)), value: formattedValue };
|
|
148
|
+
}
|
|
149
|
+
};
|
|
@@ -4,18 +4,25 @@ import SearchModal from './SearchModal.tsx';
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<div>
|
|
7
|
-
<div class="relative flex items-center w-full
|
|
7
|
+
<div class="relative flex min-w-0 items-center w-full">
|
|
8
8
|
<input
|
|
9
9
|
id="search-dummy-input"
|
|
10
10
|
type="text"
|
|
11
11
|
name="search"
|
|
12
12
|
placeholder="Search EventCatalog"
|
|
13
13
|
autocomplete="off"
|
|
14
|
-
class="block w-full rounded-md caret-transparent border-0 py-1.5 pr-
|
|
14
|
+
class="block h-9 min-w-0 w-full rounded-md caret-transparent border-0 py-1.5 pr-20 pl-10! text-[rgb(var(--ec-header-text))] bg-[rgb(var(--ec-header-bg))] shadow-xs ring-1 ring-inset ring-[rgb(var(--ec-dropdown-border))] placeholder:text-gray-400 font-light sm:text-sm sm:leading-6"
|
|
15
15
|
/>
|
|
16
16
|
<MagnifyingGlassIcon className="absolute inset-y-0 left-0 h-9 w-8 flex items-center pl-4 text-[rgb(var(--ec-icon-color))]" />
|
|
17
|
-
<div class="absolute inset-y-0 right-0 flex
|
|
18
|
-
<kbd
|
|
17
|
+
<div class="absolute inset-y-0 right-0 flex items-center gap-1 pr-2 pointer-events-none">
|
|
18
|
+
<kbd
|
|
19
|
+
class="inline-flex h-6 min-w-6 items-center justify-center rounded-lg border border-[rgb(var(--ec-dropdown-border))] bg-[rgb(var(--ec-card-bg))] px-1 font-sans text-xs font-normal text-[rgb(var(--ec-icon-color))] shadow-xs"
|
|
20
|
+
>⌘</kbd
|
|
21
|
+
>
|
|
22
|
+
<kbd
|
|
23
|
+
class="inline-flex h-6 min-w-6 items-center justify-center rounded-lg border border-[rgb(var(--ec-dropdown-border))] bg-[rgb(var(--ec-card-bg))] px-1 font-sans text-xs font-normal text-[rgb(var(--ec-icon-color))] shadow-xs"
|
|
24
|
+
>K</kbd
|
|
25
|
+
>
|
|
19
26
|
</div>
|
|
20
27
|
</div>
|
|
21
28
|
</div>
|
|
@@ -76,34 +76,39 @@ export const AssistantSettingsForm = ({ canEdit, initial, chatAvailable, hasPlan
|
|
|
76
76
|
<Row
|
|
77
77
|
title="Assistant Agent"
|
|
78
78
|
description="Assistant agent that answers questions about your architecture directly in your catalog."
|
|
79
|
-
canEdit={canEdit
|
|
79
|
+
canEdit={canEdit}
|
|
80
80
|
dirty={dirty}
|
|
81
81
|
saving={saving}
|
|
82
|
-
onSave={
|
|
82
|
+
onSave={save}
|
|
83
83
|
>
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
) : !hasPlan ? (
|
|
97
|
-
<UpgradeRequired
|
|
98
|
-
tier="Starter and Scale"
|
|
99
|
-
blurb="The EventCatalog Assistant is part of our paid plans. Upgrade to give your team a built-in AI agent that answers questions about your architecture."
|
|
100
|
-
docsUrl={ASSISTANT_DOCS_URL}
|
|
84
|
+
<div className="space-y-3">
|
|
85
|
+
<ToggleRow
|
|
86
|
+
icon={<MessageSquare className="h-4 w-4" aria-hidden />}
|
|
87
|
+
label={chatEnabled ? 'Enabled' : 'Disabled'}
|
|
88
|
+
hint={
|
|
89
|
+
chatEnabled
|
|
90
|
+
? 'Event Catalog Assistant is visible in this catalog.'
|
|
91
|
+
: 'Event Catalog Assistant is hidden from this catalog.'
|
|
92
|
+
}
|
|
93
|
+
checked={chatEnabled}
|
|
94
|
+
disabled={!canEdit}
|
|
95
|
+
onChange={setChatEnabled}
|
|
101
96
|
/>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
{chatEnabled &&
|
|
98
|
+
(chatAvailable ? (
|
|
99
|
+
<ConfigurationRequired />
|
|
100
|
+
) : !hasPlan ? (
|
|
101
|
+
<UpgradeRequired
|
|
102
|
+
tier="Starter and Scale"
|
|
103
|
+
blurb="The EventCatalog Assistant is part of our paid plans. Upgrade to give your team a built-in AI agent that answers questions about your architecture."
|
|
104
|
+
docsUrl={ASSISTANT_DOCS_URL}
|
|
105
|
+
/>
|
|
106
|
+
) : !inSSR ? (
|
|
107
|
+
<AssistantNeedsSSR />
|
|
108
|
+
) : !hasChatConfigFile ? (
|
|
109
|
+
<AssistantNeedsConfigFile />
|
|
110
|
+
) : null)}
|
|
111
|
+
</div>
|
|
107
112
|
</Row>
|
|
108
113
|
</form>
|
|
109
114
|
);
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
isVisualiserEnabled,
|
|
22
22
|
isMarkdownDownloadEnabled,
|
|
23
23
|
isRSSEnabled,
|
|
24
|
-
|
|
24
|
+
isEventCatalogChatVisible,
|
|
25
25
|
isArchitectureGraphEnabled,
|
|
26
26
|
} from '@utils/feature';
|
|
27
27
|
|
|
@@ -152,11 +152,11 @@ const editUrl =
|
|
|
152
152
|
client:only="react"
|
|
153
153
|
variant="toolbar"
|
|
154
154
|
schemas={[]}
|
|
155
|
-
chatEnabled={
|
|
155
|
+
chatEnabled={isEventCatalogChatVisible()}
|
|
156
156
|
markdownDownloadEnabled={isMarkdownDownloadEnabled()}
|
|
157
157
|
rssFeedEnabled={isRSSEnabled()}
|
|
158
158
|
editUrl={editUrl}
|
|
159
|
-
preferChatAsDefault={
|
|
159
|
+
preferChatAsDefault={isEventCatalogChatVisible()}
|
|
160
160
|
/>
|
|
161
161
|
</div>
|
|
162
162
|
</div>
|
|
@@ -7,7 +7,7 @@ import config from '@config';
|
|
|
7
7
|
import { buildUrl } from '@utils/url-builder';
|
|
8
8
|
import { GitCompare, X, AlignLeft, HistoryIcon } from 'lucide-react';
|
|
9
9
|
import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
10
|
-
import { isLLMSTxtEnabled,
|
|
10
|
+
import { isLLMSTxtEnabled, isEventCatalogChatVisible } from '@utils/feature';
|
|
11
11
|
|
|
12
12
|
import { Page } from './_index.data';
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ const pageTitle = `Diagram | ${props.data.name}`;
|
|
|
21
21
|
const currentVersion = props.data.version;
|
|
22
22
|
const allVersions = props.allVersions || [currentVersion];
|
|
23
23
|
const hasMultipleVersions = allVersions.length > 1;
|
|
24
|
-
const chatEnabled =
|
|
24
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
25
25
|
const markdownDownloadEnabled = isLLMSTxtEnabled();
|
|
26
26
|
const chatQuery = `Tell me about the "${props.data.name}" diagram (version ${props.data.version})`;
|
|
27
27
|
---
|
package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro
CHANGED
|
@@ -8,7 +8,7 @@ import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
|
8
8
|
import Badge from '@components/Badge.astro';
|
|
9
9
|
import { buildUrl } from '@utils/url-builder';
|
|
10
10
|
import { AlignLeftIcon, HistoryIcon } from 'lucide-react';
|
|
11
|
-
import {
|
|
11
|
+
import { isEventCatalogChatVisible, isMarkdownDownloadEnabled, isResourceDocsEnabled } from '@utils/feature';
|
|
12
12
|
import { getResourceDocTypeLabel } from '@utils/collections/resource-docs';
|
|
13
13
|
import { getIcon } from '@utils/badges';
|
|
14
14
|
import { collectionToResourceMap } from '@utils/collections/util';
|
|
@@ -37,7 +37,7 @@ const docsBasePath = `/docs/${props.data.resourceCollection}/${props.data.resour
|
|
|
37
37
|
const singularResourceName =
|
|
38
38
|
collectionToResourceMap[props.data.resourceCollection as keyof typeof collectionToResourceMap] ??
|
|
39
39
|
props.data.resourceCollection.slice(0, props.data.resourceCollection.length - 1);
|
|
40
|
-
const chatEnabled =
|
|
40
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
41
41
|
const chatQuery = `Tell me about the ${props.data.type} doc "${title}" for ${props.data.resourceId} (version ${props.data.version})`;
|
|
42
42
|
|
|
43
43
|
const pagefindAttributes =
|
|
@@ -69,7 +69,9 @@ const pagefindAttributes =
|
|
|
69
69
|
{
|
|
70
70
|
badges.length > 0 && (
|
|
71
71
|
<div class="flex flex-wrap gap-1.5 pt-4">
|
|
72
|
-
{badges.map((badge: any) =>
|
|
72
|
+
{badges.map((badge: any) => (
|
|
73
|
+
<Badge badge={badge} />
|
|
74
|
+
))}
|
|
73
75
|
</div>
|
|
74
76
|
)
|
|
75
77
|
}
|
|
@@ -8,7 +8,7 @@ import CopyAsMarkdown from '@components/CopyAsMarkdown';
|
|
|
8
8
|
import Badge from '@components/Badge.astro';
|
|
9
9
|
import { buildUrl } from '@utils/url-builder';
|
|
10
10
|
import { AlignLeftIcon, HistoryIcon } from 'lucide-react';
|
|
11
|
-
import {
|
|
11
|
+
import { isEventCatalogChatVisible, isMarkdownDownloadEnabled, isResourceDocsEnabled } from '@utils/feature';
|
|
12
12
|
import { getIcon } from '@utils/badges';
|
|
13
13
|
import { collectionToResourceMap } from '@utils/collections/util';
|
|
14
14
|
import { getResourceDocTypeLabel } from '@utils/collections/resource-docs';
|
|
@@ -38,7 +38,7 @@ const singularResourceName =
|
|
|
38
38
|
collectionToResourceMap[props.data.resourceCollection as keyof typeof collectionToResourceMap] ??
|
|
39
39
|
props.data.resourceCollection.slice(0, props.data.resourceCollection.length - 1);
|
|
40
40
|
const typeLabel = getResourceDocTypeLabel(props.data.type);
|
|
41
|
-
const chatEnabled =
|
|
41
|
+
const chatEnabled = isEventCatalogChatVisible();
|
|
42
42
|
const chatQuery = `Tell me about the ${props.data.type} doc "${title}" for ${props.data.resourceId} (version ${props.data.version})`;
|
|
43
43
|
|
|
44
44
|
const pagefindAttributes =
|
|
@@ -60,11 +60,17 @@ const pagefindAttributes =
|
|
|
60
60
|
<span class="text-xs md:text-sm font-semibold text-[rgb(var(--ec-accent))] capitalize">{typeLabel}</span>
|
|
61
61
|
<h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{title}</h2>
|
|
62
62
|
</div>
|
|
63
|
-
{
|
|
63
|
+
{
|
|
64
|
+
props.data.summary && (
|
|
65
|
+
<p class="text-base pt-4 text-[rgb(var(--ec-page-text-muted))] font-light">{props.data.summary}</p>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
64
68
|
{
|
|
65
69
|
badges.length > 0 && (
|
|
66
70
|
<div class="flex flex-wrap gap-1.5 pt-4">
|
|
67
|
-
{badges.map((badge: any) =>
|
|
71
|
+
{badges.map((badge: any) => (
|
|
72
|
+
<Badge badge={badge} />
|
|
73
|
+
))}
|
|
68
74
|
</div>
|
|
69
75
|
)
|
|
70
76
|
}
|