@eventcatalog/core 5.0.0-beta.9 → 5.0.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 +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-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-JZN4RSMF.js} +1 -1
- package/dist/{chunk-JQMYHZWI.js → chunk-NEAVAFSJ.js} +16 -8
- package/dist/{chunk-4CFZUHGG.js → chunk-NIVST4WY.js} +1 -1
- package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
- package/dist/{chunk-ZEY2XUJN.js → chunk-OX6TSVHY.js} +6 -6
- package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
- package/dist/{chunk-EUNQJO3J.js → chunk-RE7UTPWH.js} +1 -1
- package/dist/chunk-S5GWAUG5.js +29 -0
- package/dist/{chunk-TZVDMWQX.js → chunk-YQGRMDRB.js} +4 -2
- 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 +51 -33
- 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 +5 -5
- package/dist/federation/source-provider.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 +11 -11
- 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
- package/dist/{chunk-A2RZR3U4.js → chunk-6K7XZAYI.js} +3 -3
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
addNodes,
|
|
17
17
|
buildNode,
|
|
18
|
-
canvasDocumentName,
|
|
19
18
|
connectNodes,
|
|
20
19
|
deleteEdges,
|
|
21
20
|
deleteNodes as deleteNodesInDoc,
|
|
@@ -24,7 +23,9 @@ import {
|
|
|
24
23
|
fitGroupToChildren,
|
|
25
24
|
getCanvasMaps,
|
|
26
25
|
moveNode,
|
|
26
|
+
placeNode,
|
|
27
27
|
changesNodesOrEdges,
|
|
28
|
+
getStructureKey,
|
|
28
29
|
getCanvasStatus,
|
|
29
30
|
readMeta,
|
|
30
31
|
reopenIfDecided,
|
|
@@ -33,16 +34,41 @@ import {
|
|
|
33
34
|
setMeta,
|
|
34
35
|
type Author,
|
|
35
36
|
type CanvasStatus,
|
|
37
|
+
type DiagramLevels,
|
|
38
|
+
type LevelPlace,
|
|
39
|
+
readLevelLayout,
|
|
40
|
+
setLevelPlaces,
|
|
36
41
|
type StatusChange,
|
|
37
|
-
|
|
42
|
+
setNodeParents,
|
|
38
43
|
type RenderedSizes,
|
|
39
44
|
updateNodeData as updateNodeDataInDoc,
|
|
40
|
-
|
|
45
|
+
keepDragged,
|
|
46
|
+
LOCAL_EDGE_KEYS,
|
|
47
|
+
LOCAL_NODE_KEYS,
|
|
48
|
+
patchShared,
|
|
49
|
+
withPositions,
|
|
50
|
+
createSmoother,
|
|
51
|
+
containerFor,
|
|
52
|
+
toRelativePosition,
|
|
53
|
+
type NodePreview,
|
|
54
|
+
type LayoutResult,
|
|
55
|
+
canGoInContainer,
|
|
56
|
+
getNodeDefinition,
|
|
57
|
+
isGroupType,
|
|
58
|
+
createHotspot as createHotspotInDoc,
|
|
59
|
+
updateHotspot as updateHotspotInDoc,
|
|
60
|
+
deleteHotspot as deleteHotspotInDoc,
|
|
61
|
+
readHotspots,
|
|
62
|
+
getLock,
|
|
63
|
+
setLock,
|
|
64
|
+
type Hotspot,
|
|
65
|
+
type Editing,
|
|
66
|
+
addThreads,
|
|
67
|
+
addHotspots,
|
|
68
|
+
type ModelCanvasContent,
|
|
69
|
+
} from '@eventcatalog/visualiser/studio';
|
|
70
|
+
import { CANVAS_DELETED_REASON, canvasDocumentName } from '../document-name';
|
|
41
71
|
import { applyLayout } from '../agent-choreography';
|
|
42
|
-
import { keepDragged, LOCAL_EDGE_KEYS, LOCAL_NODE_KEYS, patchShared, withPositions } from '../flow-state';
|
|
43
|
-
import { findGroupAtPoint, toRelativePosition, type NodePreview } from '../grouping';
|
|
44
|
-
import type { LayoutResult } from '../layout';
|
|
45
|
-
import { canGoInContainer, getNodeDefinition, isGroupType } from '../node-types';
|
|
46
72
|
import { startToolSync, type ToolSync } from '../tool-sync';
|
|
47
73
|
import { createPresenceSender, type PresenceSender } from './presence-sender';
|
|
48
74
|
import { createPresenceStore, type PresenceStore } from './presence-store';
|
|
@@ -66,6 +92,14 @@ const LOCAL_ORIGIN = Symbol('studio-local');
|
|
|
66
92
|
export const BROWSER_AGENT_ORIGIN = Symbol('studio-browser-agent');
|
|
67
93
|
/** Status changes: synced, but not undone (undo takes back edits, not decisions about the canvas) */
|
|
68
94
|
const STATUS_ORIGIN = Symbol('studio-status');
|
|
95
|
+
/** A diagram file opened into a new canvas: what it starts with, synced, not undone (nothing to go back to) */
|
|
96
|
+
const OPEN_ORIGIN = Symbol('studio-open');
|
|
97
|
+
/** Where L1 and L2 put what's new on them, kept so it stays there: synced, not undone (nobody did it) */
|
|
98
|
+
const LEVEL_PLACEMENT_ORIGIN = Symbol('studio-level-placement');
|
|
99
|
+
|
|
100
|
+
const NO_LEVEL_LAYOUTS = { 1: new Map(), 2: new Map() } as const;
|
|
101
|
+
/** What someone changing a note or text shows the others as they change it (see `editing` in their presence) */
|
|
102
|
+
const EDITED_FIELDS = ['text', 'fontSize', 'angle'] as const;
|
|
69
103
|
|
|
70
104
|
export type Status = 'connecting' | 'connected' | 'disconnected';
|
|
71
105
|
export type Transport = 'websocket' | 'tools';
|
|
@@ -89,6 +123,7 @@ export function useStudioFlow({
|
|
|
89
123
|
name,
|
|
90
124
|
color,
|
|
91
125
|
picture,
|
|
126
|
+
agent,
|
|
92
127
|
syncViaTools,
|
|
93
128
|
onLayout,
|
|
94
129
|
onContainerResize,
|
|
@@ -100,6 +135,8 @@ export function useStudioFlow({
|
|
|
100
135
|
color: string;
|
|
101
136
|
/** From your sign-in provider, when you're signed in */
|
|
102
137
|
picture?: string;
|
|
138
|
+
/** You're an AI agent here (e.g. a chat's canvas view, which joins as the chat's agent) */
|
|
139
|
+
agent?: boolean;
|
|
103
140
|
/** Sync through MCP tool calls when the WebSocket can't connect (e.g. inside a chat's sandbox) */
|
|
104
141
|
syncViaTools?: ToolSync;
|
|
105
142
|
/** Someone laid the canvas out (us included): called as the new positions arrive, so they can glide there */
|
|
@@ -120,10 +157,25 @@ export function useStudioFlow({
|
|
|
120
157
|
const [doc, setDoc] = useState<Y.Doc | null>(null);
|
|
121
158
|
const [history, setHistory] = useState({ canUndo: false, canRedo: false });
|
|
122
159
|
const [title, setTitle] = useState<string | undefined>();
|
|
160
|
+
// L1 and L2 of the diagram the canvas was opened from, if it was
|
|
161
|
+
const [diagramLevels, setDiagramLevels] = useState<DiagramLevels | undefined>();
|
|
162
|
+
// What's on the canvas and how it's connected (getStructureKey): worked out when the document's nodes or edges
|
|
163
|
+
// change, which drags don't do (they're in presence until the drop)
|
|
164
|
+
const [structureKey, setStructureKey] = useState('');
|
|
165
|
+
// Where things are on L1 and L2, as people arranged them
|
|
166
|
+
const [levelLayouts, setLevelLayouts] = useState<Record<1 | 2, ReadonlyMap<string, LevelPlace>>>(NO_LEVEL_LAYOUTS);
|
|
123
167
|
const [canvasStatus, setCanvasStatusState] = useState<{ status: CanvasStatus; history: StatusChange[] }>(NEW_CANVAS_STATUS);
|
|
124
168
|
const [transport, setTransport] = useState<Transport>('websocket');
|
|
169
|
+
// Someone deleted the canvas: the server closed it for everyone, and won't open it again
|
|
170
|
+
const [deleted, setDeleted] = useState(false);
|
|
171
|
+
// What's flagged on the canvas (risks, problems, the key parts), on nodes or at places
|
|
172
|
+
const [hotspots, setHotspots] = useState<Hotspot[]>([]);
|
|
173
|
+
// Who locked the canvas (for everyone on it), if it's locked
|
|
174
|
+
const [lockedBy, setLockedBy] = useState<string | null>(null);
|
|
175
|
+
// The server's copy of the canvas has arrived (what's on it is known, e.g. that it's empty)
|
|
176
|
+
const [synced, setSynced] = useState(false);
|
|
125
177
|
const user = useRef<Author>({ name, color });
|
|
126
|
-
user.current = { name, color, ...(picture && { picture }) };
|
|
178
|
+
user.current = { name, color, ...(picture && { picture }), ...(agent && { agent }) };
|
|
127
179
|
const onLayoutRef = useRef(onLayout);
|
|
128
180
|
onLayoutRef.current = onLayout;
|
|
129
181
|
const onContainerResizeRef = useRef(onContainerResize);
|
|
@@ -136,16 +188,41 @@ export function useStudioFlow({
|
|
|
136
188
|
setEdges([]);
|
|
137
189
|
|
|
138
190
|
const doc = new Y.Doc();
|
|
139
|
-
const {
|
|
191
|
+
const {
|
|
192
|
+
nodes: yNodes,
|
|
193
|
+
edges: yEdges,
|
|
194
|
+
threads: yThreads,
|
|
195
|
+
meta: yMeta,
|
|
196
|
+
levelLayouts: yLevelLayouts,
|
|
197
|
+
hotspots: yHotspots,
|
|
198
|
+
} = getCanvasMaps(doc);
|
|
199
|
+
const syncLevelLayouts = (event: Y.YMapEvent<LevelPlace>) => {
|
|
200
|
+
const changed = new Set([...event.keysChanged].map((key) => Number(key.split(':')[0]) as 1 | 2));
|
|
201
|
+
setLevelLayouts((current) => {
|
|
202
|
+
const next = { ...current };
|
|
203
|
+
changed.forEach((level) => (next[level] = readLevelLayout(doc, level)));
|
|
204
|
+
return next;
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
yLevelLayouts.observe(syncLevelLayouts);
|
|
208
|
+
setLevelLayouts(NO_LEVEL_LAYOUTS);
|
|
140
209
|
const syncMeta = (event: Y.YMapEvent<unknown>) => {
|
|
141
210
|
const meta = readMeta(doc);
|
|
142
211
|
setTitle(meta.title);
|
|
212
|
+
if (event.keysChanged.has('diagramLevels')) setDiagramLevels(meta.diagramLevels);
|
|
143
213
|
if (event.keysChanged.has('status') || event.keysChanged.has('statusHistory'))
|
|
144
214
|
setCanvasStatusState({ status: getCanvasStatus(meta), history: meta.statusHistory ?? [] });
|
|
145
215
|
if (event.keysChanged.has('layoutAt')) onLayoutRef.current?.();
|
|
216
|
+
if (event.keysChanged.has('lockedBy')) setLockedBy(getLock(doc));
|
|
146
217
|
};
|
|
147
218
|
yMeta.observe(syncMeta);
|
|
219
|
+
setLockedBy(null);
|
|
220
|
+
const syncHotspots = () => setHotspots(readHotspots(doc));
|
|
221
|
+
yHotspots.observe(syncHotspots);
|
|
222
|
+
setHotspots([]);
|
|
148
223
|
setTitle(undefined);
|
|
224
|
+
setStructureKey('');
|
|
225
|
+
setDiagramLevels(undefined);
|
|
149
226
|
setCanvasStatusState(NEW_CANVAS_STATUS);
|
|
150
227
|
// Changing an accepted (or rejected) canvas here makes it a draft again, for everyone. Changes from others arrive
|
|
151
228
|
// already reopened by whoever made them.
|
|
@@ -166,6 +243,12 @@ export function useStudioFlow({
|
|
|
166
243
|
);
|
|
167
244
|
};
|
|
168
245
|
doc.on('afterTransaction', reopenOnEdit);
|
|
246
|
+
const syncStructure = (transaction: Y.Transaction) => {
|
|
247
|
+
// Drops and resizes here only move and size things (putting something in a container isn't LOCAL_ORIGIN)
|
|
248
|
+
if (transaction.origin !== LOCAL_ORIGIN && changesNodesOrEdges(transaction))
|
|
249
|
+
setStructureKey(getStructureKey(Array.from(yNodes.values()), Array.from(yEdges.values())));
|
|
250
|
+
};
|
|
251
|
+
doc.on('afterTransaction', syncStructure);
|
|
169
252
|
// One presence for whichever connection is used
|
|
170
253
|
const awareness = new Awareness(doc);
|
|
171
254
|
awareness.setLocalStateField('user', user.current);
|
|
@@ -180,6 +263,15 @@ export function useStudioFlow({
|
|
|
180
263
|
let fallback: ReturnType<typeof setTimeout> | undefined;
|
|
181
264
|
// Declared before the provider: it reports its first status while it's being created
|
|
182
265
|
let socketStatus: Status = 'connecting';
|
|
266
|
+
let canvasDeleted = false;
|
|
267
|
+
const onCanvasDeleted = () => {
|
|
268
|
+
canvasDeleted = true;
|
|
269
|
+
clearTimeout(fallback);
|
|
270
|
+
stopToolSync?.();
|
|
271
|
+
provider.disconnect();
|
|
272
|
+
setDeleted(true);
|
|
273
|
+
setStatus('disconnected');
|
|
274
|
+
};
|
|
183
275
|
// Some views can't use the WebSocket (a chat's sandbox may block it, or open it without the person's session):
|
|
184
276
|
// sync through tool calls instead
|
|
185
277
|
const syncThroughTools = () => {
|
|
@@ -201,23 +293,31 @@ export function useStudioFlow({
|
|
|
201
293
|
// Open isn't connected until the server lets us in (onAuthenticated)
|
|
202
294
|
if (!stopToolSync) setStatus(status === 'connected' && !letIn ? 'connecting' : (status as Status));
|
|
203
295
|
},
|
|
296
|
+
onSynced: ({ state }) => setSynced(state),
|
|
204
297
|
onAuthenticated: () => {
|
|
205
298
|
socketConnected = letIn = true;
|
|
206
299
|
if (!stopToolSync) setStatus('connected');
|
|
207
300
|
},
|
|
301
|
+
// Deleted while it was open here
|
|
302
|
+
onClose: ({ event }) => {
|
|
303
|
+
if (event.reason === CANVAS_DELETED_REASON) onCanvasDeleted();
|
|
304
|
+
},
|
|
208
305
|
// Not signed in (or the session ran out): a chat's view syncs through its tools, a page shows it's offline
|
|
209
|
-
// (coming back to the tab tries again, e.g. after signing in again elsewhere)
|
|
210
|
-
onAuthenticationFailed: () => {
|
|
306
|
+
// (coming back to the tab tries again, e.g. after signing in again elsewhere). Or the canvas was deleted.
|
|
307
|
+
onAuthenticationFailed: ({ reason }) => {
|
|
308
|
+
if (reason === CANVAS_DELETED_REASON) return onCanvasDeleted();
|
|
211
309
|
if (syncViaTools) return syncThroughTools();
|
|
212
310
|
provider.disconnect();
|
|
213
311
|
setStatus('disconnected');
|
|
214
312
|
},
|
|
215
313
|
});
|
|
216
314
|
setTransport('websocket');
|
|
315
|
+
setDeleted(false);
|
|
316
|
+
setSynced(false);
|
|
217
317
|
|
|
218
318
|
// Back online, or back on the tab: reconnect now rather than when the next retry is due
|
|
219
319
|
const reconnect = () => {
|
|
220
|
-
if (!stopToolSync && socketStatus === 'disconnected') void provider.connect();
|
|
320
|
+
if (!stopToolSync && !canvasDeleted && socketStatus === 'disconnected') void provider.connect();
|
|
221
321
|
};
|
|
222
322
|
// Away from the tab: our pointer goes from everyone's canvas
|
|
223
323
|
const onVisibilityChange = () => {
|
|
@@ -231,7 +331,7 @@ export function useStudioFlow({
|
|
|
231
331
|
// A socket that isn't let in within a few seconds (blocked, or never answered) is given up for tool calls
|
|
232
332
|
if (syncViaTools) fallback = setTimeout(() => !socketConnected && syncThroughTools(), SOCKET_TIMEOUT_MS);
|
|
233
333
|
// Undo only takes back your own changes: other people's arrive with the provider as origin, agents' with theirs
|
|
234
|
-
const undoManager = new Y.UndoManager([yNodes, yEdges, yThreads], {
|
|
334
|
+
const undoManager = new Y.UndoManager([yNodes, yEdges, yThreads, yLevelLayouts, yHotspots], {
|
|
235
335
|
captureTimeout: 500,
|
|
236
336
|
trackedOrigins: new Set([null, LOCAL_ORIGIN]),
|
|
237
337
|
});
|
|
@@ -248,6 +348,13 @@ export function useStudioFlow({
|
|
|
248
348
|
// Where others are dragging nodes, from their presence, until they drop them
|
|
249
349
|
let remoteMoves = new Map<string, XYPosition>();
|
|
250
350
|
const settling = new Set<ReturnType<typeof setTimeout>>();
|
|
351
|
+
// Shown gliding, a step a frame: at most one update a frame however many people drag (each presence arriving
|
|
352
|
+
// was an update of its own: ~5 a frame with 7 people dragging), and smooth between their ~30 updates a second.
|
|
353
|
+
// Not what's been dropped since (its drop is in the document, see syncNodes).
|
|
354
|
+
const glide = createSmoother((shown) => {
|
|
355
|
+
const moved = new Map([...shown].filter(([id]) => remoteMoves.has(id)));
|
|
356
|
+
if (moved.size) setNodes((local) => withPositions(local, moved));
|
|
357
|
+
});
|
|
251
358
|
const syncMoves = (_: unknown, origin: unknown) => {
|
|
252
359
|
if (origin === 'local') return;
|
|
253
360
|
const next = new Map<string, XYPosition>();
|
|
@@ -255,10 +362,10 @@ export function useStudioFlow({
|
|
|
255
362
|
if (id === doc.clientID || !state.moving) return;
|
|
256
363
|
Object.entries(state.moving as Record<string, XYPosition>).forEach(([nodeId, position]) => next.set(nodeId, position));
|
|
257
364
|
});
|
|
258
|
-
const moved =
|
|
365
|
+
const moved = [...next].some(([id, { x, y }]) => remoteMoves.get(id)?.x !== x || remoteMoves.get(id)?.y !== y);
|
|
259
366
|
const dropped = [...remoteMoves.keys()].filter((id) => !next.has(id));
|
|
260
367
|
remoteMoves = next;
|
|
261
|
-
if (moved.
|
|
368
|
+
if (moved || dropped.length) glide.set(next);
|
|
262
369
|
if (dropped.length === 0) return;
|
|
263
370
|
// The drop is saved in the document. If it doesn't arrive, back to where the document has it.
|
|
264
371
|
const settle = setTimeout(() => {
|
|
@@ -273,6 +380,40 @@ export function useStudioFlow({
|
|
|
273
380
|
};
|
|
274
381
|
awareness.on('change', syncMoves);
|
|
275
382
|
|
|
383
|
+
// What others are writing on notes and text, and how they're scaling and turning text, as they do it (from their
|
|
384
|
+
// presence): shown on just those nodes, and back to what the document has when they're done (their result is
|
|
385
|
+
// written to the document before their presence is cleared, so it doesn't go back in between)
|
|
386
|
+
let remoteEdits = '';
|
|
387
|
+
let remoteEdited = new Set<string>();
|
|
388
|
+
const syncEdits = (_: unknown, origin: unknown) => {
|
|
389
|
+
if (origin === 'local') return;
|
|
390
|
+
const edits = new Map<string, Record<string, unknown>>();
|
|
391
|
+
awareness.getStates().forEach((state, id) => {
|
|
392
|
+
const editing = state.editing as Editing | null | undefined;
|
|
393
|
+
if (id === doc.clientID || !editing?.id) return;
|
|
394
|
+
const { id: nodeId, ...fields } = editing;
|
|
395
|
+
edits.set(nodeId, fields);
|
|
396
|
+
});
|
|
397
|
+
const key = JSON.stringify([...edits]);
|
|
398
|
+
if (key === remoteEdits) return;
|
|
399
|
+
remoteEdits = key;
|
|
400
|
+
const before = remoteEdited;
|
|
401
|
+
remoteEdited = new Set(edits.keys());
|
|
402
|
+
setNodes((local) => {
|
|
403
|
+
let next: Node[] | undefined;
|
|
404
|
+
local.forEach((node, index) => {
|
|
405
|
+
const edit = edits.get(node.id);
|
|
406
|
+
const savedData = before.has(node.id) ? yNodes.get(node.id)?.data : undefined;
|
|
407
|
+
const changes = edit ?? (savedData && Object.fromEntries(EDITED_FIELDS.map((field) => [field, savedData[field]])));
|
|
408
|
+
if (!changes || Object.entries(changes).every(([field, value]) => node.data[field] === value)) return;
|
|
409
|
+
next ??= [...local];
|
|
410
|
+
next[index] = { ...node, data: { ...node.data, ...changes } };
|
|
411
|
+
});
|
|
412
|
+
return next ?? local;
|
|
413
|
+
});
|
|
414
|
+
};
|
|
415
|
+
awareness.on('change', syncEdits);
|
|
416
|
+
|
|
276
417
|
// Only what changed is replaced, so React Flow re-renders just those nodes
|
|
277
418
|
const syncNodes = (event: Y.YMapEvent<Node>) => {
|
|
278
419
|
if (event.transaction.origin === LOCAL_ORIGIN) return;
|
|
@@ -308,12 +449,17 @@ export function useStudioFlow({
|
|
|
308
449
|
window.removeEventListener('online', reconnect);
|
|
309
450
|
document.removeEventListener('visibilitychange', onVisibilityChange);
|
|
310
451
|
awareness.off('change', syncMoves);
|
|
452
|
+
awareness.off('change', syncEdits);
|
|
453
|
+
glide.stop();
|
|
311
454
|
sender.destroy();
|
|
312
455
|
stopToolSync?.();
|
|
313
456
|
yNodes.unobserve(syncNodes);
|
|
457
|
+
yLevelLayouts.unobserve(syncLevelLayouts);
|
|
314
458
|
yEdges.unobserve(syncEdges);
|
|
315
459
|
yMeta.unobserve(syncMeta);
|
|
460
|
+
yHotspots.unobserve(syncHotspots);
|
|
316
461
|
doc.off('afterTransaction', reopenOnEdit);
|
|
462
|
+
doc.off('afterTransaction', syncStructure);
|
|
317
463
|
presenceStore.destroy();
|
|
318
464
|
undoManager.destroy();
|
|
319
465
|
provider.destroy();
|
|
@@ -366,10 +512,10 @@ export function useStudioFlow({
|
|
|
366
512
|
dragged.current.forEach((position, id) => moveNode(doc, id, position));
|
|
367
513
|
// Containers as they grew around what was dragged, and what else is in them (moved the other way if they grew up
|
|
368
514
|
// or left). Dragged nodes are where React Flow dropped them, already in their containers' grown coordinates.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
515
|
+
// Only what actually moved or grew is written (the preview has everything in those containers)
|
|
516
|
+
dragPreview.current.forEach(({ position, width, height }, id) =>
|
|
517
|
+
placeNode(doc, id, position, width !== undefined && height !== undefined ? { width, height } : undefined)
|
|
518
|
+
);
|
|
373
519
|
dragPreview.current = new Map();
|
|
374
520
|
dragged.current.clear();
|
|
375
521
|
const shared = sharedRef.current;
|
|
@@ -456,12 +602,18 @@ export function useStudioFlow({
|
|
|
456
602
|
* on the canvas, and returns edges to add with it (e.g. a catalog resource's relationships).
|
|
457
603
|
*/
|
|
458
604
|
const insertNode = useCallback(
|
|
459
|
-
(
|
|
605
|
+
(
|
|
606
|
+
type: string,
|
|
607
|
+
data: Record<string, unknown>,
|
|
608
|
+
center: XYPosition,
|
|
609
|
+
connect?: (id: string, existing: Node[]) => Edge[],
|
|
610
|
+
inside?: string
|
|
611
|
+
) => {
|
|
460
612
|
const built = buildNode(type, data, center);
|
|
461
613
|
withDoc((doc) => {
|
|
462
614
|
const existing = Array.from(getCanvasMaps(doc).nodes.values());
|
|
463
|
-
//
|
|
464
|
-
const group = canGoInContainer(type) ?
|
|
615
|
+
// In the container asked for, else the one it's dropped on
|
|
616
|
+
const group = canGoInContainer(type) ? containerFor(center, existing, inside) : undefined;
|
|
465
617
|
const node = group
|
|
466
618
|
? { ...built, parentId: group.id, position: toRelativePosition(built.position, group.id, existing) }
|
|
467
619
|
: built;
|
|
@@ -473,11 +625,11 @@ export function useStudioFlow({
|
|
|
473
625
|
[]
|
|
474
626
|
);
|
|
475
627
|
|
|
476
|
-
/** Add a node of a
|
|
628
|
+
/** Add a node of a component (its type, or its key in the components list), centred on a canvas position (in a container, if asked) */
|
|
477
629
|
const addNode = useCallback(
|
|
478
|
-
(
|
|
479
|
-
const definition = getNodeDefinition(
|
|
480
|
-
return definition ? insertNode(type, definition.createData(), center) : undefined;
|
|
630
|
+
(component: string, center: XYPosition, inside?: string) => {
|
|
631
|
+
const definition = getNodeDefinition(component);
|
|
632
|
+
return definition ? insertNode(definition.type, definition.createData(), center, undefined, inside) : undefined;
|
|
481
633
|
},
|
|
482
634
|
[insertNode]
|
|
483
635
|
);
|
|
@@ -492,6 +644,12 @@ export function useStudioFlow({
|
|
|
492
644
|
|
|
493
645
|
/** Moves nodes (and resizes containers) from a layout in one change, so it undoes in one go */
|
|
494
646
|
const applyPositions = useCallback((layout: LayoutResult) => withDoc((doc) => applyLayout(doc, layout)), []);
|
|
647
|
+
/** Puts things where they go on L1 or L2: moved there by someone (undone like any edit), or placed by the level */
|
|
648
|
+
const setLevelLayout = useCallback(
|
|
649
|
+
(level: 1 | 2, places: ReadonlyMap<string, LevelPlace>, by: 'person' | 'level' = 'person') =>
|
|
650
|
+
withDoc((doc) => setLevelPlaces(doc, level, places), by === 'level' ? LEVEL_PLACEMENT_ORIGIN : null),
|
|
651
|
+
[]
|
|
652
|
+
);
|
|
495
653
|
|
|
496
654
|
/** Adds ready-made nodes and edges (e.g. a container with what's in it) in one change */
|
|
497
655
|
const insertNodes = useCallback(
|
|
@@ -507,13 +665,12 @@ export function useStudioFlow({
|
|
|
507
665
|
[]
|
|
508
666
|
);
|
|
509
667
|
|
|
510
|
-
/** Puts
|
|
511
|
-
const
|
|
512
|
-
(
|
|
668
|
+
/** Puts nodes in containers (or takes them out) together, e.g. a selection dropped in one, as one change */
|
|
669
|
+
const setParents = useCallback(
|
|
670
|
+
(moves: { id: string; parentId: string | undefined; at?: XYPosition }[]) =>
|
|
513
671
|
withDoc((doc) => {
|
|
514
|
-
// Where it was dropped goes first, so it's moved into (or out of) the container from there
|
|
515
672
|
if (dragged.current.size) saveDrop(doc);
|
|
516
|
-
return
|
|
673
|
+
return setNodeParents(doc, moves, renderedSizes());
|
|
517
674
|
}),
|
|
518
675
|
[]
|
|
519
676
|
);
|
|
@@ -537,6 +694,47 @@ export function useStudioFlow({
|
|
|
537
694
|
sharedRef.current?.sender.send({ viewport });
|
|
538
695
|
}, []);
|
|
539
696
|
|
|
697
|
+
/**
|
|
698
|
+
* The note or text being changed here, as it changes (what's written, a text's size and angle), for the others to
|
|
699
|
+
* see as it happens; `null` when done (after the result is saved), sent straight away
|
|
700
|
+
*/
|
|
701
|
+
const sendEditing = useCallback((editing: Editing | null) => {
|
|
702
|
+
const sender = sharedRef.current?.sender;
|
|
703
|
+
if (!sender) return;
|
|
704
|
+
sender.send({ editing: editing && { ...editing, ...(editing.text !== undefined && { text: editing.text.slice(0, 2000) }) } });
|
|
705
|
+
if (!editing) sender.flush();
|
|
706
|
+
}, []);
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* What a diagram file opened into this (new) canvas starts with: its nodes and connections, comments, hotspots and
|
|
710
|
+
* where things are on L1 and L2, in one change that isn't undone
|
|
711
|
+
*/
|
|
712
|
+
const addContent = useCallback(
|
|
713
|
+
(content: ModelCanvasContent) =>
|
|
714
|
+
withDoc((doc) => {
|
|
715
|
+
addNodes(doc, content.nodes, content.edges);
|
|
716
|
+
if (content.threads?.length) addThreads(doc, content.threads);
|
|
717
|
+
if (content.hotspots?.length) addHotspots(doc, content.hotspots);
|
|
718
|
+
setLevelPlaces(doc, 1, content.levelLayouts[1]);
|
|
719
|
+
setLevelPlaces(doc, 2, content.levelLayouts[2]);
|
|
720
|
+
}, OPEN_ORIGIN),
|
|
721
|
+
[]
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
// ---- Hotspots and the lock ----
|
|
725
|
+
|
|
726
|
+
const createHotspot = useCallback(
|
|
727
|
+
(hotspot: Omit<Hotspot, 'id' | 'createdAt'>) => withDoc((doc) => createHotspotInDoc(doc, hotspot)),
|
|
728
|
+
[]
|
|
729
|
+
);
|
|
730
|
+
const updateHotspot = useCallback(
|
|
731
|
+
(id: string, fields: Parameters<typeof updateHotspotInDoc>[2]) => withDoc((doc) => updateHotspotInDoc(doc, id, fields)),
|
|
732
|
+
[]
|
|
733
|
+
);
|
|
734
|
+
const deleteHotspot = useCallback((id: string) => withDoc((doc) => deleteHotspotInDoc(doc, id)), []);
|
|
735
|
+
/** Locks the canvas for everyone (by a name), or unlocks it (null): looked at, not changed */
|
|
736
|
+
const setLocked = useCallback((by: string | null) => withDoc((doc) => setLock(doc, by), STATUS_ORIGIN), []);
|
|
737
|
+
|
|
540
738
|
return {
|
|
541
739
|
nodes,
|
|
542
740
|
edges,
|
|
@@ -554,13 +752,27 @@ export function useStudioFlow({
|
|
|
554
752
|
updateNodeData,
|
|
555
753
|
deleteNodes,
|
|
556
754
|
applyPositions,
|
|
755
|
+
levelLayouts,
|
|
756
|
+
setLevelLayout,
|
|
557
757
|
insertNodes,
|
|
558
|
-
|
|
758
|
+
setParents,
|
|
559
759
|
title,
|
|
760
|
+
diagramLevels,
|
|
761
|
+
structureKey,
|
|
560
762
|
rename,
|
|
561
763
|
canvasStatus,
|
|
562
764
|
changeStatus,
|
|
563
765
|
transport,
|
|
766
|
+
deleted,
|
|
767
|
+
hotspots,
|
|
768
|
+
createHotspot,
|
|
769
|
+
updateHotspot,
|
|
770
|
+
deleteHotspot,
|
|
771
|
+
lockedBy,
|
|
772
|
+
setLocked,
|
|
773
|
+
sendEditing,
|
|
774
|
+
synced,
|
|
775
|
+
addContent,
|
|
564
776
|
undo,
|
|
565
777
|
redo,
|
|
566
778
|
...history,
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// Who you are in Studio: the name you give on your first visit, kept in this browser and used on every canvas
|
|
2
|
-
|
|
2
|
+
/** The colours people can go by (as Studio on the web's): on their pointer, avatar and comments */
|
|
3
|
+
export const PERSON_COLORS = ['#ef4444', '#f97316', '#eab308', '#22c55e', '#06b6d4', '#3b82f6', '#8b5cf6', '#ec4899'];
|
|
4
|
+
const COLORS = PERSON_COLORS;
|
|
3
5
|
const NAME_KEY = 'eventcatalog-studio-name';
|
|
6
|
+
const COLOR_KEY = 'eventcatalog-studio-color';
|
|
7
|
+
/** Names people give are at most this long */
|
|
8
|
+
export const MAX_NAME_LENGTH = 60;
|
|
4
9
|
|
|
5
10
|
export const getStoredName = () => {
|
|
6
11
|
try {
|
|
@@ -33,3 +38,22 @@ export const colorForName = (name: string) => {
|
|
|
33
38
|
for (const char of name) hash = (hash * 31 + char.charCodeAt(0)) | 0;
|
|
34
39
|
return COLORS[Math.abs(hash) % COLORS.length];
|
|
35
40
|
};
|
|
41
|
+
|
|
42
|
+
/** The colour you picked, kept in this browser (else it follows from your name) */
|
|
43
|
+
export const getStoredColor = () => {
|
|
44
|
+
try {
|
|
45
|
+
const color = localStorage.getItem(COLOR_KEY);
|
|
46
|
+
return color && PERSON_COLORS.includes(color) ? color : null;
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const storeColor = (color: string) => {
|
|
53
|
+
try {
|
|
54
|
+
localStorage.setItem(COLOR_KEY, color);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
// Visualiser styles ship in the page head so ClientRouter navigations keep them (see NodeGraph.astro).
|
|
3
3
|
import '@eventcatalog/visualiser/styles-core.css';
|
|
4
|
-
import '
|
|
4
|
+
import '@eventcatalog/visualiser/studio.css';
|
|
5
|
+
import '@eventcatalog/visualiser/studio-fonts.css';
|
|
5
6
|
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
|
|
6
7
|
import { buildUrl } from '@utils/url-builder';
|
|
7
8
|
import StudioDesigner from '../components/StudioDesigner';
|
|
9
|
+
import StudioNotice from '../components/StudioNotice.astro';
|
|
8
10
|
import { getCatalogResources } from '../catalog-resources';
|
|
9
11
|
import { startStudio, STUDIO_SOCKET_PATH } from '../server/runtime';
|
|
10
12
|
import { getSignedInUser, isSignedIn } from '../server/sign-in';
|
|
13
|
+
import { CANVASES_API_PATH } from '../api/canvases-api';
|
|
11
14
|
|
|
12
15
|
export const prerender = false;
|
|
13
16
|
|
|
@@ -17,27 +20,50 @@ if (!id || !/^[0-9a-f-]{36}$/i.test(id)) {
|
|
|
17
20
|
return Astro.redirect(buildUrl('/studio'));
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
const
|
|
23
|
+
// Studio can't start when its storage can't be used (e.g. the database was updated by a newer EventCatalog)
|
|
24
|
+
const started = await startStudio({ isSignedIn }).catch((error: Error) => error);
|
|
25
|
+
const unavailable = started instanceof Error ? started.message : undefined;
|
|
26
|
+
const runtime = started instanceof Error ? undefined : started;
|
|
27
|
+
// A deleted canvas's link (anyone who still had it open was told)
|
|
28
|
+
const deleted = runtime?.isDeleted(id) ?? false;
|
|
29
|
+
if (unavailable) Astro.response.status = 503;
|
|
30
|
+
else if (deleted) Astro.response.status = 410;
|
|
31
|
+
const { resources, relations } = runtime && !deleted ? await getCatalogResources() : { resources: [], relations: [] };
|
|
32
|
+
const keptInMemory = runtime?.storage.type === 'memory';
|
|
22
33
|
const signedInAs = getSignedInUser(Astro.locals);
|
|
23
34
|
---
|
|
24
35
|
|
|
25
|
-
<VerticalSideBarLayout title="Studio
|
|
36
|
+
<VerticalSideBarLayout title="Studio" showNestedSideBar={false}>
|
|
26
37
|
<main
|
|
27
38
|
class="min-h-0 overflow-hidden bg-[rgb(var(--ec-page-bg))]"
|
|
28
39
|
style="margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1); margin-right: calc(var(--ec-app-content-padding-right, 5rem) * -1); height: calc(100dvh - 60px);"
|
|
29
40
|
>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
{
|
|
42
|
+
unavailable ? (
|
|
43
|
+
<StudioNotice title="Studio isn't available" message={unavailable} />
|
|
44
|
+
) : deleted ? (
|
|
45
|
+
<StudioNotice
|
|
46
|
+
title="This canvas was deleted"
|
|
47
|
+
message="Someone deleted it, so it can't be opened any more."
|
|
48
|
+
href={buildUrl('/studio')}
|
|
49
|
+
linkText="Back to Studio"
|
|
50
|
+
/>
|
|
51
|
+
) : (
|
|
52
|
+
<StudioDesigner
|
|
53
|
+
client:only="react"
|
|
54
|
+
canvasId={id}
|
|
55
|
+
socketPath={buildUrl(STUDIO_SOCKET_PATH, true)}
|
|
56
|
+
newCanvasUrl={`${buildUrl('/studio')}?new=1`}
|
|
57
|
+
studioUrl={buildUrl('/studio')}
|
|
58
|
+
canvasesApiUrl={buildUrl(CANVASES_API_PATH, true)}
|
|
59
|
+
mcpUrl={buildUrl('/docs/mcp', true)}
|
|
60
|
+
relayScriptPath={buildUrl('/webmcp-relay/embed.js', true)}
|
|
61
|
+
keptInMemory={keptInMemory}
|
|
62
|
+
signedInAs={signedInAs}
|
|
63
|
+
resources={resources}
|
|
64
|
+
relations={relations}
|
|
65
|
+
/>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
42
68
|
</main>
|
|
43
69
|
</VerticalSideBarLayout>
|