@shepai/cli 1.177.0 → 1.178.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/apis/json-schema/Language.yaml +1 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.d.ts +23 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.js +13 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts +18 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.js +7 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +3 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.d.ts +33 -0
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.js +9 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.d.ts +42 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.js +134 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.d.ts +43 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.js +84 -0
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts +13 -2
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +14 -3
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +16 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.d.ts +35 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.js +165 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.js +22 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.d.ts +22 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.js +74 -0
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts +10 -2
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/check-agent-auth.js +7 -199
- package/dist/src/presentation/web/app/actions/create-project-folder.d.ts +16 -0
- package/dist/src/presentation/web/app/actions/create-project-folder.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/create-project-folder.js +18 -0
- package/dist/src/presentation/web/app/actions/delete-repository.d.ts +4 -1
- package/dist/src/presentation/web/app/actions/delete-repository.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/delete-repository.js +2 -2
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +2 -2
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts +3 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +13 -4
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +5 -3
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +134 -124
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.d.ts +8 -0
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.js +43 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.d.ts +27 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.js +84 -0
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +4 -2
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts +21 -0
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.js +70 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts +27 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.js +48 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +8 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts +3 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.js +3 -3
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.d.ts +15 -0
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.js +74 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts +11 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.js +22 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.d.ts +13 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.js +21 -0
- package/dist/src/presentation/web/hooks/use-workspaces.d.ts +37 -0
- package/dist/src/presentation/web/hooks/use-workspaces.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-workspaces.js +219 -0
- package/dist/src/presentation/web/lib/derive-graph.d.ts +3 -1
- package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
- package/dist/translations/ar/web.json +4 -1
- package/dist/translations/de/web.json +4 -1
- package/dist/translations/en/web.json +4 -1
- package/dist/translations/es/web.json +4 -1
- package/dist/translations/fr/web.json +4 -1
- package/dist/translations/he/web.json +4 -1
- package/dist/translations/pt/web.json +4 -1
- package/dist/translations/ru/web.json +4 -1
- package/dist/translations/uk/web.json +3 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +73 -58
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +69 -54
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +75 -60
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +69 -54
- package/web/.next/server/app/(dashboard)/chat/page.js +1 -2
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +75 -60
- package/web/.next/server/app/(dashboard)/create/page.js +1 -2
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +69 -54
- package/web/.next/server/app/(dashboard)/page.js +1 -2
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/features/page.js.nft.json +1 -1
- package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__23b5ca2c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7528eb6f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_35b56ded._.js +3 -0
- package/web/.next/server/chunks/ssr/_35b56ded._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_4cbb7f95._.js → _496c9117._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_4cbb7f95._.js.map → _496c9117._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_3fc2374c._.js → _49b9ba41._.js} +2 -2
- package/web/.next/server/chunks/ssr/_49b9ba41._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_64efdf53._.js +3 -0
- package/web/.next/server/chunks/ssr/_64efdf53._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_6abfa39e._.js +1 -1
- package/web/.next/server/chunks/ssr/{_19a779c6._.js → _83e1c526._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_19a779c6._.js.map → _83e1c526._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_f8c55130._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js.map +1 -0
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +590 -484
- package/web/.next/static/chunks/{18f429029d702545.js → 0b7251e5d717dd17.js} +1 -1
- package/web/.next/static/chunks/0fd39d549d277843.js +1 -0
- package/web/.next/static/chunks/124b79a5d2a760fb.css +1 -0
- package/web/.next/static/chunks/{b5a916fec4cdc897.js → 25a0d3f50b0a26c1.js} +1 -1
- package/web/.next/static/chunks/{829d2f8ef2715f2f.js → 2cc487403c107f3f.js} +3 -3
- package/web/.next/static/chunks/{0d0e2661bd167e0f.js → 35bf9838f21d1818.js} +1 -1
- package/web/.next/static/chunks/{b5d355eb59916926.js → 36e3d626ed8defca.js} +2 -2
- package/web/.next/static/chunks/4052a4971fbbac9c.js +1 -0
- package/web/.next/static/chunks/{c0e4cd44851a9293.js → 5df9da8b40e298ee.js} +1 -1
- package/web/.next/static/chunks/{efd57b6ffc7cbd54.js → 5f57f0d80d3db147.js} +1 -1
- package/web/.next/static/chunks/{bb479c31b5b53bac.js → 74c37f189bc83156.js} +2 -2
- package/web/.next/static/chunks/8057357cf1f9b4ef.js +1 -0
- package/web/.next/static/chunks/{eaa1b979d63d322b.js → 8286914ac835a1cc.js} +1 -1
- package/web/.next/static/chunks/{0a706f8508eae0a8.js → 8777b2a0a2e85fd1.js} +2 -2
- package/web/.next/static/chunks/{77d6506c7d1f711f.js → 9e9cddf8e38342e8.js} +1 -1
- package/web/.next/static/chunks/ac586c86d71187fc.js +1 -0
- package/web/.next/static/chunks/{ef897f150084ef85.js → c6fdd161a9e5b554.js} +1 -1
- package/web/.next/static/chunks/{4c20d4cd4786a0c8.js → e167803ac69c66c7.js} +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js.map +0 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js.map +0 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_073183f4._.js +0 -3
- package/web/.next/server/chunks/ssr/_073183f4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3fc2374c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_57b1af27._.js +0 -3
- package/web/.next/server/chunks/ssr/_57b1af27._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js.map +0 -1
- package/web/.next/static/chunks/3fc5b2287f192799.js +0 -1
- package/web/.next/static/chunks/a20f2d6f76f469b7.css +0 -1
- package/web/.next/static/chunks/ddd34e939acc204f.js +0 -1
- package/web/.next/static/chunks/f9d948464ed409cb.js +0 -1
- package/web/.next/static/chunks/fc0232384ec2b48d.js +0 -1
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_buildManifest.js +0 -0
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_ssgManifest.js +0 -0
package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire global window events used by the control center canvas to the
|
|
3
|
+
* appropriate handlers. The canvas listens for cross-component requests
|
|
4
|
+
* dispatched as CustomEvents:
|
|
5
|
+
*
|
|
6
|
+
* - shep:add-repository → addRepoAndFocus(path)
|
|
7
|
+
* - shep:feature-created → createFeatureNode(...)
|
|
8
|
+
* - shep:feature-delete-requested → handleDeleteFeature(...)
|
|
9
|
+
* - shep:feature-archive-requested → handleArchiveFeature(...)
|
|
10
|
+
* - shep:feature-unarchive-requested → handleUnarchiveFeature(...)
|
|
11
|
+
*
|
|
12
|
+
* Extracted from control-center-inner.tsx so the parent component stays
|
|
13
|
+
* focused on graph state + rendering, not event-bus plumbing.
|
|
14
|
+
*/
|
|
15
|
+
import { useEffect } from 'react';
|
|
16
|
+
export function useCanvasEventListeners(handlers) {
|
|
17
|
+
const { addRepoAndFocus, createFeatureNode, nodes, handleDeleteFeature, handleArchiveFeature, handleUnarchiveFeature, } = handlers;
|
|
18
|
+
// shep:add-repository — top-bar "add folder" button
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const handler = (e) => {
|
|
21
|
+
const path = e.detail.path;
|
|
22
|
+
addRepoAndFocus(path);
|
|
23
|
+
};
|
|
24
|
+
window.addEventListener('shep:add-repository', handler);
|
|
25
|
+
return () => window.removeEventListener('shep:add-repository', handler);
|
|
26
|
+
}, [addRepoAndFocus]);
|
|
27
|
+
// shep:feature-created — fired by the create drawer with the real server feature ID
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const handler = (e) => {
|
|
30
|
+
const detail = e.detail;
|
|
31
|
+
// When parentId is provided, attach to the parent feature node via a
|
|
32
|
+
// dependency edge instead of the repo node.
|
|
33
|
+
if (detail.parentId) {
|
|
34
|
+
const parentNodeId = `feat-${detail.parentId}`;
|
|
35
|
+
createFeatureNode(parentNodeId, {
|
|
36
|
+
state: 'creating',
|
|
37
|
+
featureId: detail.featureId,
|
|
38
|
+
name: detail.name,
|
|
39
|
+
description: detail.description,
|
|
40
|
+
repositoryPath: detail.repositoryPath,
|
|
41
|
+
}, 'dependencyEdge');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const repoNode = nodes.find((n) => n.type === 'repositoryNode' &&
|
|
45
|
+
n.data.repositoryPath === detail.repositoryPath);
|
|
46
|
+
createFeatureNode(repoNode?.id ?? null, {
|
|
47
|
+
state: 'running',
|
|
48
|
+
featureId: detail.featureId,
|
|
49
|
+
name: detail.name,
|
|
50
|
+
description: detail.description,
|
|
51
|
+
repositoryPath: detail.repositoryPath,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
window.addEventListener('shep:feature-created', handler);
|
|
55
|
+
return () => window.removeEventListener('shep:feature-created', handler);
|
|
56
|
+
}, [nodes, createFeatureNode]);
|
|
57
|
+
// shep:feature-delete-requested — fired from the feature drawer
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const handler = (e) => {
|
|
60
|
+
const { featureId, cleanup, cascadeDelete, closePr } = e.detail;
|
|
61
|
+
handleDeleteFeature(featureId, cleanup, cascadeDelete, closePr);
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener('shep:feature-delete-requested', handler);
|
|
64
|
+
return () => window.removeEventListener('shep:feature-delete-requested', handler);
|
|
65
|
+
}, [handleDeleteFeature]);
|
|
66
|
+
// shep:feature-archive-requested — fired from the feature drawer
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const handler = (e) => {
|
|
69
|
+
const { featureId } = e.detail;
|
|
70
|
+
handleArchiveFeature(featureId);
|
|
71
|
+
};
|
|
72
|
+
window.addEventListener('shep:feature-archive-requested', handler);
|
|
73
|
+
return () => window.removeEventListener('shep:feature-archive-requested', handler);
|
|
74
|
+
}, [handleArchiveFeature]);
|
|
75
|
+
// shep:feature-unarchive-requested — fired from the feature drawer
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const handler = (e) => {
|
|
78
|
+
const { featureId } = e.detail;
|
|
79
|
+
handleUnarchiveFeature(featureId);
|
|
80
|
+
};
|
|
81
|
+
window.addEventListener('shep:feature-unarchive-requested', handler);
|
|
82
|
+
return () => window.removeEventListener('shep:feature-unarchive-requested', handler);
|
|
83
|
+
}, [handleUnarchiveFeature]);
|
|
84
|
+
}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export interface ControlCenterState {
|
|
|
21
21
|
handleStartFeature: (featureId: string) => void;
|
|
22
22
|
handleStopFeature: (featureId: string) => void;
|
|
23
23
|
handleUnarchiveFeature: (featureId: string) => void;
|
|
24
|
-
handleDeleteRepository: (repositoryId: string
|
|
24
|
+
handleDeleteRepository: (repositoryId: string, options?: {
|
|
25
|
+
deleteFromDisk?: boolean;
|
|
26
|
+
}) => Promise<void>;
|
|
25
27
|
createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
|
|
26
28
|
/** Whether archived features are shown on the canvas. */
|
|
27
29
|
showArchived: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QACrC,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QACrC,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CACtB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAmlBpB"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -388,7 +388,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
388
388
|
})
|
|
389
389
|
.finally(() => endMutation());
|
|
390
390
|
}, [router, deleteSound, updateFeature, removeFeature, beginMutation, endMutation]);
|
|
391
|
-
const handleDeleteRepository = useCallback(async (repositoryId) => {
|
|
391
|
+
const handleDeleteRepository = useCallback(async (repositoryId, options) => {
|
|
392
392
|
const repoNodeId = `repo-${repositoryId}`;
|
|
393
393
|
// Find children of this repo via edges
|
|
394
394
|
const childFeatureIds = new Set(edgesRef.current.filter((e) => e.source === repoNodeId).map((e) => e.target));
|
|
@@ -415,7 +415,9 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
415
415
|
removeFeature(childId);
|
|
416
416
|
}
|
|
417
417
|
try {
|
|
418
|
-
const result = await deleteRepository(repositoryId
|
|
418
|
+
const result = await deleteRepository(repositoryId, {
|
|
419
|
+
deleteFromDisk: options?.deleteFromDisk === true,
|
|
420
|
+
});
|
|
419
421
|
if (!result.success) {
|
|
420
422
|
toast.error(result.error ?? 'Failed to remove repository');
|
|
421
423
|
rollback();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the action list for the (+) FloatingActionButton on the control
|
|
3
|
+
* center. Extracted from control-center-inner.tsx so the parent component
|
|
4
|
+
* stays focused on graph state + rendering.
|
|
5
|
+
*/
|
|
6
|
+
import type { useRouter } from 'next/navigation';
|
|
7
|
+
import type { FloatingActionButtonAction } from '../../common/floating-action-button/index.js';
|
|
8
|
+
import type { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
9
|
+
interface UseFabActionsParams {
|
|
10
|
+
router: ReturnType<typeof useRouter>;
|
|
11
|
+
clickSound: {
|
|
12
|
+
play: () => void;
|
|
13
|
+
};
|
|
14
|
+
guardedNavigate: (fn: () => void) => void;
|
|
15
|
+
handlePickFolder: () => void;
|
|
16
|
+
onNewProject: () => void;
|
|
17
|
+
featureFlags: ReturnType<typeof useFeatureFlags>;
|
|
18
|
+
}
|
|
19
|
+
export declare function useFabActions({ router, clickSound, guardedNavigate, handlePickFolder, onNewProject, featureFlags, }: UseFabActionsParams): FloatingActionButtonAction[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=use-fab-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-fab-actions.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-fab-actions.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAIrE,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;IACrC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IACjC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC1C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CAClD;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,EAAE,mBAAmB,GAAG,0BAA0B,EAAE,CA6DpD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Build the action list for the (+) FloatingActionButton on the control
|
|
4
|
+
* center. Extracted from control-center-inner.tsx so the parent component
|
|
5
|
+
* stays focused on graph state + rendering.
|
|
6
|
+
*/
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
import { FolderOpen, FolderPlus, GitBranch, Github, Sparkles } from 'lucide-react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
10
|
+
export function useFabActions({ router, clickSound, guardedNavigate, handlePickFolder, onNewProject, featureFlags, }) {
|
|
11
|
+
const { t } = useTranslation('web');
|
|
12
|
+
return useMemo(() => {
|
|
13
|
+
const actions = [
|
|
14
|
+
{
|
|
15
|
+
id: 'new-project',
|
|
16
|
+
label: 'New project',
|
|
17
|
+
icon: _jsx(FolderPlus, { className: "h-4 w-4" }),
|
|
18
|
+
onClick: () => {
|
|
19
|
+
clickSound.play();
|
|
20
|
+
onNewProject();
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'new-feature',
|
|
25
|
+
label: t('fab.newFeature'),
|
|
26
|
+
icon: _jsx(Sparkles, { className: "h-4 w-4" }),
|
|
27
|
+
onClick: () => {
|
|
28
|
+
clickSound.play();
|
|
29
|
+
guardedNavigate(() => router.push('/create'));
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'add-local-repo',
|
|
34
|
+
label: t('fab.localFolder'),
|
|
35
|
+
icon: _jsx(FolderOpen, { className: "h-4 w-4" }),
|
|
36
|
+
onClick: handlePickFolder,
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
if (featureFlags.adoptBranch) {
|
|
40
|
+
actions.push({
|
|
41
|
+
id: 'adopt-branch',
|
|
42
|
+
label: t('fab.adoptBranch'),
|
|
43
|
+
icon: _jsx(GitBranch, { className: "h-4 w-4" }),
|
|
44
|
+
onClick: () => {
|
|
45
|
+
guardedNavigate(() => router.push('/adopt'));
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (featureFlags.githubImport) {
|
|
50
|
+
actions.push({
|
|
51
|
+
id: 'add-github-repo',
|
|
52
|
+
label: t('fab.fromGithub'),
|
|
53
|
+
icon: _jsx(Github, { className: "h-4 w-4" }),
|
|
54
|
+
onClick: () => {
|
|
55
|
+
window.dispatchEvent(new CustomEvent('shep:open-github-import'));
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return actions;
|
|
60
|
+
}, [
|
|
61
|
+
t,
|
|
62
|
+
clickSound,
|
|
63
|
+
guardedNavigate,
|
|
64
|
+
router,
|
|
65
|
+
handlePickFolder,
|
|
66
|
+
onNewProject,
|
|
67
|
+
featureFlags.adoptBranch,
|
|
68
|
+
featureFlags.githubImport,
|
|
69
|
+
]);
|
|
70
|
+
}
|
package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-fit the React Flow viewport when the active workspace's visible node
|
|
3
|
+
* set changes (switching workspaces, or changing the active workspace's
|
|
4
|
+
* membership via the Manage dialog).
|
|
5
|
+
*
|
|
6
|
+
* Intentionally scoped:
|
|
7
|
+
* - Skips the first run so we don't override the persisted viewport on mount.
|
|
8
|
+
* - Skips the default workspace, which shows everything and owns the
|
|
9
|
+
* persisted viewport via useViewportPersistence.
|
|
10
|
+
* - Skips empty workspaces — there's nothing to fit.
|
|
11
|
+
* - Defers fitView to the next tick so React Flow has committed the new
|
|
12
|
+
* node set before measuring.
|
|
13
|
+
*/
|
|
14
|
+
import type { useReactFlow } from '@xyflow/react';
|
|
15
|
+
import type { CanvasNodeType } from '../../features/features-canvas/index.js';
|
|
16
|
+
type FitViewFn = ReturnType<typeof useReactFlow>['fitView'];
|
|
17
|
+
interface ActiveWorkspaceLike {
|
|
18
|
+
id: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function useWorkspaceFitView(params: {
|
|
21
|
+
activeWorkspace: ActiveWorkspaceLike;
|
|
22
|
+
isDefaultActive: boolean;
|
|
23
|
+
workspaceFilteredNodes: CanvasNodeType[];
|
|
24
|
+
fitView: FitViewFn;
|
|
25
|
+
}): void;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=use-workspace-fit-view.d.ts.map
|
package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-workspace-fit-view.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-workspace-fit-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC;AAE5D,UAAU,mBAAmB;IAC3B,EAAE,EAAE,MAAM,CAAC;CACZ;AAQD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,eAAe,EAAE,mBAAmB,CAAC;IACrC,eAAe,EAAE,OAAO,CAAC;IACzB,sBAAsB,EAAE,cAAc,EAAE,CAAC;IACzC,OAAO,EAAE,SAAS,CAAC;CACpB,GAAG,IAAI,CA2BP"}
|
package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-fit the React Flow viewport when the active workspace's visible node
|
|
3
|
+
* set changes (switching workspaces, or changing the active workspace's
|
|
4
|
+
* membership via the Manage dialog).
|
|
5
|
+
*
|
|
6
|
+
* Intentionally scoped:
|
|
7
|
+
* - Skips the first run so we don't override the persisted viewport on mount.
|
|
8
|
+
* - Skips the default workspace, which shows everything and owns the
|
|
9
|
+
* persisted viewport via useViewportPersistence.
|
|
10
|
+
* - Skips empty workspaces — there's nothing to fit.
|
|
11
|
+
* - Defers fitView to the next tick so React Flow has committed the new
|
|
12
|
+
* node set before measuring.
|
|
13
|
+
*/
|
|
14
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
15
|
+
const AUTO_FOCUS_OPTIONS = {
|
|
16
|
+
maxZoom: 1.0,
|
|
17
|
+
padding: 0.5,
|
|
18
|
+
duration: 500,
|
|
19
|
+
};
|
|
20
|
+
export function useWorkspaceFitView(params) {
|
|
21
|
+
const { activeWorkspace, isDefaultActive, workspaceFilteredNodes, fitView } = params;
|
|
22
|
+
const fingerprint = useMemo(() => {
|
|
23
|
+
if (isDefaultActive)
|
|
24
|
+
return 'default';
|
|
25
|
+
const ids = workspaceFilteredNodes
|
|
26
|
+
.map((n) => n.id)
|
|
27
|
+
.sort()
|
|
28
|
+
.join(',');
|
|
29
|
+
return `${activeWorkspace.id}:${ids}`;
|
|
30
|
+
}, [isDefaultActive, activeWorkspace.id, workspaceFilteredNodes]);
|
|
31
|
+
const prevFingerprintRef = useRef(null);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const prev = prevFingerprintRef.current;
|
|
34
|
+
prevFingerprintRef.current = fingerprint;
|
|
35
|
+
if (prev === null)
|
|
36
|
+
return;
|
|
37
|
+
if (prev === fingerprint)
|
|
38
|
+
return;
|
|
39
|
+
if (isDefaultActive)
|
|
40
|
+
return;
|
|
41
|
+
if (workspaceFilteredNodes.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
const t = setTimeout(() => {
|
|
44
|
+
fitView(AUTO_FOCUS_OPTIONS);
|
|
45
|
+
}, 0);
|
|
46
|
+
return () => clearTimeout(t);
|
|
47
|
+
}, [fingerprint, isDefaultActive, workspaceFilteredNodes.length, fitView]);
|
|
48
|
+
}
|
package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"welcome-agent-setup.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"welcome-agent-setup.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,sBAAsB,2CAyPlF"}
|
|
@@ -5,6 +5,7 @@ import { ChevronLeft, Loader2, AlertTriangle } from 'lucide-react';
|
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { getAllAgentModels } from '../../../app/actions/get-all-agent-models.js';
|
|
7
7
|
import { updateAgentAndModel } from '../../../app/actions/update-agent-and-model.js';
|
|
8
|
+
import { checkToolStatus } from '../../../app/actions/check-tool-status.js';
|
|
8
9
|
import { getAgentTypeIcon } from '../../common/feature-node/agent-type-icons.js';
|
|
9
10
|
import { getModelMeta } from '../../../lib/model-metadata.js';
|
|
10
11
|
import { cn } from '../../../lib/utils.js';
|
|
@@ -13,6 +14,7 @@ export function WelcomeAgentSetup({ onComplete, className }) {
|
|
|
13
14
|
const { t } = useTranslation('web');
|
|
14
15
|
const [groups, setGroups] = useState([]);
|
|
15
16
|
const [loading, setLoading] = useState(true);
|
|
17
|
+
const [ghInstalled, setGhInstalled] = useState(null);
|
|
16
18
|
const [step, setStep] = useState('select-agent');
|
|
17
19
|
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
18
20
|
const [saving, setSaving] = useState(false);
|
|
@@ -24,6 +26,11 @@ export function WelcomeAgentSetup({ onComplete, className }) {
|
|
|
24
26
|
.then(setGroups)
|
|
25
27
|
.finally(() => setLoading(false));
|
|
26
28
|
}, []);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
checkToolStatus()
|
|
31
|
+
.then((status) => setGhInstalled(status.gh.installed))
|
|
32
|
+
.catch(() => setGhInstalled(null));
|
|
33
|
+
}, []);
|
|
27
34
|
const activeGroup = selectedAgent ? groups.find((g) => g.agentType === selectedAgent) : null;
|
|
28
35
|
const transitionTo = useCallback((nextStep, setup) => {
|
|
29
36
|
setTransitioning(true);
|
|
@@ -95,7 +102,7 @@ export function WelcomeAgentSetup({ onComplete, className }) {
|
|
|
95
102
|
: activeGroup
|
|
96
103
|
? t('welcome.chooseModelSubtitle', { label: activeGroup.label })
|
|
97
104
|
: '';
|
|
98
|
-
return (_jsxs("div", { "data-testid": "welcome-agent-setup", className: cn('flex w-full flex-col items-center', className), children: [_jsx("div", { className: "mb-8 flex w-full max-w-xs items-center gap-1.5", children: STEPS.map((s, i) => (_jsx("div", { className: cn('h-[3px] flex-1 rounded-full transition-colors duration-300', i <= stepIndex ? 'bg-foreground/60' : 'bg-muted') }, s))) }), _jsxs("div", { className: cn('flex w-full flex-col items-center transition-opacity duration-200', visible && !transitioning ? 'opacity-100' : 'opacity-0'), children: [_jsx("h1", { className: "text-foreground/90 text-center text-5xl font-extralight tracking-tight", children: heroTitle }), _jsx("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: heroSubtitle }), step === 'select-agent' && (_jsxs("div", { "data-testid": "gh-cli-notice", className: "mt-5 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-900 dark:bg-amber-950/40", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-500" }), _jsxs("p", { className: "text-sm leading-relaxed text-amber-800 dark:text-amber-300", children: [_jsx("span", { className: "font-medium", children: t('welcome.ghCliRequired') }), ' ', t('welcome.ghCliRequiredText'), ' ', _jsx("a", { href: "https://cli.github.com/", target: "_blank", rel: "noopener noreferrer", className: "underline underline-offset-2 hover:text-amber-900 dark:hover:text-amber-200", children: t('welcome.installHere') }), "."] })] })), _jsxs("div", { className: "mt-8 flex w-full flex-col items-center", children: [step === 'select-agent' && (_jsx("div", { "data-testid": "agent-list", className: "grid w-full max-w-lg gap-3", style: {
|
|
105
|
+
return (_jsxs("div", { "data-testid": "welcome-agent-setup", className: cn('flex w-full flex-col items-center', className), children: [_jsx("div", { className: "mb-8 flex w-full max-w-xs items-center gap-1.5", children: STEPS.map((s, i) => (_jsx("div", { className: cn('h-[3px] flex-1 rounded-full transition-colors duration-300', i <= stepIndex ? 'bg-foreground/60' : 'bg-muted') }, s))) }), _jsxs("div", { className: cn('flex w-full flex-col items-center transition-opacity duration-200', visible && !transitioning ? 'opacity-100' : 'opacity-0'), children: [_jsx("h1", { className: "text-foreground/90 text-center text-5xl font-extralight tracking-tight", children: heroTitle }), _jsx("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: heroSubtitle }), step === 'select-agent' && ghInstalled === false && (_jsxs("div", { "data-testid": "gh-cli-notice", className: "mt-5 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-900 dark:bg-amber-950/40", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-500" }), _jsxs("p", { className: "text-sm leading-relaxed text-amber-800 dark:text-amber-300", children: [_jsx("span", { className: "font-medium", children: t('welcome.ghCliRequired') }), ' ', t('welcome.ghCliRequiredText'), ' ', _jsx("a", { href: "https://cli.github.com/", target: "_blank", rel: "noopener noreferrer", className: "underline underline-offset-2 hover:text-amber-900 dark:hover:text-amber-200", children: t('welcome.installHere') }), "."] })] })), _jsxs("div", { className: "mt-8 flex w-full flex-col items-center", children: [step === 'select-agent' && (_jsx("div", { "data-testid": "agent-list", className: "grid w-full max-w-lg gap-3", style: {
|
|
99
106
|
gridTemplateColumns: `repeat(${Math.min(groups.length, 4)}, minmax(0, 1fr))`,
|
|
100
107
|
}, children: groups.map((group) => {
|
|
101
108
|
const GroupIcon = getAgentTypeIcon(group.agentType);
|
|
@@ -3,6 +3,8 @@ export interface CanvasToolbarProps {
|
|
|
3
3
|
showArchived: boolean;
|
|
4
4
|
onToggleArchived: () => void;
|
|
5
5
|
onResetViewport?: () => Viewport;
|
|
6
|
+
/** Optional slot rendered at the start of the toolbar (e.g. workspace selector). */
|
|
7
|
+
startSlot?: React.ReactNode;
|
|
6
8
|
}
|
|
7
|
-
export declare function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport, }: CanvasToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport, startSlot, }: CanvasToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
8
10
|
//# sourceMappingURL=canvas-toolbar.d.ts.map
|
package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-toolbar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/canvas-toolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas-toolbar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/canvas-toolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;IACjC,oFAAoF;IACpF,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,EAAE,kBAAkB,2CA4DpB"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import { useReactFlow } from '@xyflow/react';
|
|
5
5
|
import { Eye, EyeOff, ZoomIn, ZoomOut, Maximize, RotateCcw } from 'lucide-react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { cn } from '../../../lib/utils.js';
|
|
8
|
-
export function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport, }) {
|
|
8
|
+
export function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport, startSlot, }) {
|
|
9
9
|
const { t } = useTranslation('web');
|
|
10
10
|
const { zoomIn, zoomOut, fitView, setViewport } = useReactFlow();
|
|
11
11
|
const handleZoomIn = useCallback(() => {
|
|
@@ -23,7 +23,7 @@ export function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport,
|
|
|
23
23
|
setViewport(viewport, { duration: 400 });
|
|
24
24
|
}
|
|
25
25
|
}, [onResetViewport, setViewport]);
|
|
26
|
-
return (_jsxs("div", { className: "bg-background flex items-center gap-1 rounded-xl border px-2 py-1.5 shadow-md dark:bg-neutral-900", children: [_jsx(ToolbarButton, { onClick: onToggleArchived, title: showArchived ? t('canvas.hideArchived') : t('canvas.showArchived'), active: showArchived, label: showArchived ? t('canvas.hideArchivedLabel') : t('canvas.showArchivedLabel'), children: showArchived ? _jsx(Eye, { className: "h-4 w-4" }) : _jsx(EyeOff, { className: "h-4 w-4" }) }), _jsx("div", { className: "bg-border mx-1 h-5 w-px" }), _jsx(ToolbarButton, { onClick: handleZoomOut, title: t('canvas.zoomOut'), children: _jsx(ZoomOut, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: handleZoomIn, title: t('canvas.zoomIn'), children: _jsx(ZoomIn, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: handleFitView, title: t('canvas.fitView'), children: _jsx(Maximize, { className: "h-4 w-4" }) }), onResetViewport ? (_jsx(ToolbarButton, { onClick: handleReset, title: t('canvas.resetView'), children: _jsx(RotateCcw, { className: "h-4 w-4" }) })) : null] }));
|
|
26
|
+
return (_jsxs("div", { className: "bg-background flex items-center gap-1 rounded-xl border px-2 py-1.5 shadow-md dark:bg-neutral-900", children: [startSlot ? (_jsxs(_Fragment, { children: [startSlot, _jsx("div", { className: "bg-border mx-1 h-5 w-px" })] })) : null, _jsx(ToolbarButton, { onClick: onToggleArchived, title: showArchived ? t('canvas.hideArchived') : t('canvas.showArchived'), active: showArchived, label: showArchived ? t('canvas.hideArchivedLabel') : t('canvas.showArchivedLabel'), children: showArchived ? _jsx(Eye, { className: "h-4 w-4" }) : _jsx(EyeOff, { className: "h-4 w-4" }) }), _jsx("div", { className: "bg-border mx-1 h-5 w-px" }), _jsx(ToolbarButton, { onClick: handleZoomOut, title: t('canvas.zoomOut'), children: _jsx(ZoomOut, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: handleZoomIn, title: t('canvas.zoomIn'), children: _jsx(ZoomIn, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: handleFitView, title: t('canvas.fitView'), children: _jsx(Maximize, { className: "h-4 w-4" }) }), onResetViewport ? (_jsx(ToolbarButton, { onClick: handleReset, title: t('canvas.resetView'), children: _jsx(RotateCcw, { className: "h-4 w-4" }) })) : null] }));
|
|
27
27
|
}
|
|
28
28
|
// ── Internal button ──────────────────────────────────────────────────────
|
|
29
29
|
function ToolbarButton({ children, onClick, title, label, active, }) {
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOvF,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,qCAAqC,CAAC;AAGlG,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kBAAkB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChE,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAID,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOvF,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,qCAAqC,CAAC;AAGlG,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kBAAkB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChE,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAID,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CA+IrB"}
|
|
@@ -71,5 +71,5 @@ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, selectedReposi
|
|
|
71
71
|
}, [isEmpty]);
|
|
72
72
|
const fallbackEmptyState = isEmpty && !emptyState ? (_jsx(EmptyState, { title: t('canvas.noFeatures'), description: t('canvas.noFeaturesDescription'), action: _jsxs(Button, { onClick: onAddFeature, children: [_jsx(Plus, { className: "me-2 h-4 w-4" }), t('canvas.newFeature')] }) })) : null;
|
|
73
73
|
const overlayContent = emptyState ?? fallbackEmptyState;
|
|
74
|
-
return (_jsxs("div", { "data-testid": isEmpty ? 'features-canvas-empty' : 'features-canvas', "data-no-drawer-close": true, className: "dark:bg-background pointer-events-auto relative h-full w-full bg-[#f6f7f8]", children: [_jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, onMoveEnd: onMoveEnd, defaultViewport: defaultViewport ?? FALLBACK_VIEWPORT, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, proOptions: { hideAttribution: true }, className: "[&_.react-flow__pane]:!cursor-default", children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 24, size: 1, color: "#b8bcc4", className: "dark:[&_circle]:!fill-white/[0.1]" }),
|
|
74
|
+
return (_jsxs("div", { "data-testid": isEmpty ? 'features-canvas-empty' : 'features-canvas', "data-no-drawer-close": true, className: "dark:bg-background pointer-events-auto relative h-full w-full bg-[#f6f7f8]", children: [_jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, onMoveEnd: onMoveEnd, defaultViewport: defaultViewport ?? FALLBACK_VIEWPORT, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, proOptions: { hideAttribution: true }, className: "[&_.react-flow__pane]:!cursor-default", children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 24, size: 1, color: "#b8bcc4", className: "dark:[&_circle]:!fill-white/[0.1]" }), toolbar && !isEmpty ? (_jsx(Panel, { position: "top-right", className: "!me-3 !mt-3", children: toolbar })) : null] }), showOverlay && overlayContent ? (_jsx("div", { className: cn('pointer-events-none absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300', overlayExiting ? 'opacity-0' : 'animate-in fade-in opacity-100 duration-200'), children: _jsx("div", { className: "pointer-events-auto h-full w-full", children: overlayContent }) })) : null, toolbar && isEmpty ? (_jsx("div", { className: "pointer-events-auto absolute end-3 top-3 z-20", children: toolbar })) : null] }));
|
|
75
75
|
}
|
package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CanvasNodeType } from '../../features/features-canvas/index.js';
|
|
2
|
+
import type { Workspace } from '../../../hooks/use-workspaces.js';
|
|
3
|
+
export interface ManageWorkspaceDialogProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onOpenChange: (open: boolean) => void;
|
|
6
|
+
workspace: Workspace;
|
|
7
|
+
/** All nodes currently on the canvas (unfiltered). */
|
|
8
|
+
allNodes: CanvasNodeType[];
|
|
9
|
+
onSave: (members: {
|
|
10
|
+
repoIds: string[];
|
|
11
|
+
featureIds: string[];
|
|
12
|
+
}) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function ManageWorkspaceDialog({ open, onOpenChange, workspace, allNodes, onSave, }: ManageWorkspaceDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=manage-workspace-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage-workspace-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/manage-workspace-dialog.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAG5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,sDAAsD;IACtD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;CACxE;AAQD,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,MAAM,GACP,EAAE,0BAA0B,2CA8H5B"}
|
package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { GitBranch, Sparkles } from 'lucide-react';
|
|
5
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
|
|
6
|
+
import { Checkbox } from '../../ui/checkbox.js';
|
|
7
|
+
import { Button } from '../../ui/button.js';
|
|
8
|
+
export function ManageWorkspaceDialog({ open, onOpenChange, workspace, allNodes, onSave, }) {
|
|
9
|
+
const [selectedRepoIds, setSelectedRepoIds] = useState(new Set());
|
|
10
|
+
const [selectedFeatureIds, setSelectedFeatureIds] = useState(new Set());
|
|
11
|
+
// Reset selection state whenever the dialog opens for a (possibly different) workspace.
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (open) {
|
|
14
|
+
setSelectedRepoIds(new Set(workspace.repoIds));
|
|
15
|
+
setSelectedFeatureIds(new Set(workspace.featureIds));
|
|
16
|
+
}
|
|
17
|
+
}, [open, workspace]);
|
|
18
|
+
// Group features under their parent repo by repositoryPath.
|
|
19
|
+
const repoEntries = useMemo(() => {
|
|
20
|
+
const repos = [];
|
|
21
|
+
const byPath = new Map();
|
|
22
|
+
for (const node of allNodes) {
|
|
23
|
+
if (node.type !== 'repositoryNode')
|
|
24
|
+
continue;
|
|
25
|
+
const data = node.data;
|
|
26
|
+
const path = data.repositoryPath ?? '';
|
|
27
|
+
const entry = {
|
|
28
|
+
nodeId: node.id,
|
|
29
|
+
name: data.name ?? path.split('/').filter(Boolean).pop() ?? path,
|
|
30
|
+
features: [],
|
|
31
|
+
};
|
|
32
|
+
repos.push(entry);
|
|
33
|
+
byPath.set(path, entry);
|
|
34
|
+
}
|
|
35
|
+
for (const node of allNodes) {
|
|
36
|
+
if (node.type !== 'featureNode')
|
|
37
|
+
continue;
|
|
38
|
+
const data = node.data;
|
|
39
|
+
const repo = byPath.get(data.repositoryPath ?? '');
|
|
40
|
+
if (repo) {
|
|
41
|
+
repo.features.push({ nodeId: node.id, name: data.name });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return repos;
|
|
45
|
+
}, [allNodes]);
|
|
46
|
+
const toggleRepo = (id) => {
|
|
47
|
+
setSelectedRepoIds((prev) => {
|
|
48
|
+
const next = new Set(prev);
|
|
49
|
+
if (next.has(id))
|
|
50
|
+
next.delete(id);
|
|
51
|
+
else
|
|
52
|
+
next.add(id);
|
|
53
|
+
return next;
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const toggleFeature = (id) => {
|
|
57
|
+
setSelectedFeatureIds((prev) => {
|
|
58
|
+
const next = new Set(prev);
|
|
59
|
+
if (next.has(id))
|
|
60
|
+
next.delete(id);
|
|
61
|
+
else
|
|
62
|
+
next.add(id);
|
|
63
|
+
return next;
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const handleSave = () => {
|
|
67
|
+
onSave({
|
|
68
|
+
repoIds: Array.from(selectedRepoIds),
|
|
69
|
+
featureIds: Array.from(selectedFeatureIds),
|
|
70
|
+
});
|
|
71
|
+
onOpenChange(false);
|
|
72
|
+
};
|
|
73
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-h-[80vh] max-w-lg overflow-hidden", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Manage workspace: ", workspace.name] }), _jsx(DialogDescription, { children: "Select the repositories and features that should appear on this workspace's canvas." })] }), _jsx("div", { className: "-mx-6 max-h-[50vh] overflow-y-auto px-6", children: repoEntries.length === 0 ? (_jsx("p", { className: "text-muted-foreground py-8 text-center text-sm", children: "No repositories on the canvas yet." })) : (_jsx("ul", { className: "space-y-3 py-2", children: repoEntries.map((repo) => (_jsxs("li", { children: [_jsxs("label", { className: "hover:bg-accent/30 flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5", children: [_jsx(Checkbox, { checked: selectedRepoIds.has(repo.nodeId), onCheckedChange: () => toggleRepo(repo.nodeId) }), _jsx(GitBranch, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "text-sm font-medium", children: repo.name })] }), repo.features.length > 0 ? (_jsx("ul", { className: "mt-1 ml-7 space-y-0.5", children: repo.features.map((feat) => (_jsx("li", { children: _jsxs("label", { className: "hover:bg-accent/30 flex cursor-pointer items-center gap-2 rounded-md px-2 py-1", children: [_jsx(Checkbox, { checked: selectedFeatureIds.has(feat.nodeId), onCheckedChange: () => toggleFeature(feat.nodeId) }), _jsx(Sparkles, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("span", { className: "text-muted-foreground text-xs", children: feat.name })] }) }, feat.nodeId))) })) : null] }, repo.nodeId))) })) }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { onClick: handleSave, children: "Save" })] })] }) }));
|
|
74
|
+
}
|
package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface WorkspaceNameDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
initialValue?: string;
|
|
7
|
+
confirmLabel: string;
|
|
8
|
+
onConfirm: (name: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function WorkspaceNameDialog({ open, onOpenChange, title, description, initialValue, confirmLabel, onConfirm, }: WorkspaceNameDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=workspace-name-dialog.d.ts.map
|
package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-name-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/workspace-name-dialog.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAiB,EACjB,YAAY,EACZ,SAAS,GACV,EAAE,wBAAwB,2CA4C1B"}
|
package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
|
|
5
|
+
import { Input } from '../../ui/input.js';
|
|
6
|
+
import { Button } from '../../ui/button.js';
|
|
7
|
+
export function WorkspaceNameDialog({ open, onOpenChange, title, description, initialValue = '', confirmLabel, onConfirm, }) {
|
|
8
|
+
const [value, setValue] = useState(initialValue);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (open)
|
|
11
|
+
setValue(initialValue);
|
|
12
|
+
}, [open, initialValue]);
|
|
13
|
+
const handleSubmit = (e) => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
const trimmed = value.trim();
|
|
16
|
+
if (!trimmed)
|
|
17
|
+
return;
|
|
18
|
+
onConfirm(trimmed);
|
|
19
|
+
onOpenChange(false);
|
|
20
|
+
};
|
|
21
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsx(DialogContent, { className: "max-w-sm", children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: title }), description ? _jsx(DialogDescription, { children: description }) : null] }), _jsx("div", { className: "py-4", children: _jsx(Input, { autoFocus: true, value: value, onChange: (e) => setValue(e.target.value), placeholder: "Workspace name", "data-testid": "workspace-name-input" }) }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { type: "submit", disabled: !value.trim(), children: confirmLabel })] })] }) }) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type UseWorkspacesResult, type Workspace } from '../../../hooks/use-workspaces.js';
|
|
2
|
+
export interface WorkspaceSelectorProps {
|
|
3
|
+
workspaces: UseWorkspacesResult['workspaces'];
|
|
4
|
+
activeWorkspace: Workspace;
|
|
5
|
+
onSelect: (id: string) => void;
|
|
6
|
+
onRequestCreate: () => void;
|
|
7
|
+
onRequestRename: () => void;
|
|
8
|
+
/** Request deletion of a specific workspace by id. */
|
|
9
|
+
onRequestDelete: (id: string) => void;
|
|
10
|
+
onManage: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function WorkspaceSelector({ workspaces, activeWorkspace, onSelect, onRequestCreate, onRequestRename, onRequestDelete, onManage, }: WorkspaceSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=workspace-selector.d.ts.map
|
package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-selector.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/workspace-selector.tsx"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC9C,eAAe,EAAE,SAAS,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,sDAAsD;IACtD,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,eAAe,EACf,QAAQ,EACR,eAAe,EACf,eAAe,EACf,eAAe,EACf,QAAQ,GACT,EAAE,sBAAsB,2CAwExB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Layers, Check, Plus, Pencil, Trash2, SlidersHorizontal } from 'lucide-react';
|
|
5
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '../../ui/dropdown-menu.js';
|
|
6
|
+
import { cn } from '../../../lib/utils.js';
|
|
7
|
+
import { DEFAULT_WORKSPACE_ID, } from '../../../hooks/use-workspaces.js';
|
|
8
|
+
export function WorkspaceSelector({ workspaces, activeWorkspace, onSelect, onRequestCreate, onRequestRename, onRequestDelete, onManage, }) {
|
|
9
|
+
const [open, setOpen] = useState(false);
|
|
10
|
+
const isDefault = activeWorkspace.id === DEFAULT_WORKSPACE_ID;
|
|
11
|
+
return (_jsxs(DropdownMenu, { open: open, onOpenChange: setOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", "data-testid": "workspace-selector-trigger", className: cn('inline-flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-xs font-medium transition-colors', 'hover:bg-accent hover:text-accent-foreground', isDefault ? 'text-muted-foreground' : 'text-primary bg-primary/10'), title: "Workspace", children: [_jsx(Layers, { className: "h-4 w-4" }), _jsx("span", { className: "max-w-[120px] truncate", children: activeWorkspace.name })] }) }), _jsxs(DropdownMenuContent, { align: "start", className: "min-w-[220px]", children: [_jsx(DropdownMenuLabel, { children: "Workspaces" }), _jsx(DropdownMenuSeparator, {}), workspaces.map((w) => {
|
|
12
|
+
const active = w.id === activeWorkspace.id;
|
|
13
|
+
const canDelete = w.id !== DEFAULT_WORKSPACE_ID;
|
|
14
|
+
return (_jsxs(DropdownMenuItem, { onSelect: () => onSelect(w.id), className: "group/ws-row flex items-center justify-between gap-2", children: [_jsx("span", { className: "truncate", children: w.name }), _jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [active ? _jsx(Check, { className: "h-3.5 w-3.5" }) : null, canDelete ? (_jsx("button", { type: "button", "aria-label": `Delete workspace ${w.name}`, title: `Delete workspace ${w.name}`, onClick: (event) => {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
event.stopPropagation();
|
|
17
|
+
setOpen(false);
|
|
18
|
+
onRequestDelete(w.id);
|
|
19
|
+
}, className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive rounded p-0.5 opacity-0 transition-opacity group-hover/ws-row:opacity-100 focus-visible:opacity-100", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })) : null] })] }, w.id));
|
|
20
|
+
}), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onSelect: onRequestCreate, children: [_jsx(Plus, { className: "mr-2 h-3.5 w-3.5" }), "New workspace\u2026"] }), _jsxs(DropdownMenuItem, { onSelect: onManage, disabled: isDefault, children: [_jsx(SlidersHorizontal, { className: "mr-2 h-3.5 w-3.5" }), "Manage items\u2026"] }), _jsxs(DropdownMenuItem, { onSelect: onRequestRename, disabled: isDefault, children: [_jsx(Pencil, { className: "mr-2 h-3.5 w-3.5" }), "Rename"] })] })] }));
|
|
21
|
+
}
|