@shepai/cli 1.47.0 → 1.49.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/ApprovalGateDefaults.yaml +26 -0
- package/apis/json-schema/Feature.yaml +3 -0
- package/apis/json-schema/Repository.yaml +16 -0
- package/apis/json-schema/Settings.yaml +5 -0
- package/apis/json-schema/WorkflowConfig.yaml +4 -20
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +17 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +11 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +11 -4
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts +19 -0
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.js +52 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +8 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +66 -30
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +15 -7
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +41 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +29 -4
- package/dist/src/presentation/cli/ui/messages.d.ts.map +1 -1
- package/dist/src/presentation/cli/ui/messages.js +1 -7
- package/dist/src/presentation/web/app/actions/approve-feature.d.ts +2 -1
- package/dist/src/presentation/web/app/actions/approve-feature.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/approve-feature.js +2 -2
- package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts +7 -0
- package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-merge-review-data.js +49 -0
- package/dist/src/presentation/web/app/actions/reject-feature.d.ts +7 -0
- package/dist/src/presentation/web/app/actions/reject-feature.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/reject-feature.js +34 -0
- package/dist/src/presentation/web/app/page.d.ts.map +1 -1
- package/dist/src/presentation/web/app/page.js +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts +24 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.js +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts +3 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +12 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/index.js +1 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input-config.d.ts +11 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input-config.js +1 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.d.ts +3 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.js +18 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-revision-input/index.js +1 -0
- 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 +8 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +22 -1
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts +4 -0
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/index.js +2 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +77 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.js +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts +3 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.js +7 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +3 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.js +25 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +32 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +165 -0
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.d.ts +4 -2
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +6 -15
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts +4 -0
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js +24 -3
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/index.js +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog-config.d.ts +9 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog-config.js +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.d.ts +3 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.js +19 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.d.ts +14 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.js +46 -0
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review-config.d.ts +4 -2
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.js +4 -14
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts +4 -0
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.js +24 -6
- 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 +88 -19
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +15 -0
- 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 +37 -15
- 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/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +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.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +54 -24
- package/web/.next/server/app/page.js +2 -1
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- 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/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +9 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d8fbe735._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d8fbe735._.js.map +1 -0
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_3ac3601c._.js → server/chunks/ssr/_1fafa9db._.js} +2 -2
- package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.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 +55 -25
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +54 -24
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +2 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2d1a8e37._.js +9 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__d8fbe735._.js +3 -0
- package/web/.next/{server/chunks/ssr/_3ac3601c._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_1fafa9db._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +55 -25
- package/web/.next/standalone/src/presentation/web/app/actions/approve-feature.ts +4 -2
- package/web/.next/standalone/src/presentation/web/app/actions/get-merge-review-data.ts +64 -0
- package/web/.next/standalone/src/presentation/web/app/actions/reject-feature.ts +52 -0
- package/web/.next/standalone/src/presentation/web/app/page.tsx +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.ts +24 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +64 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/index.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input-config.ts +10 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.tsx +41 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-revision-input/index.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.stories.tsx +23 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +6 -1
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/index.ts +7 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-config.ts +83 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-drawer.tsx +34 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +240 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +223 -0
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.ts +4 -2
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx +36 -8
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx +16 -47
- package/web/.next/standalone/src/presentation/web/components/common/reject-feedback-dialog/index.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog-config.ts +8 -0
- package/web/.next/standalone/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.tsx +63 -0
- package/web/.next/standalone/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.tsx +78 -0
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review-config.ts +4 -2
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.tsx +27 -6
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx +14 -42
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +157 -31
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +15 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +47 -17
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{9f8e71029fb04681.js → 0da7a9860fa6ae05.js} +2 -2
- package/web/.next/static/chunks/191ca1529c9868dd.js +10 -0
- package/web/.next/static/chunks/22f30ce91a3c79c1.js +1 -0
- package/web/.next/static/chunks/59b8bd47023e0249.css +2 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js +0 -9
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3ac3601c._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__d6d75c22._.js +0 -9
- package/web/.next/static/chunks/779c99975c85389e.js +0 -10
- package/web/.next/static/chunks/83ff3b6bbee54bce.js +0 -1
- package/web/.next/static/chunks/b7b7abe79e05b229.css +0 -2
- /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → UT60KjU8SOYIjqeqo2WT-}/_buildManifest.js +0 -0
- /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → UT60KjU8SOYIjqeqo2WT-}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{wQ3vPV9I8JeacVNyp4HFg → UT60KjU8SOYIjqeqo2WT-}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ReviewDrawerShell } from '@/components/common/review-drawer-shell';
|
|
4
|
+
import { MergeReview } from './merge-review';
|
|
5
|
+
import type { MergeReviewDrawerProps } from './merge-review-config';
|
|
6
|
+
|
|
7
|
+
export function MergeReviewDrawer({
|
|
8
|
+
open,
|
|
9
|
+
onClose,
|
|
10
|
+
featureName,
|
|
11
|
+
featureId,
|
|
12
|
+
repositoryPath,
|
|
13
|
+
branch,
|
|
14
|
+
specPath,
|
|
15
|
+
onDelete,
|
|
16
|
+
isDeleting,
|
|
17
|
+
...reviewProps
|
|
18
|
+
}: MergeReviewDrawerProps) {
|
|
19
|
+
return (
|
|
20
|
+
<ReviewDrawerShell
|
|
21
|
+
open={open}
|
|
22
|
+
onClose={onClose}
|
|
23
|
+
featureName={featureName}
|
|
24
|
+
featureId={featureId}
|
|
25
|
+
repositoryPath={repositoryPath}
|
|
26
|
+
branch={branch}
|
|
27
|
+
specPath={specPath}
|
|
28
|
+
onDelete={onDelete}
|
|
29
|
+
isDeleting={isDeleting}
|
|
30
|
+
>
|
|
31
|
+
<MergeReview {...reviewProps} />
|
|
32
|
+
</ReviewDrawerShell>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import { fn } from '@storybook/test';
|
|
4
|
+
import { PrStatus, CiStatus } from '@shepai/core/domain/generated/output';
|
|
5
|
+
import { MergeReview } from './merge-review';
|
|
6
|
+
import { MergeReviewDrawer } from './merge-review-drawer';
|
|
7
|
+
import type { MergeReviewData } from './merge-review-config';
|
|
8
|
+
|
|
9
|
+
const fullPr = {
|
|
10
|
+
url: 'https://github.com/shep-ai/cli/pull/42',
|
|
11
|
+
number: 42,
|
|
12
|
+
status: PrStatus.Open,
|
|
13
|
+
commitHash: 'a1b2c3d4e5f6789',
|
|
14
|
+
ciStatus: CiStatus.Success,
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
const samplePhases = [
|
|
18
|
+
{ id: 'phase-1', name: 'Foundation & Config', description: 'Set up types and server action' },
|
|
19
|
+
{ id: 'phase-2', name: 'Component Implementation', description: 'Build the merge review UI' },
|
|
20
|
+
{ id: 'phase-3', name: 'Integration & Wiring', description: 'Connect to control center' },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const sampleBranch = { source: 'feat/add-auth', target: 'main' };
|
|
24
|
+
|
|
25
|
+
const fullData: MergeReviewData = {
|
|
26
|
+
pr: fullPr,
|
|
27
|
+
branch: sampleBranch,
|
|
28
|
+
phases: samplePhases,
|
|
29
|
+
diffSummary: {
|
|
30
|
+
filesChanged: 12,
|
|
31
|
+
additions: 340,
|
|
32
|
+
deletions: 85,
|
|
33
|
+
commitCount: 5,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const defaultActions = {
|
|
38
|
+
onApprove: fn().mockName('onApprove'),
|
|
39
|
+
onReject: fn().mockName('onReject'),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/* ─── Standalone MergeReview ─── */
|
|
43
|
+
|
|
44
|
+
const meta: Meta<typeof MergeReview> = {
|
|
45
|
+
title: 'Common/MergeReview',
|
|
46
|
+
component: MergeReview,
|
|
47
|
+
tags: ['autodocs'],
|
|
48
|
+
parameters: {
|
|
49
|
+
layout: 'fullscreen',
|
|
50
|
+
},
|
|
51
|
+
decorators: [
|
|
52
|
+
(Story) => (
|
|
53
|
+
<div style={{ height: '600px', width: '400px', border: '1px solid var(--color-border)' }}>
|
|
54
|
+
<Story />
|
|
55
|
+
</div>
|
|
56
|
+
),
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default meta;
|
|
61
|
+
type Story = StoryObj<typeof MergeReview>;
|
|
62
|
+
|
|
63
|
+
/** Default — all data present with CI success. */
|
|
64
|
+
export const Default: Story = {
|
|
65
|
+
args: {
|
|
66
|
+
data: fullData,
|
|
67
|
+
...defaultActions,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** CI status is Pending — shows yellow badge with spinner. */
|
|
72
|
+
export const CIPending: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
data: {
|
|
75
|
+
...fullData,
|
|
76
|
+
pr: { ...fullPr, ciStatus: CiStatus.Pending },
|
|
77
|
+
},
|
|
78
|
+
...defaultActions,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** CI status is Failure — shows red badge. */
|
|
83
|
+
export const CIFailure: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
data: {
|
|
86
|
+
...fullData,
|
|
87
|
+
pr: { ...fullPr, ciStatus: CiStatus.Failure },
|
|
88
|
+
},
|
|
89
|
+
...defaultActions,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Diff summary unavailable — shows warning message. */
|
|
94
|
+
export const NoDiffSummary: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
data: {
|
|
97
|
+
pr: fullPr,
|
|
98
|
+
branch: sampleBranch,
|
|
99
|
+
warning: 'Diff statistics unavailable — worktree may have been removed',
|
|
100
|
+
},
|
|
101
|
+
...defaultActions,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/** CI status undefined — CI section omitted entirely. */
|
|
106
|
+
export const NoCIStatus: Story = {
|
|
107
|
+
args: {
|
|
108
|
+
data: {
|
|
109
|
+
...fullData,
|
|
110
|
+
pr: { ...fullPr, ciStatus: undefined },
|
|
111
|
+
},
|
|
112
|
+
...defaultActions,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/** Processing state — approve button disabled with spinner. */
|
|
117
|
+
export const Processing: Story = {
|
|
118
|
+
args: {
|
|
119
|
+
data: fullData,
|
|
120
|
+
...defaultActions,
|
|
121
|
+
isProcessing: true,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** No PR — merge without a pull request, shows branch direction and diff summary. */
|
|
126
|
+
export const NoPrWithDiff: Story = {
|
|
127
|
+
args: {
|
|
128
|
+
data: {
|
|
129
|
+
branch: { source: 'feat/fix-login', target: 'main' },
|
|
130
|
+
phases: samplePhases,
|
|
131
|
+
diffSummary: fullData.diffSummary,
|
|
132
|
+
},
|
|
133
|
+
...defaultActions,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/** No PR and no diff — bare merge approval with branch info. */
|
|
138
|
+
export const NoPrNoDiff: Story = {
|
|
139
|
+
args: {
|
|
140
|
+
data: {
|
|
141
|
+
branch: { source: 'feat/fix-login', target: 'main' },
|
|
142
|
+
warning: 'No PR or diff data available',
|
|
143
|
+
},
|
|
144
|
+
...defaultActions,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/** With implementation phases shown. */
|
|
149
|
+
export const WithPhases: Story = {
|
|
150
|
+
args: {
|
|
151
|
+
data: {
|
|
152
|
+
...fullData,
|
|
153
|
+
phases: samplePhases,
|
|
154
|
+
},
|
|
155
|
+
...defaultActions,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/* ─── Drawer Variant ─── */
|
|
160
|
+
|
|
161
|
+
type DrawerStory = StoryObj<typeof MergeReviewDrawer>;
|
|
162
|
+
|
|
163
|
+
const drawerMeta = {
|
|
164
|
+
title: 'Common/MergeReviewDrawer',
|
|
165
|
+
component: MergeReviewDrawer,
|
|
166
|
+
tags: ['autodocs'],
|
|
167
|
+
parameters: {
|
|
168
|
+
layout: 'fullscreen',
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
function DrawerTemplate(
|
|
173
|
+
props: Omit<React.ComponentProps<typeof MergeReviewDrawer>, 'open' | 'onClose'>
|
|
174
|
+
) {
|
|
175
|
+
const [open, setOpen] = useState(true);
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<div style={{ height: '100vh', background: '#f8fafc', padding: '2rem' }}>
|
|
179
|
+
<button
|
|
180
|
+
type="button"
|
|
181
|
+
onClick={() => setOpen(true)}
|
|
182
|
+
style={{ padding: '8px 16px', border: '1px solid #ccc', borderRadius: '6px' }}
|
|
183
|
+
>
|
|
184
|
+
Open Drawer
|
|
185
|
+
</button>
|
|
186
|
+
<MergeReviewDrawer {...props} open={open} onClose={() => setOpen(false)} />
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Merge review drawer with full data. */
|
|
192
|
+
export const InDrawer: DrawerStory = {
|
|
193
|
+
...drawerMeta,
|
|
194
|
+
render: () => (
|
|
195
|
+
<DrawerTemplate
|
|
196
|
+
featureName="Add User Authentication"
|
|
197
|
+
featureId="FEAT-042"
|
|
198
|
+
repositoryPath="/home/user/projects/my-app"
|
|
199
|
+
branch="feat/add-auth"
|
|
200
|
+
data={fullData}
|
|
201
|
+
{...defaultActions}
|
|
202
|
+
/>
|
|
203
|
+
),
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/** Drawer with delete button visible. */
|
|
207
|
+
export const WithDeleteButton: DrawerStory = {
|
|
208
|
+
...drawerMeta,
|
|
209
|
+
render: () => (
|
|
210
|
+
<DrawerTemplate
|
|
211
|
+
featureName="Add User Authentication"
|
|
212
|
+
featureId="FEAT-042"
|
|
213
|
+
repositoryPath="/home/user/projects/my-app"
|
|
214
|
+
branch="feat/add-auth"
|
|
215
|
+
data={fullData}
|
|
216
|
+
{...defaultActions}
|
|
217
|
+
onDelete={fn().mockName('onDelete')}
|
|
218
|
+
/>
|
|
219
|
+
),
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/** Drawer without PR — direct merge with diff summary and branch info. */
|
|
223
|
+
export const InDrawerNoPr: DrawerStory = {
|
|
224
|
+
...drawerMeta,
|
|
225
|
+
render: () => (
|
|
226
|
+
<DrawerTemplate
|
|
227
|
+
featureName="Fix Login Bug"
|
|
228
|
+
featureId="FEAT-099"
|
|
229
|
+
repositoryPath="/home/user/projects/my-app"
|
|
230
|
+
branch="feat/fix-login"
|
|
231
|
+
data={{
|
|
232
|
+
branch: { source: 'feat/fix-login', target: 'main' },
|
|
233
|
+
phases: samplePhases,
|
|
234
|
+
diffSummary: fullData.diffSummary,
|
|
235
|
+
}}
|
|
236
|
+
{...defaultActions}
|
|
237
|
+
onDelete={fn().mockName('onDelete')}
|
|
238
|
+
/>
|
|
239
|
+
),
|
|
240
|
+
};
|
package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
CheckCircle2,
|
|
5
|
+
ExternalLink,
|
|
6
|
+
GitMerge,
|
|
7
|
+
Loader2,
|
|
8
|
+
XCircle,
|
|
9
|
+
AlertTriangle,
|
|
10
|
+
FileDiff,
|
|
11
|
+
GitCommitHorizontal,
|
|
12
|
+
GitBranch,
|
|
13
|
+
ArrowRight,
|
|
14
|
+
Layers,
|
|
15
|
+
} from 'lucide-react';
|
|
16
|
+
import { CiStatus } from '@shepai/core/domain/generated/output';
|
|
17
|
+
import { Badge } from '@/components/ui/badge';
|
|
18
|
+
import { DrawerActionBar } from '@/components/common/drawer-action-bar';
|
|
19
|
+
import type { MergeReviewProps, MergeReviewPhase } from './merge-review-config';
|
|
20
|
+
|
|
21
|
+
function CiStatusBadge({ status }: { status: CiStatus }) {
|
|
22
|
+
switch (status) {
|
|
23
|
+
case CiStatus.Success:
|
|
24
|
+
return (
|
|
25
|
+
<Badge className="border-transparent bg-green-50 text-green-700 hover:bg-green-50">
|
|
26
|
+
<CheckCircle2 className="mr-1 h-3.5 w-3.5" />
|
|
27
|
+
Passing
|
|
28
|
+
</Badge>
|
|
29
|
+
);
|
|
30
|
+
case CiStatus.Pending:
|
|
31
|
+
return (
|
|
32
|
+
<Badge className="border-transparent bg-yellow-50 text-yellow-700 hover:bg-yellow-50">
|
|
33
|
+
<Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
|
|
34
|
+
Pending
|
|
35
|
+
</Badge>
|
|
36
|
+
);
|
|
37
|
+
case CiStatus.Failure:
|
|
38
|
+
return (
|
|
39
|
+
<Badge className="border-transparent bg-red-50 text-red-700 hover:bg-red-50">
|
|
40
|
+
<XCircle className="mr-1 h-3.5 w-3.5" />
|
|
41
|
+
Failing
|
|
42
|
+
</Badge>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function PhaseList({ phases }: { phases: MergeReviewPhase[] }) {
|
|
48
|
+
return (
|
|
49
|
+
<div className="border-border rounded-lg border">
|
|
50
|
+
<div className="px-4 py-3">
|
|
51
|
+
<div className="mb-3 flex items-center gap-2">
|
|
52
|
+
<Layers className="text-muted-foreground h-4 w-4" />
|
|
53
|
+
<span className="text-foreground text-xs font-semibold">Implementation Phases</span>
|
|
54
|
+
</div>
|
|
55
|
+
<ol className="space-y-2">
|
|
56
|
+
{phases.map((phase, i) => (
|
|
57
|
+
<li key={phase.id} className="flex items-start gap-2.5">
|
|
58
|
+
<span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-[10px] font-bold text-emerald-700">
|
|
59
|
+
{i + 1}
|
|
60
|
+
</span>
|
|
61
|
+
<div className="min-w-0">
|
|
62
|
+
<span className="text-foreground text-xs font-medium">{phase.name}</span>
|
|
63
|
+
{phase.description ? (
|
|
64
|
+
<p className="text-muted-foreground mt-0.5 text-[11px] leading-relaxed">
|
|
65
|
+
{phase.description}
|
|
66
|
+
</p>
|
|
67
|
+
) : null}
|
|
68
|
+
</div>
|
|
69
|
+
</li>
|
|
70
|
+
))}
|
|
71
|
+
</ol>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function MergeReview({
|
|
78
|
+
data,
|
|
79
|
+
onApprove,
|
|
80
|
+
onReject,
|
|
81
|
+
isProcessing = false,
|
|
82
|
+
isRejecting = false,
|
|
83
|
+
}: MergeReviewProps) {
|
|
84
|
+
const { pr, diffSummary, phases, branch, warning } = data;
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="flex h-full flex-col">
|
|
88
|
+
<div className="flex-1 space-y-4 overflow-y-auto p-4">
|
|
89
|
+
{/* Header */}
|
|
90
|
+
<div className="flex items-start gap-3">
|
|
91
|
+
<div className="mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-emerald-500" />
|
|
92
|
+
<div className="flex-1">
|
|
93
|
+
<h2 className="text-foreground text-sm font-bold">Merge Review</h2>
|
|
94
|
+
<p className="text-muted-foreground mt-1 text-xs leading-relaxed">
|
|
95
|
+
{pr
|
|
96
|
+
? 'Review the pull request details and approve to merge.'
|
|
97
|
+
: 'Review the changes and approve to merge.'}
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
{/* Branch merge direction (GitHub-like) */}
|
|
103
|
+
{branch ? (
|
|
104
|
+
<div className="border-border rounded-lg border">
|
|
105
|
+
<div className="flex items-center gap-2 px-4 py-3">
|
|
106
|
+
<GitBranch className="text-muted-foreground h-4 w-4 shrink-0" />
|
|
107
|
+
<Badge variant="secondary" className="font-mono text-[11px]">
|
|
108
|
+
{branch.source}
|
|
109
|
+
</Badge>
|
|
110
|
+
<ArrowRight className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
|
|
111
|
+
<Badge variant="outline" className="font-mono text-[11px]">
|
|
112
|
+
{branch.target}
|
|
113
|
+
</Badge>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
) : null}
|
|
117
|
+
|
|
118
|
+
{/* PR metadata card */}
|
|
119
|
+
{pr ? (
|
|
120
|
+
<div className="border-border rounded-lg border">
|
|
121
|
+
<div className="space-y-3 px-4 py-3">
|
|
122
|
+
{/* PR number + link */}
|
|
123
|
+
<div className="flex items-center justify-between">
|
|
124
|
+
<a
|
|
125
|
+
href={pr.url}
|
|
126
|
+
target="_blank"
|
|
127
|
+
rel="noopener noreferrer"
|
|
128
|
+
className="text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2"
|
|
129
|
+
>
|
|
130
|
+
PR #{pr.number}
|
|
131
|
+
<ExternalLink className="h-3.5 w-3.5" />
|
|
132
|
+
</a>
|
|
133
|
+
<Badge variant="outline" className="text-xs">
|
|
134
|
+
{pr.status}
|
|
135
|
+
</Badge>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
{/* CI status */}
|
|
139
|
+
{pr.ciStatus ? (
|
|
140
|
+
<div className="flex items-center justify-between">
|
|
141
|
+
<span className="text-muted-foreground text-xs font-medium">CI Status</span>
|
|
142
|
+
<CiStatusBadge status={pr.ciStatus} />
|
|
143
|
+
</div>
|
|
144
|
+
) : null}
|
|
145
|
+
|
|
146
|
+
{/* Commit hash */}
|
|
147
|
+
{pr.commitHash ? (
|
|
148
|
+
<div className="flex items-center justify-between">
|
|
149
|
+
<span className="text-muted-foreground text-xs font-medium">Commit</span>
|
|
150
|
+
<div className="flex items-center gap-1.5">
|
|
151
|
+
<GitCommitHorizontal className="text-muted-foreground h-3.5 w-3.5" />
|
|
152
|
+
<code className="bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]">
|
|
153
|
+
{pr.commitHash.slice(0, 7)}
|
|
154
|
+
</code>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
) : null}
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
) : null}
|
|
161
|
+
|
|
162
|
+
{/* Diff summary */}
|
|
163
|
+
{diffSummary ? (
|
|
164
|
+
<div className="border-border rounded-lg border">
|
|
165
|
+
<div className="px-4 py-3">
|
|
166
|
+
<div className="mb-3 flex items-center gap-2">
|
|
167
|
+
<FileDiff className="text-muted-foreground h-4 w-4" />
|
|
168
|
+
<span className="text-foreground text-xs font-semibold">Changes</span>
|
|
169
|
+
</div>
|
|
170
|
+
<div className="grid grid-cols-4 gap-3">
|
|
171
|
+
<div className="text-center">
|
|
172
|
+
<div className="text-foreground text-sm font-bold">
|
|
173
|
+
{diffSummary.filesChanged}
|
|
174
|
+
</div>
|
|
175
|
+
<div className="text-muted-foreground text-[10px]">files</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div className="text-center">
|
|
178
|
+
<div className="text-sm font-bold text-green-600">+{diffSummary.additions}</div>
|
|
179
|
+
<div className="text-muted-foreground text-[10px]">additions</div>
|
|
180
|
+
</div>
|
|
181
|
+
<div className="text-center">
|
|
182
|
+
<div className="text-sm font-bold text-red-600">-{diffSummary.deletions}</div>
|
|
183
|
+
<div className="text-muted-foreground text-[10px]">deletions</div>
|
|
184
|
+
</div>
|
|
185
|
+
<div className="text-center">
|
|
186
|
+
<div className="text-foreground text-sm font-bold">{diffSummary.commitCount}</div>
|
|
187
|
+
<div className="text-muted-foreground text-[10px]">commits</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
) : warning ? (
|
|
193
|
+
<div className="border-border rounded-lg border">
|
|
194
|
+
<div className="flex items-center gap-2 px-4 py-3">
|
|
195
|
+
<AlertTriangle className="text-muted-foreground h-4 w-4 shrink-0" />
|
|
196
|
+
<span className="text-muted-foreground text-xs">{warning}</span>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
) : null}
|
|
200
|
+
|
|
201
|
+
{/* Implementation phases */}
|
|
202
|
+
{phases && phases.length > 0 ? <PhaseList phases={phases} /> : null}
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<DrawerActionBar
|
|
206
|
+
onReject={onReject}
|
|
207
|
+
onApprove={onApprove}
|
|
208
|
+
approveLabel="Approve Merge"
|
|
209
|
+
approveIcon={
|
|
210
|
+
isProcessing ? (
|
|
211
|
+
<Loader2 className="mr-1.5 h-4 w-4 animate-spin" />
|
|
212
|
+
) : (
|
|
213
|
+
<GitMerge className="mr-1.5 h-4 w-4" />
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
revisionPlaceholder="Ask AI to revise before merging..."
|
|
217
|
+
rejectDialogTitle="Reject Merge"
|
|
218
|
+
isProcessing={isProcessing}
|
|
219
|
+
isRejecting={isRejecting}
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
@@ -14,12 +14,14 @@ export interface PrdQuestionnaireProps {
|
|
|
14
14
|
selections: Record<string, string>;
|
|
15
15
|
/** Selection change callback */
|
|
16
16
|
onSelect: (questionId: string, optionId: string) => void;
|
|
17
|
-
/** Chat refinement submit callback */
|
|
18
|
-
onRefine: (text: string) => void;
|
|
19
17
|
/** Finalize requirements callback */
|
|
20
18
|
onApprove: (actionId: string) => void;
|
|
19
|
+
/** Reject requirements callback — opens feedback dialog when provided; also used for inline text rejection */
|
|
20
|
+
onReject?: (feedback: string) => void;
|
|
21
21
|
/** Controls disabled/animated state during refinement */
|
|
22
22
|
isProcessing?: boolean;
|
|
23
|
+
/** Whether a reject operation is in flight */
|
|
24
|
+
isRejecting?: boolean;
|
|
23
25
|
/** Show the goal/context header (default: false) */
|
|
24
26
|
showHeader?: boolean;
|
|
25
27
|
}
|
|
@@ -146,10 +146,9 @@ const mockFinalAction = {
|
|
|
146
146
|
function InteractiveQuestionnaire({
|
|
147
147
|
selections: initialSelections = {},
|
|
148
148
|
...props
|
|
149
|
-
}: Omit<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
> & { selections?: Record<string, string> }) {
|
|
149
|
+
}: Omit<React.ComponentProps<typeof PrdQuestionnaire>, 'onSelect' | 'onApprove' | 'selections'> & {
|
|
150
|
+
selections?: Record<string, string>;
|
|
151
|
+
}) {
|
|
153
152
|
const [selections, setSelections] = useState<Record<string, string>>(initialSelections);
|
|
154
153
|
|
|
155
154
|
return (
|
|
@@ -157,7 +156,6 @@ function InteractiveQuestionnaire({
|
|
|
157
156
|
{...props}
|
|
158
157
|
selections={selections}
|
|
159
158
|
onSelect={(qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId }))}
|
|
160
|
-
onRefine={fn().mockName('onRefine')}
|
|
161
159
|
onApprove={fn().mockName('onApprove')}
|
|
162
160
|
/>
|
|
163
161
|
);
|
|
@@ -174,7 +172,6 @@ const meta: Meta<typeof PrdQuestionnaire> = {
|
|
|
174
172
|
},
|
|
175
173
|
argTypes: {
|
|
176
174
|
onSelect: { action: 'onSelect' },
|
|
177
|
-
onRefine: { action: 'onRefine' },
|
|
178
175
|
onApprove: { action: 'onApprove' },
|
|
179
176
|
},
|
|
180
177
|
decorators: [
|
|
@@ -296,7 +293,7 @@ function DrawerTemplate({
|
|
|
296
293
|
...props
|
|
297
294
|
}: Omit<
|
|
298
295
|
React.ComponentProps<typeof PrdQuestionnaireDrawer>,
|
|
299
|
-
'open' | 'onClose' | 'onSelect' | '
|
|
296
|
+
'open' | 'onClose' | 'onSelect' | 'onApprove' | 'selections'
|
|
300
297
|
> & { selections?: Record<string, string> }) {
|
|
301
298
|
const [open, setOpen] = useState(true);
|
|
302
299
|
const [selections, setSelections] = useState<Record<string, string>>(initialSelections);
|
|
@@ -316,7 +313,6 @@ function DrawerTemplate({
|
|
|
316
313
|
onClose={() => setOpen(false)}
|
|
317
314
|
selections={selections}
|
|
318
315
|
onSelect={(qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId }))}
|
|
319
|
-
onRefine={fn().mockName('onRefine')}
|
|
320
316
|
onApprove={fn().mockName('onApprove')}
|
|
321
317
|
/>
|
|
322
318
|
</div>
|
|
@@ -383,3 +379,35 @@ export const DeletingState: DrawerStory = {
|
|
|
383
379
|
/>
|
|
384
380
|
),
|
|
385
381
|
};
|
|
382
|
+
|
|
383
|
+
/* ─── Reject Variants ─── */
|
|
384
|
+
|
|
385
|
+
const allAnsweredSelections = {
|
|
386
|
+
problem: 'user_pain',
|
|
387
|
+
priority: 'p1',
|
|
388
|
+
success: 'adoption',
|
|
389
|
+
timeline: 'sprint',
|
|
390
|
+
scope: 'mvp',
|
|
391
|
+
stakeholders: 'end_users',
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
/** All answered with reject button visible on last step. */
|
|
395
|
+
export const WithRejectButton: Story = {
|
|
396
|
+
render: () => (
|
|
397
|
+
<InteractiveQuestionnaire
|
|
398
|
+
data={mockData}
|
|
399
|
+
selections={allAnsweredSelections}
|
|
400
|
+
onReject={fn().mockName('onReject')}
|
|
401
|
+
/>
|
|
402
|
+
),
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
/** Rejecting state — reject button disabled with spinner while reject action is in flight. */
|
|
406
|
+
export const RejectingState: Story = {
|
|
407
|
+
args: {
|
|
408
|
+
data: mockData,
|
|
409
|
+
selections: allAnsweredSelections,
|
|
410
|
+
onReject: fn().mockName('onReject'),
|
|
411
|
+
isRejecting: true,
|
|
412
|
+
},
|
|
413
|
+
};
|