@shepai/cli 1.48.0 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/json-schema/RejectionFeedbackEntry.yaml +4 -1
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +3 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +5 -1
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +3 -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/nodes/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +65 -36
- 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 +34 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.js +30 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.js +8 -4
- package/dist/src/presentation/cli/commands/feat/show.command.d.ts +6 -0
- package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/show.command.js +52 -14
- 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/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/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/merge-review/merge-review-config.d.ts +4 -2
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.js +4 -15
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +1 -1
- 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 +48 -33
- 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_client-reference-manifest.js +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +41 -26
- 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_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/server/chunks/ssr/_1fafa9db._.js.map +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 +42 -27
- 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_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +41 -26
- 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_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/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 +42 -27
- package/web/.next/standalone/src/presentation/web/app/actions/approve-feature.ts +4 -2
- package/web/.next/standalone/src/presentation/web/app/actions/reject-feature.ts +52 -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/merge-review/merge-review-config.ts +4 -2
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +24 -53
- 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 +94 -49
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/25cab79117866d51.js +10 -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]__19d52794._.js +0 -9
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +0 -9
- package/web/.next/static/chunks/66378a6c055c4e67.js +0 -10
- package/web/.next/static/chunks/8668962d3e682263.css +0 -2
- /package/web/.next/static/{1kZFDMQ0i-Y8dy1KkHlzv → y92RZZcCAiudDG54kYSQf}/_buildManifest.js +0 -0
- /package/web/.next/static/{1kZFDMQ0i-Y8dy1KkHlzv → y92RZZcCAiudDG54kYSQf}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{1kZFDMQ0i-Y8dy1KkHlzv → y92RZZcCAiudDG54kYSQf}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/reject-feature.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAqCD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { resolve } from '../../lib/server-container.js';
|
|
3
|
+
export async function rejectFeature(featureId, feedback) {
|
|
4
|
+
if (!featureId.trim()) {
|
|
5
|
+
return { rejected: false, error: 'Feature id is required' };
|
|
6
|
+
}
|
|
7
|
+
if (!feedback.trim()) {
|
|
8
|
+
return { rejected: false, error: 'Feedback is required' };
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const featureRepo = resolve('IFeatureRepository');
|
|
12
|
+
const feature = await featureRepo.findById(featureId);
|
|
13
|
+
if (!feature) {
|
|
14
|
+
return { rejected: false, error: 'Feature not found' };
|
|
15
|
+
}
|
|
16
|
+
if (!feature.agentRunId) {
|
|
17
|
+
return { rejected: false, error: 'Feature has no agent run' };
|
|
18
|
+
}
|
|
19
|
+
const rejectUseCase = resolve('RejectAgentRunUseCase');
|
|
20
|
+
const result = await rejectUseCase.execute(feature.agentRunId, feedback);
|
|
21
|
+
if (!result.rejected) {
|
|
22
|
+
return { rejected: false, error: result.reason };
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
rejected: true,
|
|
26
|
+
iteration: result.iteration,
|
|
27
|
+
iterationWarning: result.iterationWarning,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
const message = error instanceof Error ? error.message : 'Failed to reject feature';
|
|
32
|
+
return { rejected: false, error: message };
|
|
33
|
+
}
|
|
34
|
+
}
|
package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface DrawerActionBarProps {
|
|
3
|
+
/** Callback when user rejects with feedback (inline input or dialog) */
|
|
4
|
+
onReject?: (feedback: string) => void;
|
|
5
|
+
/** Callback when user approves */
|
|
6
|
+
onApprove: () => void;
|
|
7
|
+
/** Label for the approve button */
|
|
8
|
+
approveLabel: string;
|
|
9
|
+
/** Icon element for the approve button */
|
|
10
|
+
approveIcon?: ReactNode;
|
|
11
|
+
/** Placeholder for the inline revision input */
|
|
12
|
+
revisionPlaceholder?: string;
|
|
13
|
+
/** Title for the reject feedback dialog */
|
|
14
|
+
rejectDialogTitle?: string;
|
|
15
|
+
/** Whether an approval/processing operation is in flight */
|
|
16
|
+
isProcessing?: boolean;
|
|
17
|
+
/** Whether a reject operation is in flight */
|
|
18
|
+
isRejecting?: boolean;
|
|
19
|
+
/** Whether to show the reject button (defaults to true when onReject is provided) */
|
|
20
|
+
showRejectButton?: boolean;
|
|
21
|
+
/** Content rendered between revision input and action buttons (e.g. progress bar) */
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=drawer-action-bar-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer-action-bar-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,kCAAkC;IAClC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DrawerActionBarProps } from './drawer-action-bar-config.js';
|
|
2
|
+
export declare function DrawerActionBar({ onReject, onApprove, approveLabel, approveIcon, revisionPlaceholder, rejectDialogTitle, isProcessing, isRejecting, showRejectButton, children, }: DrawerActionBarProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=drawer-action-bar.d.ts.map
|
package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer-action-bar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,YAAoB,EACpB,WAAmB,EACnB,gBAAuB,EACvB,QAAQ,GACT,EAAE,oBAAoB,2CA2CtB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { X } from 'lucide-react';
|
|
5
|
+
import { Button } from '../../ui/button.js';
|
|
6
|
+
import { RejectFeedbackDialog } from '../../common/reject-feedback-dialog/index.js';
|
|
7
|
+
import { DrawerRevisionInput } from '../../common/drawer-revision-input/index.js';
|
|
8
|
+
export function DrawerActionBar({ onReject, onApprove, approveLabel, approveIcon, revisionPlaceholder, rejectDialogTitle, isProcessing = false, isRejecting = false, showRejectButton = true, children, }) {
|
|
9
|
+
const [rejectDialogOpen, setRejectDialogOpen] = useState(false);
|
|
10
|
+
const disabled = isProcessing || isRejecting;
|
|
11
|
+
return (_jsxs("div", { className: "border-border shrink-0 border-t", children: [children, onReject ? (_jsx(DrawerRevisionInput, { onSubmit: onReject, placeholder: revisionPlaceholder, disabled: disabled || !onReject })) : null, _jsxs("div", { className: "flex items-center gap-2 px-4 pb-4", children: [onReject && showRejectButton ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "outline", className: "text-destructive hover:text-destructive", disabled: disabled, onClick: () => setRejectDialogOpen(true), children: [_jsx(X, { className: "mr-1.5 h-4 w-4" }), "Reject"] }), _jsx(RejectFeedbackDialog, { open: rejectDialogOpen, onOpenChange: setRejectDialogOpen, onConfirm: onReject, isSubmitting: isRejecting, title: rejectDialogTitle })] })) : null, _jsxs(Button, { type: "button", className: "flex-1", disabled: disabled, onClick: onApprove, children: [approveIcon, approveLabel] })] })] }));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DrawerActionBar } from './drawer-action-bar.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DrawerRevisionInputProps {
|
|
2
|
+
/** Callback when user submits revision text */
|
|
3
|
+
onSubmit: (text: string) => void;
|
|
4
|
+
/** Placeholder text for the input */
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
/** Accessible label for the input */
|
|
7
|
+
ariaLabel?: string;
|
|
8
|
+
/** Whether the input should be disabled */
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=drawer-revision-input-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer-revision-input-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-revision-input/drawer-revision-input-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DrawerRevisionInputProps } from './drawer-revision-input-config.js';
|
|
2
|
+
export declare function DrawerRevisionInput({ onSubmit, placeholder, ariaLabel, disabled, }: DrawerRevisionInputProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=drawer-revision-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer-revision-input.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,WAAmC,EACnC,SAAS,EACT,QAAgB,GACjB,EAAE,wBAAwB,2CA2B1B"}
|
package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Send } from 'lucide-react';
|
|
5
|
+
import { Button } from '../../ui/button.js';
|
|
6
|
+
import { Input } from '../../ui/input.js';
|
|
7
|
+
export function DrawerRevisionInput({ onSubmit, placeholder = 'Ask AI to revise...', ariaLabel, disabled = false, }) {
|
|
8
|
+
const [chatInput, setChatInput] = useState('');
|
|
9
|
+
function handleSubmit(e) {
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
const text = chatInput.trim();
|
|
12
|
+
if (!text)
|
|
13
|
+
return;
|
|
14
|
+
onSubmit(text);
|
|
15
|
+
setChatInput('');
|
|
16
|
+
}
|
|
17
|
+
return (_jsxs("form", { onSubmit: handleSubmit, className: "flex items-center gap-2 p-4", children: [_jsx(Input, { type: "text", placeholder: placeholder, "aria-label": ariaLabel ?? placeholder, disabled: disabled, value: chatInput, onChange: (e) => setChatInput(e.target.value), className: "flex-1" }), _jsx(Button, { type: "submit", variant: "secondary", size: "icon", "aria-label": "Send", disabled: disabled, children: _jsx(Send, {}) })] }));
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-revision-input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DrawerRevisionInput } from './drawer-revision-input.js';
|
|
@@ -46,10 +46,12 @@ export interface MergeReviewProps {
|
|
|
46
46
|
data: MergeReviewData;
|
|
47
47
|
/** Approve merge callback */
|
|
48
48
|
onApprove: () => void;
|
|
49
|
-
/**
|
|
50
|
-
|
|
49
|
+
/** Reject merge callback — opens feedback dialog when provided; also used for inline text rejection */
|
|
50
|
+
onReject?: (feedback: string) => void;
|
|
51
51
|
/** Controls disabled state during approval */
|
|
52
52
|
isProcessing?: boolean;
|
|
53
|
+
/** Whether a reject operation is in flight */
|
|
54
|
+
isRejecting?: boolean;
|
|
53
55
|
}
|
|
54
56
|
/** Props for the merge review drawer (shell wrapper) */
|
|
55
57
|
export interface MergeReviewDrawerProps extends MergeReviewProps {
|
package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-review-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/merge-review/merge-review-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAE/E,yCAAyC;AACzC,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,kCAAkC;AAClC,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,uEAAuE;IACvE,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,IAAI,EAAE,eAAe,CAAC;IACtB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,
|
|
1
|
+
{"version":3,"file":"merge-review-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/merge-review/merge-review-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAE/E,yCAAyC;AACzC,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,kCAAkC;AAClC,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,uEAAuE;IACvE,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,IAAI,EAAE,eAAe,CAAC;IACtB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,uGAAuG;IACvG,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,8CAA8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,wCAAwC;IACxC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { MergeReviewProps } from './merge-review-config.js';
|
|
2
|
-
export declare function MergeReview({ data, onApprove,
|
|
2
|
+
export declare function MergeReview({ data, onApprove, onReject, isProcessing, isRejecting, }: MergeReviewProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=merge-review.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-review.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/merge-review/merge-review.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"merge-review.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/merge-review/merge-review.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AA0DhF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,YAAoB,EACpB,WAAmB,GACpB,EAAE,gBAAgB,2CA4IlB"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { CheckCircle2, ExternalLink, GitMerge, Loader2, XCircle, AlertTriangle, FileDiff, GitCommitHorizontal, GitBranch, ArrowRight, Layers, Send, } from 'lucide-react';
|
|
3
|
+
import { CheckCircle2, ExternalLink, GitMerge, Loader2, XCircle, AlertTriangle, FileDiff, GitCommitHorizontal, GitBranch, ArrowRight, Layers, } from 'lucide-react';
|
|
5
4
|
import { CiStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
6
5
|
import { Badge } from '../../ui/badge.js';
|
|
7
|
-
import {
|
|
8
|
-
import { Input } from '../../ui/input.js';
|
|
6
|
+
import { DrawerActionBar } from '../../common/drawer-action-bar/index.js';
|
|
9
7
|
function CiStatusBadge({ status }) {
|
|
10
8
|
switch (status) {
|
|
11
9
|
case CiStatus.Success:
|
|
@@ -19,18 +17,9 @@ function CiStatusBadge({ status }) {
|
|
|
19
17
|
function PhaseList({ phases }) {
|
|
20
18
|
return (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "px-4 py-3", children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx(Layers, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "text-foreground text-xs font-semibold", children: "Implementation Phases" })] }), _jsx("ol", { className: "space-y-2", children: phases.map((phase, i) => (_jsxs("li", { className: "flex items-start gap-2.5", children: [_jsx("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", children: i + 1 }), _jsxs("div", { className: "min-w-0", children: [_jsx("span", { className: "text-foreground text-xs font-medium", children: phase.name }), phase.description ? (_jsx("p", { className: "text-muted-foreground mt-0.5 text-[11px] leading-relaxed", children: phase.description })) : null] })] }, phase.id))) })] }) }));
|
|
21
19
|
}
|
|
22
|
-
export function MergeReview({ data, onApprove,
|
|
20
|
+
export function MergeReview({ data, onApprove, onReject, isProcessing = false, isRejecting = false, }) {
|
|
23
21
|
const { pr, diffSummary, phases, branch, warning } = data;
|
|
24
|
-
const [chatInput, setChatInput] = useState('');
|
|
25
|
-
function handleSubmit(e) {
|
|
26
|
-
e.preventDefault();
|
|
27
|
-
const text = chatInput.trim();
|
|
28
|
-
if (!text)
|
|
29
|
-
return;
|
|
30
|
-
onRefine(text);
|
|
31
|
-
setChatInput('');
|
|
32
|
-
}
|
|
33
22
|
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex-1 space-y-4 overflow-y-auto p-4", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-emerald-500" }), _jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-foreground text-sm font-bold", children: "Merge Review" }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs leading-relaxed", children: pr
|
|
34
23
|
? 'Review the pull request details and approve to merge.'
|
|
35
|
-
: 'Review the changes and approve to merge.' })] })] }), branch ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "flex items-center gap-2 px-4 py-3", children: [_jsx(GitBranch, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx(Badge, { variant: "secondary", className: "font-mono text-[11px]", children: branch.source }), _jsx(ArrowRight, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx(Badge, { variant: "outline", className: "font-mono text-[11px]", children: branch.target })] }) })) : null, pr ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "space-y-3 px-4 py-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("a", { href: pr.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2", children: ["PR #", pr.number, _jsx(ExternalLink, { className: "h-3.5 w-3.5" })] }), _jsx(Badge, { variant: "outline", className: "text-xs", children: pr.status })] }), pr.ciStatus ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "CI Status" }), _jsx(CiStatusBadge, { status: pr.ciStatus })] })) : null, pr.commitHash ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Commit" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("code", { className: "bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]", children: pr.commitHash.slice(0, 7) })] })] })) : null] }) })) : null, diffSummary ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "px-4 py-3", children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx(FileDiff, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "text-foreground text-xs font-semibold", children: "Changes" })] }), _jsxs("div", { className: "grid grid-cols-4 gap-3", children: [_jsxs("div", { className: "text-center", children: [_jsx("div", { className: "text-foreground text-sm font-bold", children: diffSummary.filesChanged }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "files" })] }), _jsxs("div", { className: "text-center", children: [_jsxs("div", { className: "text-sm font-bold text-green-600", children: ["+", diffSummary.additions] }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "additions" })] }), _jsxs("div", { className: "text-center", children: [_jsxs("div", { className: "text-sm font-bold text-red-600", children: ["-", diffSummary.deletions] }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "deletions" })] }), _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "text-foreground text-sm font-bold", children: diffSummary.commitCount }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "commits" })] })] })] }) })) : warning ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "flex items-center gap-2 px-4 py-3", children: [_jsx(AlertTriangle, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "text-muted-foreground text-xs", children: warning })] }) })) : null, phases && phases.length > 0 ? _jsx(PhaseList, { phases: phases }) : null] }),
|
|
24
|
+
: 'Review the changes and approve to merge.' })] })] }), branch ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "flex items-center gap-2 px-4 py-3", children: [_jsx(GitBranch, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx(Badge, { variant: "secondary", className: "font-mono text-[11px]", children: branch.source }), _jsx(ArrowRight, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx(Badge, { variant: "outline", className: "font-mono text-[11px]", children: branch.target })] }) })) : null, pr ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "space-y-3 px-4 py-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("a", { href: pr.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2", children: ["PR #", pr.number, _jsx(ExternalLink, { className: "h-3.5 w-3.5" })] }), _jsx(Badge, { variant: "outline", className: "text-xs", children: pr.status })] }), pr.ciStatus ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "CI Status" }), _jsx(CiStatusBadge, { status: pr.ciStatus })] })) : null, pr.commitHash ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Commit" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("code", { className: "bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]", children: pr.commitHash.slice(0, 7) })] })] })) : null] }) })) : null, diffSummary ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "px-4 py-3", children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx(FileDiff, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "text-foreground text-xs font-semibold", children: "Changes" })] }), _jsxs("div", { className: "grid grid-cols-4 gap-3", children: [_jsxs("div", { className: "text-center", children: [_jsx("div", { className: "text-foreground text-sm font-bold", children: diffSummary.filesChanged }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "files" })] }), _jsxs("div", { className: "text-center", children: [_jsxs("div", { className: "text-sm font-bold text-green-600", children: ["+", diffSummary.additions] }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "additions" })] }), _jsxs("div", { className: "text-center", children: [_jsxs("div", { className: "text-sm font-bold text-red-600", children: ["-", diffSummary.deletions] }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "deletions" })] }), _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "text-foreground text-sm font-bold", children: diffSummary.commitCount }), _jsx("div", { className: "text-muted-foreground text-[10px]", children: "commits" })] })] })] }) })) : warning ? (_jsx("div", { className: "border-border rounded-lg border", children: _jsxs("div", { className: "flex items-center gap-2 px-4 py-3", children: [_jsx(AlertTriangle, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "text-muted-foreground text-xs", children: warning })] }) })) : null, phases && phases.length > 0 ? _jsx(PhaseList, { phases: phases }) : null] }), _jsx(DrawerActionBar, { onReject: onReject, onApprove: onApprove, approveLabel: "Approve Merge", approveIcon: isProcessing ? (_jsx(Loader2, { className: "mr-1.5 h-4 w-4 animate-spin" })) : (_jsx(GitMerge, { className: "mr-1.5 h-4 w-4" })), revisionPlaceholder: "Ask AI to revise before merging...", rejectDialogTitle: "Reject Merge", isProcessing: isProcessing, isRejecting: isRejecting })] }));
|
|
36
25
|
}
|
package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.d.ts
CHANGED
|
@@ -7,12 +7,14 @@ export interface PrdQuestionnaireProps {
|
|
|
7
7
|
selections: Record<string, string>;
|
|
8
8
|
/** Selection change callback */
|
|
9
9
|
onSelect: (questionId: string, optionId: string) => void;
|
|
10
|
-
/** Chat refinement submit callback */
|
|
11
|
-
onRefine: (text: string) => void;
|
|
12
10
|
/** Finalize requirements callback */
|
|
13
11
|
onApprove: (actionId: string) => void;
|
|
12
|
+
/** Reject requirements callback — opens feedback dialog when provided; also used for inline text rejection */
|
|
13
|
+
onReject?: (feedback: string) => void;
|
|
14
14
|
/** Controls disabled/animated state during refinement */
|
|
15
15
|
isProcessing?: boolean;
|
|
16
|
+
/** Whether a reject operation is in flight */
|
|
17
|
+
isRejecting?: boolean;
|
|
16
18
|
/** Show the goal/context header (default: false) */
|
|
17
19
|
showHeader?: boolean;
|
|
18
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-questionnaire-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,cAAc,EACd,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,oBAAoB,CAAC;IAC3B,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gCAAgC;IAChC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,
|
|
1
|
+
{"version":3,"file":"prd-questionnaire-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,cAAc,EACd,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,oBAAoB,CAAC;IAC3B,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gCAAgC;IAChC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,qCAAqC;IACrC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE,iCAAiC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,wCAAwC;IACxC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
|
package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { PrdQuestionnaireProps } from './prd-questionnaire-config.js';
|
|
2
|
-
export declare function PrdQuestionnaire({ data, selections, onSelect,
|
|
2
|
+
export declare function PrdQuestionnaire({ data, selections, onSelect, onApprove, onReject, isProcessing, isRejecting, showHeader, }: PrdQuestionnaireProps): import("react/jsx-runtime").JSX.Element | null;
|
|
3
3
|
//# sourceMappingURL=prd-questionnaire.d.ts.map
|
package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-questionnaire.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"prd-questionnaire.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAoB,EACpB,WAAmB,EACnB,UAAkB,GACnB,EAAE,qBAAqB,kDAqKvB"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { Check, ChevronLeft, ChevronRight } from 'lucide-react';
|
|
4
4
|
import { useCallback, useMemo, useState } from 'react';
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { Button } from '../../ui/button.js';
|
|
7
|
-
import { Input } from '../../ui/input.js';
|
|
8
7
|
import { Badge } from '../../ui/badge.js';
|
|
9
|
-
|
|
8
|
+
import { DrawerActionBar } from '../../common/drawer-action-bar/index.js';
|
|
9
|
+
export function PrdQuestionnaire({ data, selections, onSelect, onApprove, onReject, isProcessing = false, isRejecting = false, showHeader = false, }) {
|
|
10
10
|
const { question, context, questions, finalAction } = data;
|
|
11
11
|
const [currentStep, setCurrentStep] = useState(0);
|
|
12
|
-
const [chatInput, setChatInput] = useState('');
|
|
13
12
|
const total = questions.length;
|
|
14
13
|
const isFirstStep = currentStep === 0;
|
|
15
14
|
const isLastStep = currentStep === total - 1;
|
|
@@ -22,21 +21,13 @@ export function PrdQuestionnaire({ data, selections, onSelect, onRefine, onAppro
|
|
|
22
21
|
setTimeout(() => setCurrentStep((s) => s + 1), 250);
|
|
23
22
|
}
|
|
24
23
|
}, [onSelect, isLastStep]);
|
|
25
|
-
function handleSubmit(e) {
|
|
26
|
-
e.preventDefault();
|
|
27
|
-
const text = chatInput.trim();
|
|
28
|
-
if (!text)
|
|
29
|
-
return;
|
|
30
|
-
onRefine(text);
|
|
31
|
-
setChatInput('');
|
|
32
|
-
}
|
|
33
24
|
if (total === 0)
|
|
34
25
|
return null;
|
|
35
26
|
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex-1 space-y-4 overflow-y-auto p-4", children: [showHeader ? (_jsxs("div", { className: "border-border flex items-start gap-3 border-b pb-3", children: [_jsx("div", { className: "mt-1.5 h-2 w-2 shrink-0 rounded-full bg-amber-500" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-foreground mb-1.5 text-sm font-bold", children: question }), _jsx("p", { className: "text-muted-foreground text-xs leading-relaxed", children: context })] })] })) : null, _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("label", { className: "text-foreground min-w-0 flex-1 text-sm font-semibold", children: currentQuestion.question }), _jsx("div", { className: "mt-1.5 flex shrink-0 gap-1", children: questions.map((q, idx) => (_jsx("button", { type: "button", "aria-label": `Go to question ${idx + 1}`, className: cn('h-1.5 rounded-full transition-all duration-200', idx === currentStep ? 'bg-primary w-4' : 'w-1.5', idx !== currentStep && selections[q.id] ? 'bg-primary/50' : '', idx !== currentStep && !selections[q.id] ? 'bg-muted-foreground/25' : ''), onClick: () => setCurrentStep(idx) }, q.id))) })] }), _jsx("div", { className: "space-y-2", children: currentQuestion.options.map((opt, optIdx) => {
|
|
36
27
|
const selected = selections[currentQuestion.id] === opt.id;
|
|
37
28
|
const letter = String.fromCharCode(65 + optIdx);
|
|
38
29
|
return (_jsx("button", { type: "button", className: cn('border-border w-full rounded-md border px-3 py-3 text-left text-xs transition-all', 'hover:border-primary/70 hover:bg-primary/5 group', selected && 'border-primary bg-primary/5', opt.isNew && 'animate-option-highlight'), disabled: isProcessing, onClick: () => handleSelect(currentQuestion.id, opt.id), children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsxs("span", { className: "text-muted-foreground mt-0.5 font-mono text-xs", children: [letter, "."] }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "mb-0.5 flex items-center gap-2", children: [_jsx("span", { className: "text-foreground text-xs font-semibold", children: opt.label }), opt.recommended ? (_jsx(Badge, { className: "px-1.5 py-0 text-[10px]", children: "AI Recommended" })) : null, opt.isNew ? (_jsx(Badge, { className: "border-transparent bg-emerald-600 px-1.5 py-0 text-[10px] text-white hover:bg-emerald-600/80", children: "New" })) : null] }), _jsx("div", { className: "text-muted-foreground text-xs leading-snug", children: opt.rationale })] })] }) }, opt.id));
|
|
39
|
-
}) })] }), _jsxs("div", { className: "flex items-center justify-between pt-2", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isFirstStep || isProcessing, onClick: () => setCurrentStep((s) => s - 1), children: [_jsx(ChevronLeft, { className: "mr-1 h-4 w-4" }), "Previous"] }), isLastStep ? (_jsxs(Button, { type: "button",
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
}) })] }), _jsxs("div", { className: "flex items-center justify-between pt-2", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isFirstStep || isProcessing, onClick: () => setCurrentStep((s) => s - 1), children: [_jsx(ChevronLeft, { className: "mr-1 h-4 w-4" }), "Previous"] }), !isLastStep ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isProcessing, onClick: () => setCurrentStep((s) => s + 1), children: [selections[currentQuestion.id] ? 'Next' : 'Skip', _jsx(ChevronRight, { className: "ml-1 h-4 w-4" })] })) : null] })] }), _jsx(DrawerActionBar, { onReject: onReject, onApprove: () => onApprove(finalAction.id), approveLabel: finalAction.label, approveIcon: _jsx(Check, { className: "mr-1.5 h-4 w-4" }), revisionPlaceholder: "Ask AI to refine requirements...", isProcessing: isProcessing, isRejecting: isRejecting, children: _jsx("div", { className: cn('bg-muted h-1.5 overflow-hidden', (answeredCount > 0 && answeredCount < total) || isProcessing
|
|
31
|
+
? 'opacity-100'
|
|
32
|
+
: 'opacity-0', 'transition-opacity duration-200'), "data-testid": "progress-bar-container", children: isProcessing ? (_jsx("div", { className: "bg-primary animate-indeterminate-progress h-full w-1/3" })) : (_jsx("div", { className: "bg-primary h-full transition-all duration-300", style: { width: `${total > 0 ? (answeredCount / total) * 100 : 0}%` }, "data-testid": "progress-bar" })) }) })] }));
|
|
42
33
|
}
|
package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts
CHANGED
|
@@ -23,4 +23,8 @@ export declare const InDrawerWithSelections: DrawerStory;
|
|
|
23
23
|
export declare const WithDeleteButton: DrawerStory;
|
|
24
24
|
/** Drawer with delete in progress (button disabled). */
|
|
25
25
|
export declare const DeletingState: DrawerStory;
|
|
26
|
+
/** All answered with reject button visible on last step. */
|
|
27
|
+
export declare const WithRejectButton: Story;
|
|
28
|
+
/** Rejecting state — reject button disabled with spinner while reject action is in flight. */
|
|
29
|
+
export declare const RejectingState: Story;
|
|
26
30
|
//# sourceMappingURL=prd-questionnaire.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-questionnaire.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"prd-questionnaire.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAiKpE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAkBvC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAU/C,sFAAsF;AACtF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,cAAc,EAAE,KAW5B,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,WAAW,EAAE,KAczB,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,EAAE,KAStB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,KA8BzB,CAAC;AAIF,KAAK,WAAW,GAAG,QAAQ,CAAC,OAAO,sBAAsB,CAAC,CAAC;AA0C3D,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,EAAE,WAWtB,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,WAepC,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,EAAE,WAW9B,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,aAAa,EAAE,WAY3B,CAAC;AAaF,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,cAAc,EAAE,KAO5B,CAAC"}
|
package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js
CHANGED
|
@@ -140,7 +140,7 @@ const mockFinalAction = {
|
|
|
140
140
|
/* ─── Interactive wrapper for stories ─── */
|
|
141
141
|
function InteractiveQuestionnaire({ selections: initialSelections = {}, ...props }) {
|
|
142
142
|
const [selections, setSelections] = useState(initialSelections);
|
|
143
|
-
return (_jsx(PrdQuestionnaire, { ...props, selections: selections, onSelect: (qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId })),
|
|
143
|
+
return (_jsx(PrdQuestionnaire, { ...props, selections: selections, onSelect: (qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId })), onApprove: fn().mockName('onApprove') }));
|
|
144
144
|
}
|
|
145
145
|
/* ─── Standalone PrdQuestionnaire ─── */
|
|
146
146
|
const meta = {
|
|
@@ -152,7 +152,6 @@ const meta = {
|
|
|
152
152
|
},
|
|
153
153
|
argTypes: {
|
|
154
154
|
onSelect: { action: 'onSelect' },
|
|
155
|
-
onRefine: { action: 'onRefine' },
|
|
156
155
|
onApprove: { action: 'onApprove' },
|
|
157
156
|
},
|
|
158
157
|
decorators: [
|
|
@@ -239,7 +238,7 @@ const drawerMeta = {
|
|
|
239
238
|
function DrawerTemplate({ selections: initialSelections = {}, ...props }) {
|
|
240
239
|
const [open, setOpen] = useState(true);
|
|
241
240
|
const [selections, setSelections] = useState(initialSelections);
|
|
242
|
-
return (_jsxs("div", { style: { height: '100vh', background: '#f8fafc', padding: '2rem' }, children: [_jsx("button", { type: "button", onClick: () => setOpen(true), style: { padding: '8px 16px', border: '1px solid #ccc', borderRadius: '6px' }, children: "Open Drawer" }), _jsx(PrdQuestionnaireDrawer, { ...props, open: open, onClose: () => setOpen(false), selections: selections, onSelect: (qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId })),
|
|
241
|
+
return (_jsxs("div", { style: { height: '100vh', background: '#f8fafc', padding: '2rem' }, children: [_jsx("button", { type: "button", onClick: () => setOpen(true), style: { padding: '8px 16px', border: '1px solid #ccc', borderRadius: '6px' }, children: "Open Drawer" }), _jsx(PrdQuestionnaireDrawer, { ...props, open: open, onClose: () => setOpen(false), selections: selections, onSelect: (qId, optId) => setSelections((prev) => ({ ...prev, [qId]: optId })), onApprove: fn().mockName('onApprove') })] }));
|
|
243
242
|
}
|
|
244
243
|
/** Drawer with stepper — navigate questions one at a time. */
|
|
245
244
|
export const InDrawer = {
|
|
@@ -265,3 +264,25 @@ export const DeletingState = {
|
|
|
265
264
|
...drawerMeta,
|
|
266
265
|
render: () => (_jsx(DrawerTemplate, { featureName: "User Authentication Flow", featureId: "FEAT-042", lifecycleLabel: "Requirements", data: mockData, onDelete: fn().mockName('onDelete'), isDeleting: true })),
|
|
267
266
|
};
|
|
267
|
+
/* ─── Reject Variants ─── */
|
|
268
|
+
const allAnsweredSelections = {
|
|
269
|
+
problem: 'user_pain',
|
|
270
|
+
priority: 'p1',
|
|
271
|
+
success: 'adoption',
|
|
272
|
+
timeline: 'sprint',
|
|
273
|
+
scope: 'mvp',
|
|
274
|
+
stakeholders: 'end_users',
|
|
275
|
+
};
|
|
276
|
+
/** All answered with reject button visible on last step. */
|
|
277
|
+
export const WithRejectButton = {
|
|
278
|
+
render: () => (_jsx(InteractiveQuestionnaire, { data: mockData, selections: allAnsweredSelections, onReject: fn().mockName('onReject') })),
|
|
279
|
+
};
|
|
280
|
+
/** Rejecting state — reject button disabled with spinner while reject action is in flight. */
|
|
281
|
+
export const RejectingState = {
|
|
282
|
+
args: {
|
|
283
|
+
data: mockData,
|
|
284
|
+
selections: allAnsweredSelections,
|
|
285
|
+
onReject: fn().mockName('onReject'),
|
|
286
|
+
isRejecting: true,
|
|
287
|
+
},
|
|
288
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/reject-feedback-dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,YAAY,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RejectFeedbackDialog } from './reject-feedback-dialog.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RejectFeedbackDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
onConfirm: (feedback: string) => void;
|
|
5
|
+
isSubmitting: boolean;
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=reject-feedback-dialog-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-feedback-dialog-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RejectFeedbackDialogProps } from './reject-feedback-dialog-config.js';
|
|
2
|
+
export declare function RejectFeedbackDialog({ open, onOpenChange, onConfirm, isSubmitting, title, description, }: RejectFeedbackDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=reject-feedback-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-feedback-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAMjF,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,KAAqB,EACrB,WAAiC,GAClC,EAAE,yBAAyB,2CAiD3B"}
|
package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Loader2 } from 'lucide-react';
|
|
5
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
|
|
6
|
+
import { Textarea } from '../../ui/textarea.js';
|
|
7
|
+
const DEFAULT_TITLE = 'Reject Requirements';
|
|
8
|
+
const DEFAULT_DESCRIPTION = 'Provide feedback for the agent to address in the next iteration. Feedback is required.';
|
|
9
|
+
export function RejectFeedbackDialog({ open, onOpenChange, onConfirm, isSubmitting, title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, }) {
|
|
10
|
+
const [feedback, setFeedback] = useState('');
|
|
11
|
+
// Reset feedback when dialog opens
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (open) {
|
|
14
|
+
setFeedback('');
|
|
15
|
+
}
|
|
16
|
+
}, [open]);
|
|
17
|
+
const isFeedbackEmpty = feedback.trim().length === 0;
|
|
18
|
+
return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: title }), _jsx(AlertDialogDescription, { children: description })] }), _jsx(Textarea, { "aria-label": "Rejection feedback", placeholder: "Describe what needs to change...", value: feedback, onChange: (e) => setFeedback(e.target.value), disabled: isSubmitting, rows: 4 }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isSubmitting, onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isFeedbackEmpty || isSubmitting, onClick: () => onConfirm(feedback.trim()), children: isSubmitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Rejecting\u2026"] })) : ('Confirm Reject') })] })] }) }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { RejectFeedbackDialog } from './reject-feedback-dialog.js';
|
|
3
|
+
declare const meta: Meta<typeof RejectFeedbackDialog>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof RejectFeedbackDialog>;
|
|
6
|
+
/** Default — dialog open with empty feedback; confirm button disabled. */
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
/** With feedback entered — confirm button enabled. */
|
|
9
|
+
export declare const WithFeedback: Story;
|
|
10
|
+
/** Submitting state — spinner shown, buttons disabled. */
|
|
11
|
+
export declare const Submitting: Story;
|
|
12
|
+
/** Custom title and description for tech decisions context. */
|
|
13
|
+
export declare const CustomTitle: Story;
|
|
14
|
+
//# sourceMappingURL=reject-feedback-dialog.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-feedback-dialog.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,oBAAoB,CAa3C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEnD,0EAA0E;AAC1E,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,sDAAsD;AACtD,eAAO,MAAM,YAAY,EAAE,KAoB1B,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { fn } from '@storybook/test';
|
|
2
|
+
import { RejectFeedbackDialog } from './reject-feedback-dialog.js';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Composed/RejectFeedbackDialog',
|
|
5
|
+
component: RejectFeedbackDialog,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
open: true,
|
|
12
|
+
onOpenChange: fn().mockName('onOpenChange'),
|
|
13
|
+
onConfirm: fn().mockName('onConfirm'),
|
|
14
|
+
isSubmitting: false,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
/** Default — dialog open with empty feedback; confirm button disabled. */
|
|
19
|
+
export const Default = {};
|
|
20
|
+
/** With feedback entered — confirm button enabled. */
|
|
21
|
+
export const WithFeedback = {
|
|
22
|
+
play: async ({ canvasElement }) => {
|
|
23
|
+
// Type feedback into the textarea to show enabled state
|
|
24
|
+
const textarea = canvasElement.ownerDocument.querySelector('textarea[aria-label="Rejection feedback"]');
|
|
25
|
+
if (textarea) {
|
|
26
|
+
// Simulate React-compatible input
|
|
27
|
+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')?.set;
|
|
28
|
+
nativeInputValueSetter?.call(textarea, 'The requirements are missing error handling for edge cases. Please add validation for empty inputs.');
|
|
29
|
+
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
|
30
|
+
textarea.dispatchEvent(new Event('change', { bubbles: true }));
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/** Submitting state — spinner shown, buttons disabled. */
|
|
35
|
+
export const Submitting = {
|
|
36
|
+
args: {
|
|
37
|
+
isSubmitting: true,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
/** Custom title and description for tech decisions context. */
|
|
41
|
+
export const CustomTitle = {
|
|
42
|
+
args: {
|
|
43
|
+
title: 'Reject Plan',
|
|
44
|
+
description: 'Provide feedback on the technical plan for the agent to revise. Be specific about which decisions need changes.',
|
|
45
|
+
},
|
|
46
|
+
};
|