@eventcatalog/core 4.12.2 → 5.0.0-beta.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/LICENSE +226 -95
- package/NOTICE +30 -0
- package/README.md +3 -2
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +43 -16
- package/dist/analytics/log-build.d.cts +6 -5
- package/dist/analytics/log-build.d.ts +6 -5
- package/dist/analytics/log-build.js +4 -3
- package/dist/{chunk-U4YJSTGV.js → chunk-AYNZXUB5.js} +2 -10
- package/dist/{chunk-IVVM67LN.js → chunk-CR6AK5LR.js} +1 -1
- package/dist/{chunk-GTIC4R74.js → chunk-LR7AGRHN.js} +13 -16
- package/dist/chunk-TQLRG35T.js +203 -0
- package/dist/{chunk-WK4J6FP3.js → chunk-TWN43V4T.js} +1 -1
- package/dist/{chunk-ZW3MYAWF.js → chunk-WAIADKQE.js} +1 -1
- package/dist/{chunk-RPVA2SZY.js → chunk-ZHKEARLJ.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +407 -291
- package/dist/eventcatalog.config.d.cts +2 -3
- package/dist/eventcatalog.config.d.ts +2 -3
- package/dist/eventcatalog.js +30 -93
- package/dist/federation/content-cache.d.cts +0 -5
- package/dist/federation/content-cache.d.ts +0 -5
- package/dist/federation/diagnostics.d.cts +0 -5
- package/dist/federation/diagnostics.d.ts +0 -5
- package/dist/federation/federate.cjs +0 -9
- package/dist/federation/federate.d.cts +0 -5
- package/dist/federation/federate.d.ts +0 -5
- package/dist/federation/federate.js +2 -3
- package/dist/federation/filesystem-source-provider.d.cts +0 -5
- package/dist/federation/filesystem-source-provider.d.ts +0 -5
- package/dist/federation/github-source-provider.d.cts +0 -5
- package/dist/federation/github-source-provider.d.ts +0 -5
- package/dist/federation/output-transaction.d.cts +0 -4
- package/dist/federation/output-transaction.d.ts +0 -4
- package/dist/federation/public-assets.d.cts +0 -5
- package/dist/federation/public-assets.d.ts +0 -5
- package/dist/federation/source-provider.d.cts +0 -5
- package/dist/federation/source-provider.d.ts +0 -5
- package/dist/federation/types.d.cts +0 -5
- package/dist/federation/types.d.ts +0 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/license-C1y-56bb.d.cts +23 -0
- package/dist/license-C1y-56bb.d.ts +23 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__layout.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__react.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__server.mjs +3 -0
- package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +12 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__graphql.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__json.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__markup.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__protobuf.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__yaml.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-dark.mjs +3 -0
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-light.mjs +3 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +240 -0
- package/dist/utils/license-status.d.cts +28 -0
- package/dist/utils/license-status.d.ts +28 -0
- package/dist/utils/license-status.js +12 -0
- package/eventcatalog/astro.config.mjs +1 -1
- package/eventcatalog/integrations/eventcatalog-runtime.mjs +1 -1
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +29 -19
- package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +74 -0
- package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +24 -28
- package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +16 -11
- package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +4 -218
- package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +27 -36
- package/eventcatalog/src/components/Header.astro +43 -58
- package/eventcatalog/src/components/Lists/PillListFlat.styles.css +17 -17
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +1 -1
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -0
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +49 -18
- package/eventcatalog/src/components/MDX/RemoteFile.astro +2 -24
- package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +59 -93
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +1 -32
- package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +20 -67
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -11
- package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +11 -60
- package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -3
- package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +0 -3
- package/eventcatalog/src/components/SchemaExplorer/VersionHistoryModal.tsx +2 -9
- package/eventcatalog/src/components/SchemaExplorer/parse-schema.ts +46 -0
- package/eventcatalog/src/components/SchemaExplorer/utils.ts +11 -0
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +2 -9
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +288 -0
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +3 -19
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +85 -30
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +7 -75
- package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +2 -2
- package/eventcatalog/src/components/TrialBadge.astro +82 -0
- package/eventcatalog/src/content.config.ts +9 -90
- package/eventcatalog/src/{enterprise → features}/ai/chat-api.ts +22 -34
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/ga4.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/gtm.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/adapters/posthog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsHead.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsTracker.astro +2 -4
- package/eventcatalog/src/{enterprise → features}/analytics/tracker.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/api/catalog.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/[...auth].ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/custom-pages.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/index.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/collections/resource-docs.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/collection.ts +0 -5
- package/eventcatalog/src/features/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/index.tsx +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/types.ts +0 -5
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/index.astro → features/custom-documentation/components/CustomDocumentationPage.astro} +5 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/badge-styles.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/custom-docs.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/docs-search.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/custom-pages/routes.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/directory/user-team-directory.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-extractor.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/field-indexer.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/fields-db.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/fields/pages/api/fields.ts +1 -6
- package/eventcatalog/src/{enterprise → features}/fields/pages/fields.astro +1 -2
- package/eventcatalog/src/{enterprise → features}/integrations/eventcatalog-features.ts +17 -75
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/links.ts +59 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +299 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/shared.ts +14 -0
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +454 -0
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +432 -0
- package/eventcatalog/src/features/mcp/apps/mermaid-stub.ts +10 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/schema-code.tsx +65 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/shared.ts +23 -0
- package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +170 -0
- package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +98 -0
- package/eventcatalog/src/features/mcp/apps/shared/resource-types.ts +15 -0
- package/eventcatalog/src/features/mcp/apps/viewer/shared.ts +24 -0
- package/eventcatalog/src/features/mcp/apps/viewer/styles.css +25 -0
- package/eventcatalog/src/features/mcp/apps/viewer/view.tsx +59 -0
- package/eventcatalog/src/features/mcp/mcp-app-icons.ts +63 -0
- package/eventcatalog/src/features/mcp/mcp-apps.ts +160 -0
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-auth.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scope.ts +7 -7
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-scoped-tools.ts +47 -40
- package/eventcatalog/src/{enterprise → features}/mcp/mcp-server.ts +347 -34
- package/eventcatalog/src/{enterprise → features}/mcp/oauth-protected-resource.ts +0 -5
- package/eventcatalog/src/features/mcp/schema-viewer.ts +24 -0
- package/eventcatalog/src/{enterprise → features}/tools/catalog-tools.ts +133 -102
- package/eventcatalog/src/features/tools/index.ts +5 -0
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/reset.ts +0 -5
- package/eventcatalog/src/{enterprise → features}/visualizer-layout/save.ts +0 -5
- package/eventcatalog/src/layouts/BaseLayout.astro +2 -2
- package/eventcatalog/src/layouts/Footer.astro +31 -39
- package/eventcatalog/src/layouts/SettingsLayout.astro +6 -6
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +7 -37
- package/eventcatalog/src/{enterprise → pages}/api/schemas/[collection]/[id]/[version]/index.ts +0 -22
- package/eventcatalog/src/{enterprise → pages}/api/schemas/services/[id]/[version]/[specification]/index.ts +0 -19
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -5
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].md.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].mdx.ts +2 -6
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +9 -5
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +12 -0
- package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/root-index.astro → pages/docs/custom/index.astro} +1 -23
- package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -9
- package/eventcatalog/src/pages/docs/llm/llms.txt.ts +4 -4
- package/eventcatalog/src/pages/docs/llm/schemas.txt.ts +0 -11
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +2 -2
- package/eventcatalog/src/pages/index.astro +2 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +0 -3
- package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -4
- package/eventcatalog/src/pages/settings/assistant.astro +2 -4
- package/eventcatalog/src/pages/settings/license.astro +18 -0
- package/eventcatalog/src/pages/settings/llm-access.astro +1 -4
- package/eventcatalog/src/pages/settings/mcp.astro +33 -4
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -2
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +2 -45
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +7 -109
- package/eventcatalog/src/pages/visualiser/_mermaid-route.ts +78 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/_index.data.ts +44 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +3 -40
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/_index.data.ts +29 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +3 -38
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +56 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version].mermaid.ts +20 -0
- package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -32
- package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -8
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +2 -12
- package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +0 -10
- package/eventcatalog/src/stores/sidebar-store/state.ts +4 -6
- package/eventcatalog/src/styles/theme.css +22 -18
- package/eventcatalog/src/styles/themes/forest.css +8 -8
- package/eventcatalog/src/styles/themes/ocean.css +8 -8
- package/eventcatalog/src/styles/themes/sapphire.css +8 -8
- package/eventcatalog/src/styles/themes/sunset.css +8 -8
- package/eventcatalog/src/utils/clipboard.ts +4 -4
- package/eventcatalog/src/utils/collections/flow-step-schema.ts +117 -0
- package/eventcatalog/src/utils/collections/pointer-schema.ts +7 -0
- package/eventcatalog/src/utils/collections/resource-docs.ts +677 -14
- package/eventcatalog/src/utils/collections/schema-loader.ts +0 -5
- package/eventcatalog/src/utils/feature.ts +14 -23
- package/eventcatalog/src/utils/license.ts +114 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram-types.ts +32 -0
- package/eventcatalog/src/utils/node-graphs/architecture-diagram.ts +84 -0
- package/eventcatalog/src/utils/node-graphs/catalog-force-graph.ts +1 -0
- package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +4 -25
- package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -39
- package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +11 -27
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +679 -0
- package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +3 -20
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +62 -4
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +8 -23
- package/eventcatalog/src/utils/node-graphs/flow-lanes.ts +119 -0
- package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +153 -45
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +28 -0
- package/eventcatalog/src/utils/node-graphs/layout-persistence.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +16 -34
- package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -25
- package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +18 -54
- package/eventcatalog/src/utils/node-graphs/system-levels-node-graph.ts +59 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +20 -80
- package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -78
- package/eventcatalog/src/utils/trial.ts +36 -0
- package/eventcatalog/tsconfig.json +1 -1
- package/package.json +11 -11
- package/dist/chunk-FV56YFM4.js +0 -7
- package/dist/federation/entitlement.cjs +0 -31
- package/dist/federation/entitlement.d.cts +0 -12
- package/dist/federation/entitlement.d.ts +0 -12
- package/dist/federation/entitlement.js +0 -6
- package/dist/runtime-dependencies/dagre.mjs +0 -3
- package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +0 -265
- package/eventcatalog/src/enterprise/LICENSE +0 -57
- package/eventcatalog/src/enterprise/README.md +0 -5
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +0 -691
- package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +0 -9
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/[...path]/index.astro +0 -18
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/feature.astro +0 -171
- package/eventcatalog/src/enterprise/feature.ts +0 -75
- package/eventcatalog/src/enterprise/tools/index.ts +0 -10
- package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +0 -126
- package/eventcatalog/src/pages/settings/billing.astro +0 -17
- package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +0 -26
- package/eventcatalog/src/types/mcp-modules.d.ts +0 -67
- package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +0 -261
- package/eventcatalog/src/utils/node-graphs/export-node-graph.ts +0 -91
- /package/eventcatalog/src/{enterprise → features}/auth/error.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/login.astro +0 -0
- /package/eventcatalog/src/{enterprise → features}/auth/unauthorized.astro +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path]/_index.data.ts +0 -0
- /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path].mdx.ts +0 -0
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
SCHEMA_RELATIONSHIP_LABELS,
|
|
39
39
|
} from './utils';
|
|
40
40
|
import { createSchemaDetailsLoader, useSchemaDetails } from './useSchemaDetails';
|
|
41
|
-
import {
|
|
41
|
+
import { parseSchemaForViewer } from './parse-schema';
|
|
42
42
|
import type { SchemaItem, SchemaSourceInfo, SchemaRelationshipCollection, VersionDiff, Owner, Producer } from './types';
|
|
43
43
|
|
|
44
44
|
const MESSAGE_TYPE_LABELS: Partial<Record<SchemaItem['collection'], string>> = {
|
|
@@ -310,7 +310,6 @@ interface SchemaDetailsPanelProps {
|
|
|
310
310
|
availableVersions: SchemaItem[];
|
|
311
311
|
selectedVersion: string | null;
|
|
312
312
|
onVersionChange: (version: string) => void;
|
|
313
|
-
apiAccessEnabled?: boolean;
|
|
314
313
|
showOwners?: boolean;
|
|
315
314
|
showProducersConsumers?: boolean;
|
|
316
315
|
/** Tab slug from the URL, when the server could read it. Lets the first render show the right tab. */
|
|
@@ -324,7 +323,6 @@ export default function SchemaDetailsPanel({
|
|
|
324
323
|
availableVersions,
|
|
325
324
|
selectedVersion,
|
|
326
325
|
onVersionChange,
|
|
327
|
-
apiAccessEnabled = false,
|
|
328
326
|
showOwners = true,
|
|
329
327
|
showProducersConsumers = true,
|
|
330
328
|
initialTab,
|
|
@@ -428,55 +426,14 @@ export default function SchemaDetailsPanel({
|
|
|
428
426
|
}, [comparing, diffFromItem, diffToItem]);
|
|
429
427
|
const selectedDiffs = selectedDiff ? [selectedDiff] : [];
|
|
430
428
|
|
|
431
|
-
//
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (!parsed.properties && !parsed.$schema && !parsed.type) {
|
|
440
|
-
return null;
|
|
441
|
-
}
|
|
442
|
-
return parsed;
|
|
443
|
-
} catch {
|
|
444
|
-
return null;
|
|
445
|
-
}
|
|
446
|
-
}, [message.schemaContent, message.schemaExtension]);
|
|
447
|
-
|
|
448
|
-
// Check if this is an Avro schema
|
|
449
|
-
const parsedAvroSchema = useMemo(() => {
|
|
450
|
-
const extLower = message.schemaExtension?.toLowerCase();
|
|
451
|
-
const isAvroSchema =
|
|
452
|
-
(extLower === 'avro' || extLower === 'avsc') && message.schemaContent && message.schemaContent.trim() !== '';
|
|
453
|
-
if (!isAvroSchema) return null;
|
|
454
|
-
|
|
455
|
-
try {
|
|
456
|
-
const parsed = JSON.parse(message.schemaContent ?? '');
|
|
457
|
-
if (!parsed.type) {
|
|
458
|
-
return null;
|
|
459
|
-
}
|
|
460
|
-
return parsed;
|
|
461
|
-
} catch {
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
}, [message.schemaContent, message.schemaExtension]);
|
|
465
|
-
|
|
466
|
-
// Check if this is a Protobuf schema. The extension falls back to the schema
|
|
467
|
-
// format when the schema has no file path, so accept both 'proto' and 'protobuf'.
|
|
468
|
-
const parsedProtoSchema = useMemo(() => {
|
|
469
|
-
const extLower = message.schemaExtension?.toLowerCase();
|
|
470
|
-
const isProtoSchema =
|
|
471
|
-
(extLower === 'proto' || extLower === 'protobuf') && message.schemaContent && message.schemaContent.trim() !== '';
|
|
472
|
-
if (!isProtoSchema) return null;
|
|
473
|
-
|
|
474
|
-
try {
|
|
475
|
-
return parseProtobufSchema(message.schemaContent ?? '');
|
|
476
|
-
} catch {
|
|
477
|
-
return null;
|
|
478
|
-
}
|
|
479
|
-
}, [message.schemaContent, message.schemaExtension]);
|
|
429
|
+
// Parse JSON Schema, Avro and Protobuf schemas for the Properties tab
|
|
430
|
+
const viewableSchema = useMemo(
|
|
431
|
+
() => parseSchemaForViewer(message.schemaExtension, message.schemaContent),
|
|
432
|
+
[message.schemaContent, message.schemaExtension]
|
|
433
|
+
);
|
|
434
|
+
const parsedSchema = viewableSchema.kind === 'json' ? viewableSchema.schema : null;
|
|
435
|
+
const parsedAvroSchema = viewableSchema.kind === 'avro' ? viewableSchema.schema : null;
|
|
436
|
+
const parsedProtoSchema = viewableSchema.kind === 'protobuf' ? viewableSchema.schema : null;
|
|
480
437
|
|
|
481
438
|
const handleCopy = async () => {
|
|
482
439
|
if (!message.schemaContent) return;
|
|
@@ -832,7 +789,7 @@ export default function SchemaDetailsPanel({
|
|
|
832
789
|
<p className="text-sm">No schema content available</p>
|
|
833
790
|
</div>
|
|
834
791
|
) : (
|
|
835
|
-
<DiffViewer diffs={selectedDiffs}
|
|
792
|
+
<DiffViewer diffs={selectedDiffs} />
|
|
836
793
|
)}
|
|
837
794
|
</div>
|
|
838
795
|
</div>
|
|
@@ -843,12 +800,7 @@ export default function SchemaDetailsPanel({
|
|
|
843
800
|
) : activeTab === 'flows' && showFlowsTab ? (
|
|
844
801
|
<SchemaFlows message={message} flows={flows} />
|
|
845
802
|
) : activeTab === 'api' ? (
|
|
846
|
-
<ApiContentViewer
|
|
847
|
-
message={message}
|
|
848
|
-
onCopy={handleCopyCustom}
|
|
849
|
-
copiedId={copiedId}
|
|
850
|
-
apiAccessEnabled={apiAccessEnabled}
|
|
851
|
-
/>
|
|
803
|
+
<ApiContentViewer message={message} onCopy={handleCopyCustom} copiedId={copiedId} />
|
|
852
804
|
) : (
|
|
853
805
|
<SchemaContentViewer
|
|
854
806
|
message={message}
|
|
@@ -877,7 +829,6 @@ export default function SchemaDetailsPanel({
|
|
|
877
829
|
onOpenChange={setIsDiffModalOpen}
|
|
878
830
|
diffs={selectedDiffs}
|
|
879
831
|
messageName={message.data.name}
|
|
880
|
-
apiAccessEnabled={apiAccessEnabled}
|
|
881
832
|
/>
|
|
882
833
|
<SchemaCodeModal
|
|
883
834
|
isOpen={isCodeModalOpen}
|
|
@@ -44,10 +44,9 @@ function getGroupKey(item: SchemaItem): string {
|
|
|
44
44
|
|
|
45
45
|
interface SchemaExplorerProps {
|
|
46
46
|
schemas: SchemaItem[];
|
|
47
|
-
apiAccessEnabled?: boolean;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
export default function SchemaExplorer({ schemas
|
|
49
|
+
export default function SchemaExplorer({ schemas }: SchemaExplorerProps) {
|
|
51
50
|
const [searchQuery, setSearchQuery] = useState(() => {
|
|
52
51
|
if (typeof window !== 'undefined') {
|
|
53
52
|
const stored = localStorage.getItem('schemaRegistrySearchQuery');
|
|
@@ -594,7 +593,6 @@ export default function SchemaExplorer({ schemas, apiAccessEnabled = false }: Sc
|
|
|
594
593
|
availableVersions={availableVersions}
|
|
595
594
|
selectedVersion={selectedVersion}
|
|
596
595
|
onVersionChange={handleVersionChange}
|
|
597
|
-
apiAccessEnabled={apiAccessEnabled}
|
|
598
596
|
/>
|
|
599
597
|
) : (
|
|
600
598
|
<div className="flex h-full items-center justify-center">
|
|
@@ -5,7 +5,6 @@ import type { SchemaItem } from './types';
|
|
|
5
5
|
interface SchemaPageViewerProps {
|
|
6
6
|
message: SchemaItem;
|
|
7
7
|
availableVersions: SchemaItem[];
|
|
8
|
-
apiAccessEnabled?: boolean;
|
|
9
8
|
showOwners?: boolean;
|
|
10
9
|
showProducersConsumers?: boolean;
|
|
11
10
|
/** Tab requested in the URL, resolved on the server to avoid a flash of the default tab. */
|
|
@@ -18,7 +17,6 @@ interface SchemaPageViewerProps {
|
|
|
18
17
|
export default function SchemaPageViewer({
|
|
19
18
|
message,
|
|
20
19
|
availableVersions,
|
|
21
|
-
apiAccessEnabled = false,
|
|
22
20
|
showOwners = true,
|
|
23
21
|
showProducersConsumers = true,
|
|
24
22
|
initialTab,
|
|
@@ -38,7 +36,6 @@ export default function SchemaPageViewer({
|
|
|
38
36
|
availableVersions={availableVersions}
|
|
39
37
|
selectedVersion={message.data.version}
|
|
40
38
|
onVersionChange={handleVersionChange}
|
|
41
|
-
apiAccessEnabled={apiAccessEnabled}
|
|
42
39
|
showOwners={showOwners}
|
|
43
40
|
showProducersConsumers={showProducersConsumers}
|
|
44
41
|
initialTab={initialTab}
|
|
@@ -8,16 +8,9 @@ interface VersionHistoryModalProps {
|
|
|
8
8
|
onOpenChange: (open: boolean) => void;
|
|
9
9
|
diffs: VersionDiff[];
|
|
10
10
|
messageName: string;
|
|
11
|
-
apiAccessEnabled?: boolean;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
export default function VersionHistoryModal({
|
|
15
|
-
isOpen,
|
|
16
|
-
onOpenChange,
|
|
17
|
-
diffs,
|
|
18
|
-
messageName,
|
|
19
|
-
apiAccessEnabled = false,
|
|
20
|
-
}: VersionHistoryModalProps) {
|
|
13
|
+
export default function VersionHistoryModal({ isOpen, onOpenChange, diffs, messageName }: VersionHistoryModalProps) {
|
|
21
14
|
return (
|
|
22
15
|
<Dialog.Root open={isOpen} onOpenChange={onOpenChange}>
|
|
23
16
|
<Dialog.Portal>
|
|
@@ -48,7 +41,7 @@ export default function VersionHistoryModal({
|
|
|
48
41
|
{/* Content */}
|
|
49
42
|
<div className="flex-1 overflow-y-auto p-6">
|
|
50
43
|
{diffs.length > 0 ? (
|
|
51
|
-
<DiffViewer diffs={diffs}
|
|
44
|
+
<DiffViewer diffs={diffs} />
|
|
52
45
|
) : (
|
|
53
46
|
<div className="flex items-center justify-center h-full">
|
|
54
47
|
<p className="text-[rgb(var(--ec-page-text-muted))] text-center">No version comparison available</p>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { parseProtobufSchema, type ProtobufSchema } from '@utils/protobuf-schema';
|
|
2
|
+
|
|
3
|
+
/** A schema, parsed for the viewer that shows its properties. Other formats are only shown as code. */
|
|
4
|
+
export type ViewableSchema =
|
|
5
|
+
| { kind: 'json'; schema: Record<string, any> }
|
|
6
|
+
| { kind: 'avro'; schema: Record<string, any> }
|
|
7
|
+
| { kind: 'protobuf'; schema: ProtobufSchema }
|
|
8
|
+
| { kind: 'code' };
|
|
9
|
+
|
|
10
|
+
const parseJson = (content: string) => {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(content);
|
|
13
|
+
} catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parses a schema for the JSON Schema, Avro or Protobuf viewer, from its file extension.
|
|
20
|
+
* Used by the Schema Explorer and the MCP server's schema viewer, so both show the same schemas as properties.
|
|
21
|
+
*/
|
|
22
|
+
export function parseSchemaForViewer(extension: string | undefined, content: string | undefined): ViewableSchema {
|
|
23
|
+
if (!content?.trim()) return { kind: 'code' };
|
|
24
|
+
|
|
25
|
+
switch (extension?.toLowerCase()) {
|
|
26
|
+
case 'json': {
|
|
27
|
+
const schema = parseJson(content);
|
|
28
|
+
return schema && (schema.properties || schema.$schema || schema.type) ? { kind: 'json', schema } : { kind: 'code' };
|
|
29
|
+
}
|
|
30
|
+
case 'avro':
|
|
31
|
+
case 'avsc': {
|
|
32
|
+
const schema = parseJson(content);
|
|
33
|
+
return schema?.type ? { kind: 'avro', schema } : { kind: 'code' };
|
|
34
|
+
}
|
|
35
|
+
// The extension falls back to the schema format when the schema has no file path, so accept both
|
|
36
|
+
case 'proto':
|
|
37
|
+
case 'protobuf':
|
|
38
|
+
try {
|
|
39
|
+
return { kind: 'protobuf', schema: parseProtobufSchema(content) };
|
|
40
|
+
} catch {
|
|
41
|
+
return { kind: 'code' };
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
return { kind: 'code' };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -113,6 +113,17 @@ export const getLanguageForHighlight = (extension?: string): string => {
|
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
+
/** Style of highlighted schema code, shared by the Schema tab and the MCP server's schema viewer */
|
|
117
|
+
export const SCHEMA_CODE_STYLE = {
|
|
118
|
+
margin: 0,
|
|
119
|
+
padding: '1.25rem',
|
|
120
|
+
borderRadius: 0,
|
|
121
|
+
fontSize: '0.8125rem',
|
|
122
|
+
lineHeight: '1.625',
|
|
123
|
+
background: 'transparent',
|
|
124
|
+
overflow: 'auto',
|
|
125
|
+
} as const;
|
|
126
|
+
|
|
116
127
|
export const getSchemaTypeLabel = (extension?: string): string => {
|
|
117
128
|
if (!extension) return 'JSON';
|
|
118
129
|
const ext = extension.toLowerCase();
|
|
@@ -4,19 +4,18 @@ import { ExternalLink, MessageSquare, ServerCog, Wrench } from 'lucide-react';
|
|
|
4
4
|
import { aiSettingsSchema } from '@utils/eventcatalog-config/config-schema';
|
|
5
5
|
import { ReadOnlyBanner } from './ReadOnlyBanner';
|
|
6
6
|
import { Row, cn } from './Row';
|
|
7
|
-
import { ASSISTANT_CONFIGURATION_DOCS_URL, ASSISTANT_DOCS_URL, ToggleRow
|
|
7
|
+
import { ASSISTANT_CONFIGURATION_DOCS_URL, ASSISTANT_DOCS_URL, ToggleRow } from './SettingsShared';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
canEdit: boolean;
|
|
11
11
|
initial: { chatEnabled: boolean; llmsTxtEnabled: boolean };
|
|
12
12
|
chatAvailable: boolean;
|
|
13
|
-
hasPlan: boolean;
|
|
14
13
|
inSSR: boolean;
|
|
15
14
|
hasChatConfigFile: boolean;
|
|
16
15
|
apiBase: string;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
export const AssistantSettingsForm = ({ canEdit, initial, chatAvailable,
|
|
18
|
+
export const AssistantSettingsForm = ({ canEdit, initial, chatAvailable, inSSR, hasChatConfigFile, apiBase }: Props) => {
|
|
20
19
|
const [chatEnabled, setChatEnabled] = useState(initial.chatEnabled);
|
|
21
20
|
const [pristine, setPristine] = useState(initial.chatEnabled);
|
|
22
21
|
const [saving, setSaving] = useState(false);
|
|
@@ -97,12 +96,6 @@ export const AssistantSettingsForm = ({ canEdit, initial, chatAvailable, hasPlan
|
|
|
97
96
|
{chatEnabled &&
|
|
98
97
|
(chatAvailable ? (
|
|
99
98
|
<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
99
|
) : !inSSR ? (
|
|
107
100
|
<AssistantNeedsSSR />
|
|
108
101
|
) : !hasChatConfigFile ? (
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { ArrowUpRight, Clock, TriangleAlert } from 'lucide-react';
|
|
3
|
+
import { Row, cn } from './Row';
|
|
4
|
+
import { getTrialStatus, LICENSE_FAQ_URL, LICENSE_REMINDER_DAYS, LICENSE_RENEW_URL, TRIAL_LENGTH_DAYS } from '@utils/trial';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The license status (see getLicenseStatus in @utils/license) with dates as unix ms, so it can be
|
|
8
|
+
* passed to the browser. Days left are counted there, so a prerendered page stays current.
|
|
9
|
+
*/
|
|
10
|
+
export type LicenseProps =
|
|
11
|
+
| { state: 'none' }
|
|
12
|
+
| {
|
|
13
|
+
state: 'licensed' | 'expired';
|
|
14
|
+
org?: string;
|
|
15
|
+
licenseId?: string;
|
|
16
|
+
issuedAt?: number;
|
|
17
|
+
expiresAt?: number;
|
|
18
|
+
}
|
|
19
|
+
| { state: 'plan'; plan: 'scale' | 'starter' }
|
|
20
|
+
| { state: 'invalid'; reason: string };
|
|
21
|
+
|
|
22
|
+
const DAY_IN_MS = 24 * 60 * 60 * 1000;
|
|
23
|
+
|
|
24
|
+
// A fixed locale and time zone, so the browser renders the same dates as the server
|
|
25
|
+
const formatDate = (date?: Date | number) =>
|
|
26
|
+
date === undefined ? '—' : new Date(date).toLocaleDateString('en-GB', { dateStyle: 'long', timeZone: 'UTC' });
|
|
27
|
+
const formatDays = (days: number) => `${days} ${days === 1 ? 'day' : 'days'}`;
|
|
28
|
+
|
|
29
|
+
type Tone = 'success' | 'warning' | 'danger' | 'info' | 'neutral';
|
|
30
|
+
|
|
31
|
+
const PILL_TONES: Record<Tone, string> = {
|
|
32
|
+
success:
|
|
33
|
+
'border-[rgb(var(--ec-badge-color-green-text)/0.3)] bg-[rgb(var(--ec-badge-color-green-background))] text-[rgb(var(--ec-badge-color-green-text))]',
|
|
34
|
+
warning:
|
|
35
|
+
'border-[rgb(var(--ec-badge-color-amber-text)/0.3)] bg-[rgb(var(--ec-badge-color-amber-background))] text-[rgb(var(--ec-badge-color-amber-text))]',
|
|
36
|
+
danger:
|
|
37
|
+
'border-[rgb(var(--ec-badge-color-red-text)/0.3)] bg-[rgb(var(--ec-badge-color-red-background))] text-[rgb(var(--ec-badge-color-red-text))]',
|
|
38
|
+
info: 'border-[rgb(var(--ec-accent)/0.3)] bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))]',
|
|
39
|
+
neutral: 'border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))]',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const StatusPill = ({ tone, children }: { tone: Tone; children: React.ReactNode }) => (
|
|
43
|
+
<span
|
|
44
|
+
className={cn('inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-[11px] font-semibold', PILL_TONES[tone])}
|
|
45
|
+
>
|
|
46
|
+
<span className="h-1.5 w-1.5 rounded-full bg-current" aria-hidden />
|
|
47
|
+
{children}
|
|
48
|
+
</span>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
type Detail = { label: string; value: React.ReactNode; mono?: boolean };
|
|
52
|
+
|
|
53
|
+
const DetailsTable = ({
|
|
54
|
+
title,
|
|
55
|
+
status,
|
|
56
|
+
details,
|
|
57
|
+
}: {
|
|
58
|
+
title: string;
|
|
59
|
+
status: { tone: Tone; label: string };
|
|
60
|
+
details: Detail[];
|
|
61
|
+
}) => (
|
|
62
|
+
<div className="overflow-hidden rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))]">
|
|
63
|
+
<div className="flex items-center justify-between gap-3 border-b border-[rgb(var(--ec-page-border))] px-4 py-3">
|
|
64
|
+
<p className="text-[13px] font-semibold text-[rgb(var(--ec-page-text))]">{title}</p>
|
|
65
|
+
<StatusPill tone={status.tone}>{status.label}</StatusPill>
|
|
66
|
+
</div>
|
|
67
|
+
<dl className="divide-y divide-[rgb(var(--ec-page-border))]">
|
|
68
|
+
{details.map((detail) => (
|
|
69
|
+
<div key={detail.label} className="grid grid-cols-[9rem_minmax(0,_1fr)] gap-4 px-4 py-2.5">
|
|
70
|
+
<dt className="text-[12px] text-[rgb(var(--ec-page-text-muted))]">{detail.label}</dt>
|
|
71
|
+
<dd
|
|
72
|
+
className={cn(
|
|
73
|
+
'min-w-0 break-words text-[13px] text-[rgb(var(--ec-page-text))]',
|
|
74
|
+
detail.mono && 'font-mono text-[12px]'
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
{detail.value}
|
|
78
|
+
</dd>
|
|
79
|
+
</div>
|
|
80
|
+
))}
|
|
81
|
+
</dl>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// Verified when the page was rendered, but may have expired since
|
|
86
|
+
const isExpired = (license: LicenseProps, now: number) =>
|
|
87
|
+
license.state === 'expired' || (license.state === 'licensed' && license.expiresAt !== undefined && license.expiresAt <= now);
|
|
88
|
+
|
|
89
|
+
const PLAN_NAMES = { scale: 'EventCatalog Scale', starter: 'EventCatalog Starter' };
|
|
90
|
+
|
|
91
|
+
// Days left on a license that's about to expire, or undefined
|
|
92
|
+
const getDaysLeft = (license: LicenseProps, now: number) => {
|
|
93
|
+
if (license.state !== 'licensed' || license.expiresAt === undefined) return;
|
|
94
|
+
const daysLeft = Math.max(0, Math.ceil((license.expiresAt - now) / DAY_IN_MS));
|
|
95
|
+
return daysLeft < LICENSE_REMINDER_DAYS ? daysLeft : undefined;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A callout below the license once it's about to expire, or has expired, so it's hard to miss.
|
|
100
|
+
*/
|
|
101
|
+
const LicenseNotice = ({ license, now }: { license: LicenseProps; now: number }) => {
|
|
102
|
+
const expired = isExpired(license, now);
|
|
103
|
+
const daysLeft = getDaysLeft(license, now);
|
|
104
|
+
if (!expired && daysLeft === undefined) return null;
|
|
105
|
+
|
|
106
|
+
const expiresAt = license.state === 'licensed' || license.state === 'expired' ? license.expiresAt : undefined;
|
|
107
|
+
const Icon = expired ? TriangleAlert : Clock;
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
role="alert"
|
|
111
|
+
className={cn(
|
|
112
|
+
'flex gap-3 rounded-lg border p-4',
|
|
113
|
+
expired
|
|
114
|
+
? 'border-[rgb(var(--ec-badge-color-red-text)/0.3)] bg-[rgb(var(--ec-badge-color-red-background))] text-[rgb(var(--ec-badge-color-red-text))]'
|
|
115
|
+
: 'border-[rgb(var(--ec-badge-color-amber-text)/0.3)] bg-[rgb(var(--ec-badge-color-amber-background))] text-[rgb(var(--ec-badge-color-amber-text))]'
|
|
116
|
+
)}
|
|
117
|
+
>
|
|
118
|
+
<Icon className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
|
|
119
|
+
<div className="space-y-1">
|
|
120
|
+
<p className="text-[13px] font-semibold">
|
|
121
|
+
{expired ? 'Your commercial license has expired' : `Your commercial license expires in ${formatDays(daysLeft!)}`}
|
|
122
|
+
</p>
|
|
123
|
+
<p className="text-[13px] opacity-90">
|
|
124
|
+
{expired
|
|
125
|
+
? `It expired on ${formatDate(expiresAt)}. Renew it to keep using EventCatalog commercially.`
|
|
126
|
+
: `It expires on ${formatDate(expiresAt)}. Renew it before then to keep using EventCatalog commercially.`}
|
|
127
|
+
</p>
|
|
128
|
+
<div className="flex flex-wrap items-center gap-3 pt-2">
|
|
129
|
+
<a
|
|
130
|
+
href={LICENSE_RENEW_URL}
|
|
131
|
+
target="_blank"
|
|
132
|
+
rel="noreferrer"
|
|
133
|
+
className="inline-flex items-center gap-1.5 rounded-md bg-[rgb(var(--ec-page-text))] px-3.5 py-1.5 text-[13px] font-medium text-[rgb(var(--ec-page-bg))] shadow-sm transition-opacity hover:opacity-85"
|
|
134
|
+
>
|
|
135
|
+
Renew license
|
|
136
|
+
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden />
|
|
137
|
+
</a>
|
|
138
|
+
<a
|
|
139
|
+
href={LICENSE_FAQ_URL}
|
|
140
|
+
target="_blank"
|
|
141
|
+
rel="noreferrer"
|
|
142
|
+
className="text-[13px] font-medium underline underline-offset-2 hover:opacity-80"
|
|
143
|
+
>
|
|
144
|
+
License FAQ
|
|
145
|
+
</a>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const LicenseTable = ({ license, now }: { license: LicenseProps; now: number }) => {
|
|
153
|
+
if (license.state === 'plan') {
|
|
154
|
+
return (
|
|
155
|
+
<DetailsTable
|
|
156
|
+
title={PLAN_NAMES[license.plan]}
|
|
157
|
+
status={{ tone: 'success', label: 'Active' }}
|
|
158
|
+
details={[{ label: 'License key', value: `EVENTCATALOG_${license.plan.toUpperCase()}_LICENSE_KEY`, mono: true }]}
|
|
159
|
+
/>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
const expired = isExpired(license, now);
|
|
163
|
+
if (license.state === 'licensed' && !expired) {
|
|
164
|
+
const daysLeft = Math.max(0, Math.ceil(((license.expiresAt ?? now) - now) / DAY_IN_MS));
|
|
165
|
+
const expiringSoon = daysLeft < LICENSE_REMINDER_DAYS;
|
|
166
|
+
return (
|
|
167
|
+
<DetailsTable
|
|
168
|
+
title="Commercial license"
|
|
169
|
+
status={expiringSoon ? { tone: 'warning', label: 'Expires soon' } : { tone: 'success', label: 'Active' }}
|
|
170
|
+
details={[
|
|
171
|
+
{ label: 'Licensed to', value: license.org || '—' },
|
|
172
|
+
{ label: 'License ID', value: license.licenseId || '—', mono: true },
|
|
173
|
+
{ label: 'Issued', value: formatDate(license.issuedAt) },
|
|
174
|
+
{ label: 'Expires', value: formatDate(license.expiresAt) },
|
|
175
|
+
{ label: 'Time left', value: formatDays(daysLeft) },
|
|
176
|
+
]}
|
|
177
|
+
/>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
if ((license.state === 'licensed' || license.state === 'expired') && expired) {
|
|
181
|
+
return (
|
|
182
|
+
<DetailsTable
|
|
183
|
+
title="Commercial license"
|
|
184
|
+
status={{ tone: 'danger', label: 'Expired' }}
|
|
185
|
+
details={[
|
|
186
|
+
{ label: 'Licensed to', value: license.org || '—' },
|
|
187
|
+
{ label: 'License ID', value: license.licenseId || '—', mono: true },
|
|
188
|
+
{ label: 'Issued', value: formatDate(license.issuedAt) },
|
|
189
|
+
{ label: 'Expired', value: formatDate(license.expiresAt) },
|
|
190
|
+
]}
|
|
191
|
+
/>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (license.state === 'invalid') {
|
|
195
|
+
return (
|
|
196
|
+
<DetailsTable
|
|
197
|
+
title="Commercial license"
|
|
198
|
+
status={{ tone: 'warning', label: 'Not verified' }}
|
|
199
|
+
details={[
|
|
200
|
+
{ label: 'File', value: 'license.jwt', mono: true },
|
|
201
|
+
{ label: 'Problem', value: `It could not be verified: ${license.reason}.` },
|
|
202
|
+
]}
|
|
203
|
+
/>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const TrialTable = ({ trialStartedAt, now }: { trialStartedAt?: number; now: number }) => {
|
|
210
|
+
const trial = getTrialStatus(trialStartedAt, now);
|
|
211
|
+
if (!trial) {
|
|
212
|
+
return (
|
|
213
|
+
<DetailsTable
|
|
214
|
+
title="EventCatalog trial"
|
|
215
|
+
status={{ tone: 'neutral', label: 'Not started' }}
|
|
216
|
+
details={[
|
|
217
|
+
{
|
|
218
|
+
label: 'Start date',
|
|
219
|
+
value: 'No trial start date (tsd) in eventcatalog.config.js.',
|
|
220
|
+
},
|
|
221
|
+
]}
|
|
222
|
+
/>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
const startedAt = trial.endsAt.getTime() - TRIAL_LENGTH_DAYS * DAY_IN_MS;
|
|
226
|
+
return (
|
|
227
|
+
<DetailsTable
|
|
228
|
+
title="EventCatalog trial"
|
|
229
|
+
status={trial.ended ? { tone: 'warning', label: 'Ended' } : { tone: 'info', label: 'Active' }}
|
|
230
|
+
details={[
|
|
231
|
+
{ label: 'Length', value: formatDays(TRIAL_LENGTH_DAYS) },
|
|
232
|
+
{ label: 'Started', value: formatDate(startedAt) },
|
|
233
|
+
{ label: trial.ended ? 'Ended' : 'Ends', value: formatDate(trial.endsAt) },
|
|
234
|
+
...(trial.ended ? [] : [{ label: 'Time left', value: formatDays(trial.daysLeft) }]),
|
|
235
|
+
]}
|
|
236
|
+
/>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
interface Props {
|
|
241
|
+
license: LicenseProps;
|
|
242
|
+
/** The trial start date (`tsd` in eventcatalog.config.js), unix ms */
|
|
243
|
+
trialStartedAt?: number;
|
|
244
|
+
/** When the page was rendered, unix ms: the first render matches the server's, then it counts from now */
|
|
245
|
+
renderedAt: number;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const LicenseSettings = ({ license, trialStartedAt, renderedAt }: Props) => {
|
|
249
|
+
const [now, setNow] = useState(renderedAt);
|
|
250
|
+
useEffect(() => setNow(Date.now()), []);
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<div className="divide-y divide-[rgb(var(--ec-page-border))]">
|
|
254
|
+
<Row
|
|
255
|
+
title="License"
|
|
256
|
+
description="EventCatalog is licensed under the Business Source License 1.1. Your license is read from the license.jwt file in the root of your catalog."
|
|
257
|
+
canEdit={false}
|
|
258
|
+
dirty={false}
|
|
259
|
+
>
|
|
260
|
+
<div className="space-y-4">
|
|
261
|
+
<LicenseTable license={license} now={now} />
|
|
262
|
+
<LicenseNotice license={license} now={now} />
|
|
263
|
+
{/* The trial applies until there's a valid license or plan */}
|
|
264
|
+
{license.state !== 'plan' && (license.state !== 'licensed' || isExpired(license, now)) && (
|
|
265
|
+
<TrialTable trialStartedAt={trialStartedAt} now={now} />
|
|
266
|
+
)}
|
|
267
|
+
</div>
|
|
268
|
+
</Row>
|
|
269
|
+
|
|
270
|
+
<Row
|
|
271
|
+
title="Learn more"
|
|
272
|
+
description="Who can use EventCatalog for free, and when you need a commercial license."
|
|
273
|
+
canEdit={false}
|
|
274
|
+
dirty={false}
|
|
275
|
+
>
|
|
276
|
+
<a
|
|
277
|
+
href={LICENSE_FAQ_URL}
|
|
278
|
+
target="_blank"
|
|
279
|
+
rel="noreferrer"
|
|
280
|
+
className="inline-flex items-center gap-1.5 rounded-md bg-[rgb(var(--ec-page-text))] px-4 py-2 text-[13px] font-medium text-[rgb(var(--ec-page-bg))] shadow-sm transition-opacity hover:opacity-85"
|
|
281
|
+
>
|
|
282
|
+
Read the license FAQ
|
|
283
|
+
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden />
|
|
284
|
+
</a>
|
|
285
|
+
</Row>
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
};
|
|
@@ -4,27 +4,18 @@ import { Bot, FileText } from 'lucide-react';
|
|
|
4
4
|
import { aiSettingsSchema } from '@utils/eventcatalog-config/config-schema';
|
|
5
5
|
import { ReadOnlyBanner } from './ReadOnlyBanner';
|
|
6
6
|
import { Row } from './Row';
|
|
7
|
-
import { ToggleRow,
|
|
7
|
+
import { ToggleRow, UrlPanel } from './SettingsShared';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
canEdit: boolean;
|
|
11
11
|
initial: { llmsTxtEnabled: boolean; chatEnabled: boolean };
|
|
12
|
-
hasScalePlan: boolean;
|
|
13
12
|
apiBase: string;
|
|
14
13
|
llmsTxtUrl: string;
|
|
15
14
|
llmsFullTxtUrl: string;
|
|
16
15
|
schemasTxtUrl: string;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
export const LlmAccessSettingsForm = ({
|
|
20
|
-
canEdit,
|
|
21
|
-
initial,
|
|
22
|
-
hasScalePlan,
|
|
23
|
-
apiBase,
|
|
24
|
-
llmsTxtUrl,
|
|
25
|
-
llmsFullTxtUrl,
|
|
26
|
-
schemasTxtUrl,
|
|
27
|
-
}: Props) => {
|
|
18
|
+
export const LlmAccessSettingsForm = ({ canEdit, initial, apiBase, llmsTxtUrl, llmsFullTxtUrl, schemasTxtUrl }: Props) => {
|
|
28
19
|
const [llmsTxtEnabled, setLlmsTxtEnabled] = useState(initial.llmsTxtEnabled);
|
|
29
20
|
const [pristine, setPristine] = useState(initial.llmsTxtEnabled);
|
|
30
21
|
const [saving, setSaving] = useState(false);
|
|
@@ -108,14 +99,7 @@ export const LlmAccessSettingsForm = ({
|
|
|
108
99
|
canEdit={false}
|
|
109
100
|
dirty={false}
|
|
110
101
|
>
|
|
111
|
-
{
|
|
112
|
-
<SchemasTxtAvailable url={schemasTxtUrl} />
|
|
113
|
-
) : (
|
|
114
|
-
<UpgradeRequired
|
|
115
|
-
tier="Scale"
|
|
116
|
-
blurb="The schema index is a Scale-plan feature. Upgrade to publish a machine-readable catalogue of your schemas alongside llms.txt."
|
|
117
|
-
/>
|
|
118
|
-
)}
|
|
102
|
+
<SchemasTxtAvailable url={schemasTxtUrl} />
|
|
119
103
|
</Row>
|
|
120
104
|
</form>
|
|
121
105
|
);
|