@eventcatalog/core 5.0.0-beta.9 → 5.0.1
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 +13 -12
- package/README.md +5 -5
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +91 -44
- package/dist/analytics/log-build.d.cts +2 -2
- package/dist/analytics/log-build.d.ts +2 -2
- package/dist/analytics/log-build.js +6 -5
- package/dist/analytics/studio-usage.cjs +90 -0
- package/dist/analytics/studio-usage.d.cts +5 -0
- package/dist/analytics/studio-usage.d.ts +5 -0
- package/dist/analytics/studio-usage.js +10 -0
- package/dist/catalog-runtime.cjs +1 -1
- package/dist/{chunk-ZEY2XUJN.js → chunk-46TBJZC3.js} +1 -1
- package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
- package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
- package/dist/chunk-CA6WCQ2T.js +54 -0
- package/dist/{chunk-GAHKCOQM.js → chunk-DVHJTQWQ.js} +1 -1
- package/dist/{chunk-TZVDMWQX.js → chunk-HFR5OPHV.js} +4 -2
- package/dist/{chunk-4CFZUHGG.js → chunk-KTXSCPEK.js} +1 -1
- package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
- package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
- package/dist/chunk-S5GWAUG5.js +29 -0
- package/dist/{chunk-EUNQJO3J.js → chunk-UWAXRTAJ.js} +1 -1
- package/dist/{chunk-JQMYHZWI.js → chunk-YPWK5ITM.js} +15 -7
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +57 -7
- package/dist/docs/development/00-why-eventcatalog.md +11 -11
- package/dist/docs/development/01-fundamentals.md +20 -13
- package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
- package/dist/docs/development/01-getting-started/installation.md +9 -1
- package/dist/docs/development/_getting-started.mdx +1 -1
- package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
- package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
- package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
- package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
- package/dist/docs/development/authentication/01-introduction.md +2 -23
- package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
- package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
- package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
- package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
- package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
- package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
- package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
- package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
- package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
- package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
- package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
- package/dist/docs/development/components/components/11-flow.md +17 -0
- package/dist/docs/development/components/components/15-nodegraph.md +43 -10
- package/dist/docs/development/components/components/18-remote-schema.md +1 -4
- package/dist/docs/development/components/custom-components/07-reference.md +14 -0
- package/dist/docs/development/customization/02-themes.md +0 -5
- package/dist/docs/development/customization/03-search.md +1 -1
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
- package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
- package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
- package/dist/docs/development/deployment/hosting-options.md +7 -2
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
- package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
- package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
- package/dist/docs/development/guides/97-architecture-graph.md +1 -1
- package/dist/docs/development/guides/99-adding-analytics.md +0 -7
- package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
- package/dist/docs/development/guides/domains/09-reference.md +4 -4
- package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
- package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
- package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
- package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
- package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
- package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
- package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
- package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
- package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
- package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
- package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
- package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
- package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
- package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
- package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
- package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
- package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
- package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
- package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
- package/dist/docs/development/guides/systems/01-introduction.md +1 -1
- package/dist/docs/development/guides/systems/02-create-system.md +2 -2
- package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
- package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
- package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
- package/dist/docs/development/guides/systems/06-reference.md +4 -4
- package/dist/docs/development/license/01-license-file.md +151 -0
- package/dist/docs/development/license/_category_.json +12 -0
- package/dist/docs/development/license-keys/_category_.json +3 -3
- package/dist/docs/development/license-keys/integrations.md +7 -37
- package/dist/docs/development/license-keys/license-validation.md +4 -0
- package/dist/docs/development/license-keys/overview.md +5 -1
- package/dist/docs/development/license-keys/plans.md +4 -2
- package/dist/docs/development/studio/01-introduction.md +60 -0
- package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
- package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
- package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
- package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
- package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
- package/dist/docs/development/studio/07-reference.md +294 -0
- package/dist/docs/development/studio/_category_.json +12 -0
- package/dist/docs/development/upgrading/v5.md +345 -0
- package/dist/docs/federation/00-overview.md +2 -8
- package/dist/docs/federation/01-first-federation.md +6 -18
- package/dist/docs/federation/explanation/how-it-works.md +0 -4
- package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
- package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
- package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
- package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
- package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
- package/dist/docs/federation/how-to/run-in-ci.md +2 -9
- package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
- package/dist/docs/federation/how-to/use-local-sources.md +0 -4
- package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
- package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
- package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
- package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
- package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
- package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
- package/dist/docs/federation/reference/cli.md +2 -8
- package/dist/docs/federation/reference/configuration.md +0 -4
- package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
- package/dist/docs/federation/reference/generated-output.md +0 -4
- package/dist/docs/federation/reference/supported-content.md +0 -4
- package/dist/docs/federation/reference/troubleshooting.md +0 -14
- package/dist/docs/plugins/02-generators.md +1 -1
- package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
- package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
- package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
- package/dist/docs/plugins/apicurio/00-intro.md +2 -31
- package/dist/docs/plugins/apicurio/01-installation.md +2 -26
- package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
- package/dist/docs/plugins/apicurio/03-features.md +1 -3
- package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
- package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
- package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
- package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
- package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
- package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
- package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
- package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
- package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
- package/dist/docs/plugins/backstage/00-overview.md +1 -7
- package/dist/docs/plugins/backstage/01-get-started.md +6 -15
- package/dist/docs/plugins/backstage/06-configuration.md +2 -8
- package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
- package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
- package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
- package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
- package/dist/docs/plugins/eventbridge/03-api.md +2 -20
- package/dist/docs/plugins/github/00-intro.md +0 -31
- package/dist/docs/plugins/github/01-installation.md +2 -34
- package/dist/docs/plugins/graphql/00-intro.md +0 -30
- package/dist/docs/plugins/graphql/01-installation.md +1 -53
- package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
- package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
- package/dist/docs/plugins/openapi/00-intro.md +0 -30
- package/dist/docs/plugins/openapi/01-installation.md +1 -57
- package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
- package/dist/docs/plugins/openapi/03-features.md +0 -4
- package/dist/eventcatalog-config-file-utils.cjs +34 -41
- package/dist/eventcatalog-config-file-utils.d.cts +56 -58
- package/dist/eventcatalog-config-file-utils.d.ts +56 -58
- package/dist/eventcatalog-config-file-utils.js +1 -1
- package/dist/eventcatalog.cjs +340 -249
- package/dist/eventcatalog.config.d.cts +18 -15
- package/dist/eventcatalog.config.d.ts +18 -15
- package/dist/eventcatalog.js +46 -28
- package/dist/features.cjs +36 -49
- package/dist/features.d.cts +1 -3
- package/dist/features.d.ts +1 -3
- package/dist/features.js +4 -6
- package/dist/federation/federate.cjs +37 -44
- package/dist/federation/federate.js +2 -2
- package/dist/generate.cjs +37 -42
- package/dist/generate.js +4 -4
- package/dist/resolve-catalog-dependencies.cjs +34 -41
- package/dist/resolve-catalog-dependencies.js +2 -2
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
- package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +5 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
- package/dist/utils/child-process-signals.cjs +53 -0
- package/dist/utils/child-process-signals.d.cts +19 -0
- package/dist/utils/child-process-signals.d.ts +19 -0
- package/dist/utils/child-process-signals.js +6 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +11 -4
- package/dist/utils/license-status.d.cts +3 -2
- package/dist/utils/license-status.d.ts +3 -2
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/astro.config.mjs +21 -1
- package/eventcatalog/integrations/config-loader.mjs +56 -58
- package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
- package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
- package/eventcatalog/integrations/storage.mjs +20 -0
- package/eventcatalog/integrations/studio-server.mjs +4 -1
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
- package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
- package/eventcatalog/src/components/NavigationProgress.astro +7 -0
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
- package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
- package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
- package/eventcatalog/src/components/Search/search-utils.ts +26 -0
- package/eventcatalog/src/components/Seo.astro +5 -1
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
- package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
- package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
- package/eventcatalog/src/components/Settings/Row.tsx +7 -4
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
- package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
- package/eventcatalog/src/components/TrialBadge.astro +20 -9
- package/eventcatalog/src/content.config.ts +19 -2
- package/eventcatalog/src/features/auth/error.astro +4 -2
- package/eventcatalog/src/features/auth/login.astro +2 -1
- package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
- package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
- package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
- package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
- package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
- package/eventcatalog/src/features/server/start.ts +25 -0
- package/eventcatalog/src/features/storage/database.ts +88 -0
- package/eventcatalog/src/features/storage/migrations.ts +85 -0
- package/eventcatalog/src/features/storage/sql/database.sql +5 -0
- package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
- package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
- package/eventcatalog/src/features/storage/sql.ts +28 -0
- package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
- package/eventcatalog/src/features/studio/agents.ts +28 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
- package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
- package/eventcatalog/src/features/studio/api/client.ts +40 -0
- package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
- package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
- package/eventcatalog/src/features/studio/catalog.ts +16 -14
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
- package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
- package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
- package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
- package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
- package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
- package/eventcatalog/src/features/studio/document-name.ts +7 -0
- package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
- package/eventcatalog/src/features/studio/identity.ts +25 -1
- package/eventcatalog/src/features/studio/limits.ts +2 -0
- package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
- package/eventcatalog/src/features/studio/pages/index.astro +596 -373
- package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
- package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
- package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
- package/eventcatalog/src/features/studio/server/storage.ts +53 -73
- package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
- package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
- package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
- package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
- package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
- package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
- package/eventcatalog/src/pages/_index.astro +5 -342
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
- package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
- package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/index.astro +4 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
- package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
- package/eventcatalog/src/pages/settings/license.astro +9 -1
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
- package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
- package/eventcatalog/src/utils/collections/flows.ts +20 -7
- package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
- package/eventcatalog/src/utils/collections/resources.ts +2 -0
- package/eventcatalog/src/utils/collections/util.ts +8 -4
- package/eventcatalog/src/utils/git.ts +11 -0
- package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
- package/eventcatalog/src/utils/license.ts +1 -1
- package/eventcatalog/src/utils/link-validation.ts +25 -19
- package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
- package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
- package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
- package/eventcatalog/src/utils/page-title.ts +15 -0
- package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
- package/eventcatalog/src/utils/trial.ts +13 -0
- package/package.json +12 -12
- package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
- package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
- package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
- package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
- package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
- package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
- package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
- package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
- package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
- package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
- package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
- package/eventcatalog/src/features/studio/clipboard.ts +0 -97
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
- package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
- package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
- package/eventcatalog/src/features/studio/components/icons.ts +0 -53
- package/eventcatalog/src/features/studio/components/status.ts +0 -51
- package/eventcatalog/src/features/studio/edges.ts +0 -56
- package/eventcatalog/src/features/studio/flow-state.ts +0 -92
- package/eventcatalog/src/features/studio/grouping.ts +0 -226
- package/eventcatalog/src/features/studio/layout.ts +0 -42
- package/eventcatalog/src/features/studio/levels.ts +0 -282
- package/eventcatalog/src/features/studio/node-types.ts +0 -205
- package/eventcatalog/src/features/studio/pages/new.astro +0 -24
- package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
- package/eventcatalog/src/features/studio/placement.ts +0 -197
- package/eventcatalog/src/features/studio/studio.css +0 -273
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import { createContext, memo, useCallback, useContext, useRef, useState } from 'react';
|
|
2
|
-
import { NodeResizeControl, NodeResizer, ResizeControlVariant, useStoreApi, type NodeProps, type NodeTypes } from '@xyflow/react';
|
|
3
|
-
import { DomainCardNode, nodeComponents, SystemGroupNode } from '@eventcatalog/visualiser';
|
|
4
|
-
import { GROUP_PADDING } from '../grouping';
|
|
5
|
-
import { getNodeName, GROUP_TYPES, nodeDefinitions } from '../node-types';
|
|
6
|
-
|
|
7
|
-
/** How the canvas draws each kind of node: the visualiser's nodes, notes and text written on the canvas, and resizable containers */
|
|
8
|
-
|
|
9
|
-
export type UpdateNodeData = (id: string, updater: (data: Record<string, unknown>) => Record<string, unknown>) => void;
|
|
10
|
-
|
|
11
|
-
// Notes are edited in place, so their callbacks need to reach the shared design
|
|
12
|
-
export const UpdateNodeDataContext = createContext<UpdateNodeData>(() => {});
|
|
13
|
-
|
|
14
|
-
// Which container something dragged would drop into, to highlight it
|
|
15
|
-
export const DropTargetContext = createContext<string | null>(null);
|
|
16
|
-
|
|
17
|
-
// The visualiser types its node components' props as nodes (Node<Data>) rather than React Flow's NodeProps, so
|
|
18
|
-
// they don't type-check as NodeTypes, though that's what React Flow renders them with
|
|
19
|
-
const visualiserNodes = nodeComponents as unknown as NodeTypes;
|
|
20
|
-
const SystemGroupComponent: NodeTypes[string] = SystemGroupNode;
|
|
21
|
-
|
|
22
|
-
/** The handles that set a node's width, on either side (its height follows what's written in it) */
|
|
23
|
-
function WidthHandles() {
|
|
24
|
-
return (
|
|
25
|
-
<>
|
|
26
|
-
{/* Horizontal only: otherwise React Flow saves the height too, and it stops growing with what's written */}
|
|
27
|
-
<NodeResizeControl
|
|
28
|
-
position="left"
|
|
29
|
-
variant={ResizeControlVariant.Line}
|
|
30
|
-
resizeDirection="horizontal"
|
|
31
|
-
minWidth={80}
|
|
32
|
-
className="studio-width-handle"
|
|
33
|
-
/>
|
|
34
|
-
<NodeResizeControl
|
|
35
|
-
position="right"
|
|
36
|
-
variant={ResizeControlVariant.Line}
|
|
37
|
-
resizeDirection="horizontal"
|
|
38
|
-
minWidth={80}
|
|
39
|
-
className="studio-width-handle"
|
|
40
|
-
/>
|
|
41
|
-
</>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* What's written on a note or text, and writing it: Enter starts a new line, Escape or ⌘/Ctrl + Enter (or clicking
|
|
47
|
-
* away) finishes, and it's saved for everyone then
|
|
48
|
-
*/
|
|
49
|
-
function Writing({
|
|
50
|
-
id,
|
|
51
|
-
text,
|
|
52
|
-
editing,
|
|
53
|
-
onDone,
|
|
54
|
-
placeholder,
|
|
55
|
-
className,
|
|
56
|
-
}: {
|
|
57
|
-
id: string;
|
|
58
|
-
text: string;
|
|
59
|
-
editing: boolean;
|
|
60
|
-
onDone: () => void;
|
|
61
|
-
placeholder: string;
|
|
62
|
-
className: string;
|
|
63
|
-
}) {
|
|
64
|
-
const updateNodeData = useContext(UpdateNodeDataContext);
|
|
65
|
-
// The box grows with what's written (the node's height follows it)
|
|
66
|
-
const fit = (area: HTMLTextAreaElement) => {
|
|
67
|
-
area.style.height = 'auto';
|
|
68
|
-
area.style.height = `${area.scrollHeight}px`;
|
|
69
|
-
};
|
|
70
|
-
if (!editing) return <p className={className}>{text || <span className="opacity-50">{placeholder}</span>}</p>;
|
|
71
|
-
return (
|
|
72
|
-
<textarea
|
|
73
|
-
ref={(area) => {
|
|
74
|
-
if (area) fit(area);
|
|
75
|
-
}}
|
|
76
|
-
autoFocus
|
|
77
|
-
defaultValue={text}
|
|
78
|
-
placeholder={placeholder}
|
|
79
|
-
onFocus={(event) => event.currentTarget.select()}
|
|
80
|
-
onInput={(event) => fit(event.currentTarget)}
|
|
81
|
-
onBlur={(event) => {
|
|
82
|
-
const value = event.currentTarget.value;
|
|
83
|
-
onDone();
|
|
84
|
-
if (value !== text) updateNodeData(id, (current) => ({ ...current, text: value }));
|
|
85
|
-
}}
|
|
86
|
-
onKeyDown={(event) => {
|
|
87
|
-
if (event.key === 'Escape' || (event.key === 'Enter' && (event.metaKey || event.ctrlKey))) event.currentTarget.blur();
|
|
88
|
-
}}
|
|
89
|
-
className={`nodrag nopan nowheel block w-full resize-none overflow-hidden bg-transparent outline-none ${className}`}
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** A sticky note's colours: soft paper colours, readable in light and dark themes (the names are the visualiser's) */
|
|
95
|
-
const NOTE_COLORS: Record<string, { fill: string; border: string }> = {
|
|
96
|
-
yellow: { fill: '#fef9c3', border: '#fde047' },
|
|
97
|
-
blue: { fill: '#dbeafe', border: '#93c5fd' },
|
|
98
|
-
green: { fill: '#dcfce7', border: '#86efac' },
|
|
99
|
-
pink: { fill: '#fce7f3', border: '#f9a8d4' },
|
|
100
|
-
purple: { fill: '#ede9fe', border: '#c4b5fd' },
|
|
101
|
-
gray: { fill: '#f3f4f6', border: '#d1d5db' },
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* A sticky note: a few lines on paper, about as wide as a card and as tall as what's on it. Double click it to
|
|
106
|
-
* write; when it's selected, its colour can be changed and its width set.
|
|
107
|
-
*/
|
|
108
|
-
const StickyNote = memo(function StickyNote({ id, data, selected }: NodeProps) {
|
|
109
|
-
const updateNodeData = useContext(UpdateNodeDataContext);
|
|
110
|
-
const [editing, setEditing] = useState(false);
|
|
111
|
-
const colorName = typeof data.color === 'string' && NOTE_COLORS[data.color] ? data.color : 'yellow';
|
|
112
|
-
const color = NOTE_COLORS[colorName];
|
|
113
|
-
return (
|
|
114
|
-
<div
|
|
115
|
-
className="studio-note"
|
|
116
|
-
style={{ background: color.fill, borderColor: color.border }}
|
|
117
|
-
onDoubleClick={() => setEditing(true)}
|
|
118
|
-
>
|
|
119
|
-
{selected && !editing && (
|
|
120
|
-
<>
|
|
121
|
-
<WidthHandles />
|
|
122
|
-
<div className="nodrag nopan studio-note-colors" role="radiogroup" aria-label="Note colour">
|
|
123
|
-
{Object.entries(NOTE_COLORS).map(([name, { fill, border }]) => (
|
|
124
|
-
<button
|
|
125
|
-
key={name}
|
|
126
|
-
role="radio"
|
|
127
|
-
aria-checked={name === colorName}
|
|
128
|
-
title={name.charAt(0).toUpperCase() + name.slice(1)}
|
|
129
|
-
onClick={() => updateNodeData(id, (current) => ({ ...current, color: name }))}
|
|
130
|
-
className="studio-note-color"
|
|
131
|
-
style={{ background: fill, borderColor: name === colorName ? 'rgb(var(--ec-page-text))' : border }}
|
|
132
|
-
/>
|
|
133
|
-
))}
|
|
134
|
-
</div>
|
|
135
|
-
</>
|
|
136
|
-
)}
|
|
137
|
-
<Writing
|
|
138
|
-
id={id}
|
|
139
|
-
text={String(data.text ?? '')}
|
|
140
|
-
editing={editing}
|
|
141
|
-
onDone={() => setEditing(false)}
|
|
142
|
-
placeholder="Double-click to write a note"
|
|
143
|
-
className="studio-note-body"
|
|
144
|
-
/>
|
|
145
|
-
</div>
|
|
146
|
-
);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Text written straight on the canvas (titles, labels, notes to self): double click it to write. Its width is set
|
|
151
|
-
* with the handles on either side; its height follows what's written.
|
|
152
|
-
*/
|
|
153
|
-
const TextNode = memo(function TextNode({ id, data, selected }: NodeProps) {
|
|
154
|
-
const [editing, setEditing] = useState(false);
|
|
155
|
-
return (
|
|
156
|
-
<div className="studio-text" onDoubleClick={() => setEditing(true)}>
|
|
157
|
-
{selected && !editing && <WidthHandles />}
|
|
158
|
-
<Writing
|
|
159
|
-
id={id}
|
|
160
|
-
text={String(data.text ?? '')}
|
|
161
|
-
editing={editing}
|
|
162
|
-
onDone={() => setEditing(false)}
|
|
163
|
-
placeholder="Double-click to write"
|
|
164
|
-
className="studio-text-body"
|
|
165
|
-
/>
|
|
166
|
-
</div>
|
|
167
|
-
);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* A domain or system as a container: resizable when selected, highlighted when something's dragged over it.
|
|
172
|
-
* Like frames in design tools, it's moved and selected by its header, and dragging inside it draws a selection
|
|
173
|
-
* box (its body lets the pointer through to the canvas: see studio.css).
|
|
174
|
-
*/
|
|
175
|
-
const GroupNode = memo(function GroupNode(props: NodeProps) {
|
|
176
|
-
const isDropTarget = useContext(DropTargetContext) === props.id;
|
|
177
|
-
const store = useStoreApi();
|
|
178
|
-
// Where what's inside has to stay (with room around it and for the header), in the container's parent's
|
|
179
|
-
// coordinates: found when a resize starts, so it can't be resized smaller than what's in it
|
|
180
|
-
const contents = useRef<{ left: number; top: number; right: number; bottom: number } | null>(null);
|
|
181
|
-
const onResizeStart = useCallback(() => {
|
|
182
|
-
const { nodeLookup } = store.getState();
|
|
183
|
-
const container = nodeLookup.get(props.id);
|
|
184
|
-
const children = [...nodeLookup.values()].filter((node) => node.parentId === props.id);
|
|
185
|
-
if (!container || children.length === 0) {
|
|
186
|
-
contents.current = null;
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
const { x, y } = container.position;
|
|
190
|
-
const size = (node: (typeof children)[number]) => ({
|
|
191
|
-
width: node.measured.width ?? node.width ?? 0,
|
|
192
|
-
height: node.measured.height ?? node.height ?? 0,
|
|
193
|
-
});
|
|
194
|
-
const own = size(container);
|
|
195
|
-
// A side already closer in than that (e.g. something placed in the padding) can still move out, just not in
|
|
196
|
-
contents.current = {
|
|
197
|
-
left: Math.max(x + Math.min(...children.map((node) => node.position.x)) - GROUP_PADDING.left, x),
|
|
198
|
-
top: Math.max(y + Math.min(...children.map((node) => node.position.y)) - GROUP_PADDING.top, y),
|
|
199
|
-
right: Math.min(
|
|
200
|
-
x + Math.max(...children.map((node) => node.position.x + size(node).width)) + GROUP_PADDING.right,
|
|
201
|
-
x + own.width
|
|
202
|
-
),
|
|
203
|
-
bottom: Math.min(
|
|
204
|
-
y + Math.max(...children.map((node) => node.position.y + size(node).height)) + GROUP_PADDING.bottom,
|
|
205
|
-
y + own.height
|
|
206
|
-
),
|
|
207
|
-
};
|
|
208
|
-
}, [store, props.id]);
|
|
209
|
-
const shouldResize = useCallback(
|
|
210
|
-
(_: unknown, { x, y, width, height }: { x: number; y: number; width: number; height: number }) => {
|
|
211
|
-
const bounds = contents.current;
|
|
212
|
-
return !bounds || (x <= bounds.left && y <= bounds.top && x + width >= bounds.right && y + height >= bounds.bottom);
|
|
213
|
-
},
|
|
214
|
-
[]
|
|
215
|
-
);
|
|
216
|
-
return (
|
|
217
|
-
<div style={{ width: '100%', height: '100%', position: 'relative' }}>
|
|
218
|
-
<NodeResizer
|
|
219
|
-
isVisible={props.selected}
|
|
220
|
-
onResizeStart={onResizeStart}
|
|
221
|
-
shouldResize={shouldResize}
|
|
222
|
-
minWidth={240}
|
|
223
|
-
minHeight={160}
|
|
224
|
-
lineClassName="!border-[rgb(var(--ec-accent))]"
|
|
225
|
-
handleClassName="!h-2.5 !w-2.5 !rounded-sm !border-2 !bg-[rgb(var(--ec-card-bg))] !border-[rgb(var(--ec-accent))]"
|
|
226
|
-
/>
|
|
227
|
-
<SystemGroupComponent {...props} />
|
|
228
|
-
{/* The header (and the badge on its border) */}
|
|
229
|
-
<div className="ec-group-grip absolute inset-x-0 -top-3 h-[60px] cursor-grab" />
|
|
230
|
-
{isDropTarget ? (
|
|
231
|
-
// What's dragged over it goes in it when it's dropped
|
|
232
|
-
<div className="ec-drop-target">
|
|
233
|
-
<span className="ec-drop-target-label">Drop to add to {getNodeName(props.type, props.data, 'this container')}</span>
|
|
234
|
-
</div>
|
|
235
|
-
) : (
|
|
236
|
-
props.selected && <div className="ec-group-selected" />
|
|
237
|
-
)}
|
|
238
|
-
</div>
|
|
239
|
-
);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
export const nodeTypes: NodeTypes = {
|
|
243
|
-
...Object.fromEntries(
|
|
244
|
-
nodeDefinitions.map((definition) => [
|
|
245
|
-
definition.type,
|
|
246
|
-
definition.type === 'note' ? StickyNote : definition.type === 'text' ? TextNode : visualiserNodes[definition.type],
|
|
247
|
-
])
|
|
248
|
-
),
|
|
249
|
-
// Only dropped in from the catalog
|
|
250
|
-
system: visualiserNodes.system,
|
|
251
|
-
'context-domain': DomainCardNode,
|
|
252
|
-
// Domains and systems as containers
|
|
253
|
-
[GROUP_TYPES.domain]: GroupNode,
|
|
254
|
-
[GROUP_TYPES.system]: GroupNode,
|
|
255
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { LucideIcon } from 'lucide-react';
|
|
2
|
-
import {
|
|
3
|
-
ArrowRightLeft,
|
|
4
|
-
Bot,
|
|
5
|
-
Boxes,
|
|
6
|
-
Database,
|
|
7
|
-
Globe,
|
|
8
|
-
Group,
|
|
9
|
-
Mail,
|
|
10
|
-
MonitorSmartphone,
|
|
11
|
-
Search,
|
|
12
|
-
ServerIcon,
|
|
13
|
-
StickyNote,
|
|
14
|
-
Type,
|
|
15
|
-
User,
|
|
16
|
-
Zap,
|
|
17
|
-
} from 'lucide-react';
|
|
18
|
-
import { GROUP_TYPES } from '../node-types';
|
|
19
|
-
|
|
20
|
-
/** How each kind of node, and each catalog collection, looks in the canvas's lists (the colours are each kind's own) */
|
|
21
|
-
export type NodeIcon = { icon: LucideIcon; className: string };
|
|
22
|
-
|
|
23
|
-
export const NODE_ICONS: Record<string, NodeIcon> = {
|
|
24
|
-
[GROUP_TYPES.domain]: { icon: Boxes, className: 'text-yellow-500' },
|
|
25
|
-
[GROUP_TYPES.system]: { icon: Group, className: 'text-violet-600' },
|
|
26
|
-
// Catalog domains and systems added as cards
|
|
27
|
-
'context-domain': { icon: Boxes, className: 'text-yellow-500' },
|
|
28
|
-
system: { icon: Group, className: 'text-violet-600' },
|
|
29
|
-
service: { icon: ServerIcon, className: 'text-pink-600' },
|
|
30
|
-
event: { icon: Zap, className: 'text-orange-600' },
|
|
31
|
-
command: { icon: Mail, className: 'text-blue-600' },
|
|
32
|
-
query: { icon: Search, className: 'text-green-600' },
|
|
33
|
-
channel: { icon: ArrowRightLeft, className: 'text-gray-600' },
|
|
34
|
-
data: { icon: Database, className: 'text-blue-600' },
|
|
35
|
-
view: { icon: MonitorSmartphone, className: 'text-sky-600' },
|
|
36
|
-
externalSystem: { icon: Globe, className: 'text-purple-600' },
|
|
37
|
-
agent: { icon: Bot, className: 'text-violet-600' },
|
|
38
|
-
actor: { icon: User, className: 'text-sky-600' },
|
|
39
|
-
note: { icon: StickyNote, className: 'text-yellow-500' },
|
|
40
|
-
text: { icon: Type, className: 'text-[rgb(var(--ec-icon-color))]' },
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/** The catalog's collections, in the order the catalog list shows them, with the icon of the node each becomes */
|
|
44
|
-
export const CATALOG_GROUPS: ({ collection: string; label: string } & NodeIcon)[] = [
|
|
45
|
-
{ collection: 'domains', label: 'Domains', ...NODE_ICONS[GROUP_TYPES.domain] },
|
|
46
|
-
{ collection: 'systems', label: 'Systems', ...NODE_ICONS[GROUP_TYPES.system] },
|
|
47
|
-
{ collection: 'services', label: 'Services', ...NODE_ICONS.service },
|
|
48
|
-
{ collection: 'events', label: 'Events', ...NODE_ICONS.event },
|
|
49
|
-
{ collection: 'commands', label: 'Commands', ...NODE_ICONS.command },
|
|
50
|
-
{ collection: 'queries', label: 'Queries', ...NODE_ICONS.query },
|
|
51
|
-
{ collection: 'channels', label: 'Channels', ...NODE_ICONS.channel },
|
|
52
|
-
{ collection: 'containers', label: 'Data Stores', ...NODE_ICONS.data },
|
|
53
|
-
];
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { CanvasStatus } from '../canvas-doc';
|
|
2
|
-
import type { Status } from '../hooks/use-studio-flow';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Status and destructive colours for the canvas, from the theme's badge colours (EventCatalog has no status
|
|
6
|
-
* variables), so they follow light, dark and custom themes. Kept here rather than repeated in each component.
|
|
7
|
-
*/
|
|
8
|
-
export const STATUS = {
|
|
9
|
-
success: { text: 'text-[rgb(var(--ec-badge-color-green-text))]', dot: 'bg-[rgb(var(--ec-badge-color-green-text))]' },
|
|
10
|
-
warning: { text: 'text-[rgb(var(--ec-badge-color-yellow-text))]', dot: 'bg-[rgb(var(--ec-badge-color-yellow-text))]' },
|
|
11
|
-
danger: {
|
|
12
|
-
text: 'text-[rgb(var(--ec-badge-color-red-text))]',
|
|
13
|
-
dot: 'bg-[rgb(var(--ec-badge-color-red-text))]',
|
|
14
|
-
hover: 'hover:bg-[rgb(var(--ec-badge-color-red-background))]',
|
|
15
|
-
},
|
|
16
|
-
} as const;
|
|
17
|
-
|
|
18
|
-
/** The dot showing whether the canvas is connected */
|
|
19
|
-
export const CONNECTION_DOT: Record<Status, string> = {
|
|
20
|
-
connected: STATUS.success.dot,
|
|
21
|
-
connecting: STATUS.warning.dot,
|
|
22
|
-
disconnected: STATUS.danger.dot,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/** How each canvas status looks and what it means (from the theme's badge colours) */
|
|
26
|
-
export const CANVAS_STATUS_LOOK: Record<CanvasStatus, { label: string; description: string; pill: string; dot: string }> = {
|
|
27
|
-
draft: {
|
|
28
|
-
label: 'Draft',
|
|
29
|
-
description: 'Being worked on',
|
|
30
|
-
pill: 'bg-[rgb(var(--ec-badge-color-gray-background))] text-[rgb(var(--ec-badge-color-gray-text))] border-[rgb(var(--ec-badge-color-gray-text)/0.25)]',
|
|
31
|
-
dot: 'bg-[rgb(var(--ec-badge-color-gray-text))]',
|
|
32
|
-
},
|
|
33
|
-
proposed: {
|
|
34
|
-
label: 'Proposed',
|
|
35
|
-
description: 'Ready for review',
|
|
36
|
-
pill: 'bg-[rgb(var(--ec-badge-color-yellow-background))] text-[rgb(var(--ec-badge-color-yellow-text))] border-[rgb(var(--ec-badge-color-yellow-text)/0.3)]',
|
|
37
|
-
dot: 'bg-[rgb(var(--ec-badge-color-yellow-text))]',
|
|
38
|
-
},
|
|
39
|
-
accepted: {
|
|
40
|
-
label: 'Accepted',
|
|
41
|
-
description: 'The agreed design',
|
|
42
|
-
pill: 'bg-[rgb(var(--ec-badge-color-green-background))] text-[rgb(var(--ec-badge-color-green-text))] border-[rgb(var(--ec-badge-color-green-text)/0.3)]',
|
|
43
|
-
dot: 'bg-[rgb(var(--ec-badge-color-green-text))]',
|
|
44
|
-
},
|
|
45
|
-
rejected: {
|
|
46
|
-
label: 'Rejected',
|
|
47
|
-
description: 'Decided against, kept for the record',
|
|
48
|
-
pill: 'bg-[rgb(var(--ec-badge-color-red-background))] text-[rgb(var(--ec-badge-color-red-text))] border-[rgb(var(--ec-badge-color-red-text)/0.3)]',
|
|
49
|
-
dot: 'bg-[rgb(var(--ec-badge-color-red-text))]',
|
|
50
|
-
},
|
|
51
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { Connection, Edge, EdgeMarker } from '@xyflow/react';
|
|
2
|
-
|
|
3
|
-
/** Connections on a canvas, labelled with EventCatalog's wording (e.g. "publishes event", "subscribed by") */
|
|
4
|
-
|
|
5
|
-
/** Node types that are messages, and their catalog collection */
|
|
6
|
-
export const MESSAGE_COLLECTIONS: Record<string, string> = {
|
|
7
|
-
event: 'events',
|
|
8
|
-
command: 'commands',
|
|
9
|
-
query: 'queries',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const EDGE_COLOR = '#6b7280';
|
|
13
|
-
export const EDGE_MARKER: EdgeMarker = { type: 'arrowclosed', color: EDGE_COLOR, width: 18, height: 18 };
|
|
14
|
-
|
|
15
|
-
const PRODUCERS = ['service', 'agent', 'actor', 'externalSystem', 'view'];
|
|
16
|
-
const PRODUCER_LABELS: Record<string, string> = { commands: 'invokes', events: 'publishes \nevent', queries: 'requests' };
|
|
17
|
-
const MESSAGE_LABELS: Record<string, string> = { commands: 'accepts', events: 'subscribed by', queries: 'accepts' };
|
|
18
|
-
|
|
19
|
-
const getCollection = (sourceType?: string, targetType?: string) =>
|
|
20
|
-
MESSAGE_COLLECTIONS[sourceType ?? ''] ?? MESSAGE_COLLECTIONS[targetType ?? ''];
|
|
21
|
-
|
|
22
|
-
export const getEdgeLabel = (sourceType = '', targetType = ''): string => {
|
|
23
|
-
const sourceCollection = MESSAGE_COLLECTIONS[sourceType];
|
|
24
|
-
const targetCollection = MESSAGE_COLLECTIONS[targetType];
|
|
25
|
-
|
|
26
|
-
if (PRODUCERS.includes(sourceType) && targetCollection) return PRODUCER_LABELS[targetCollection];
|
|
27
|
-
// One message leading to another (e.g. an event that causes a command)
|
|
28
|
-
if (sourceCollection && targetCollection) return 'triggers';
|
|
29
|
-
if (sourceCollection && targetType === 'channel') return 'sent to';
|
|
30
|
-
if (sourceCollection) return MESSAGE_LABELS[sourceCollection];
|
|
31
|
-
if (sourceType === 'channel') return 'routes to';
|
|
32
|
-
if (targetType === 'channel') return 'publishes to';
|
|
33
|
-
if (targetType === 'data') return 'writes to';
|
|
34
|
-
if (sourceType === 'data') return 'read by';
|
|
35
|
-
if (sourceType === 'actor') return 'uses';
|
|
36
|
-
if (targetType === 'view') return 'serves';
|
|
37
|
-
if (targetType === 'externalSystem') return 'calls';
|
|
38
|
-
if (targetType === 'actor') return 'notifies';
|
|
39
|
-
return '';
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/** Message edges get the animated envelope edge from the visualiser, everything else a labelled smooth step edge */
|
|
43
|
-
export const createEdge = (connection: Connection, sourceType?: string, targetType?: string): Edge => {
|
|
44
|
-
const collection = getCollection(sourceType, targetType);
|
|
45
|
-
return {
|
|
46
|
-
id: `edge-${crypto.randomUUID().slice(0, 8)}`,
|
|
47
|
-
source: connection.source,
|
|
48
|
-
target: connection.target,
|
|
49
|
-
sourceHandle: connection.sourceHandle ?? null,
|
|
50
|
-
targetHandle: connection.targetHandle ?? null,
|
|
51
|
-
type: collection ? 'animated' : 'smoothstep',
|
|
52
|
-
label: getEdgeLabel(sourceType, targetType),
|
|
53
|
-
markerEnd: EDGE_MARKER,
|
|
54
|
-
data: collection ? { message: { collection } } : {},
|
|
55
|
-
};
|
|
56
|
-
};
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { Edge, Node, XYPosition } from '@xyflow/react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The design (nodes and edges) comes from the shared document; some state stays with each person: what they
|
|
5
|
-
* have selected, what they're dragging and resizing, and the sizes React Flow measured in their browser.
|
|
6
|
-
*/
|
|
7
|
-
export const LOCAL_NODE_KEYS = ['selected', 'dragging', 'resizing', 'measured'] as const satisfies readonly (keyof Node)[];
|
|
8
|
-
export const LOCAL_EDGE_KEYS = ['selected'] as const satisfies readonly (keyof Edge)[];
|
|
9
|
-
|
|
10
|
-
/** A shared item with the local-only state of the one already shown. Nothing else is kept from the local one. */
|
|
11
|
-
export const withLocalState = <T extends object>(shared: T, local: T | undefined, localKeys: readonly (keyof T)[]): T => {
|
|
12
|
-
if (!local) return shared;
|
|
13
|
-
const kept: Partial<T> = {};
|
|
14
|
-
for (const key of localKeys) if (local[key] !== undefined) kept[key] = local[key];
|
|
15
|
-
return { ...shared, ...kept };
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Applies changes to shared items (by id) to the items shown, keeping every unchanged item as the same object
|
|
20
|
-
* (so React Flow doesn't re-render it) and the order they were first seen in (new ones go at the end).
|
|
21
|
-
* `getShared` returns an item's shared value, or undefined if it was deleted. Returns `local` itself when
|
|
22
|
-
* nothing changed.
|
|
23
|
-
*/
|
|
24
|
-
export const patchShared = <T extends { id: string }>(
|
|
25
|
-
local: T[],
|
|
26
|
-
changedIds: Iterable<string>,
|
|
27
|
-
getShared: (id: string) => T | undefined,
|
|
28
|
-
localKeys: readonly (keyof T)[]
|
|
29
|
-
): T[] => {
|
|
30
|
-
const indexById = new Map(local.map((item, index) => [item.id, index]));
|
|
31
|
-
let next: T[] | undefined;
|
|
32
|
-
const removed = new Set<string>();
|
|
33
|
-
const added: T[] = [];
|
|
34
|
-
|
|
35
|
-
for (const id of changedIds) {
|
|
36
|
-
const shared = getShared(id);
|
|
37
|
-
const index = indexById.get(id);
|
|
38
|
-
if (!shared) {
|
|
39
|
-
if (index !== undefined) removed.add(id);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (index === undefined) {
|
|
43
|
-
added.push(shared);
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
next ??= [...local];
|
|
47
|
-
next[index] = withLocalState(shared, local[index], localKeys);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!next && removed.size === 0 && added.length === 0) return local;
|
|
51
|
-
const patched = next ?? local;
|
|
52
|
-
return [...(removed.size ? patched.filter((item) => !removed.has(item.id)) : patched), ...added];
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/** Where nodes being dragged are, by id, until they're dropped (and saved) */
|
|
56
|
-
export type Moves = ReadonlyMap<string, XYPosition>;
|
|
57
|
-
|
|
58
|
-
const samePosition = (a: XYPosition, b: XYPosition) => a.x === b.x && a.y === b.y;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Nodes moved to the positions given (e.g. where someone else is dragging them), except ones being dragged
|
|
62
|
-
* here. Returns `nodes` itself when none move.
|
|
63
|
-
*/
|
|
64
|
-
export const withPositions = (nodes: Node[], positions: Moves): Node[] => {
|
|
65
|
-
if (positions.size === 0) return nodes;
|
|
66
|
-
let next: Node[] | undefined;
|
|
67
|
-
nodes.forEach((node, index) => {
|
|
68
|
-
const position = positions.get(node.id);
|
|
69
|
-
if (!position || node.dragging || samePosition(position, node.position)) return;
|
|
70
|
-
next ??= [...nodes];
|
|
71
|
-
next[index] = { ...node, position };
|
|
72
|
-
});
|
|
73
|
-
return next ?? nodes;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* After shared changes are applied (`next`, from `previous`): nodes being dragged here stay where they're being
|
|
78
|
-
* dragged (when they're dropped, the drop is saved and wins). Returns `next` itself when none are.
|
|
79
|
-
*/
|
|
80
|
-
export const keepDragged = (next: Node[], previous: Node[]): Node[] => {
|
|
81
|
-
if (next === previous) return next;
|
|
82
|
-
const dragged = new Map(previous.filter((node) => node.dragging).map((node) => [node.id, node.position]));
|
|
83
|
-
if (dragged.size === 0) return next;
|
|
84
|
-
let kept: Node[] | undefined;
|
|
85
|
-
next.forEach((node, index) => {
|
|
86
|
-
const position = dragged.get(node.id);
|
|
87
|
-
if (!position || samePosition(position, node.position)) return;
|
|
88
|
-
kept ??= [...next];
|
|
89
|
-
kept[index] = { ...node, position };
|
|
90
|
-
});
|
|
91
|
-
return kept ?? next;
|
|
92
|
-
};
|