mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
feat: enhance feature dialogs with planning mode tooltips
- Integrated Tooltip components into AddFeatureDialog, EditFeatureDialog, and MassEditDialog to provide user guidance on planning mode availability. - Updated the rendering logic for planning mode selection to conditionally display tooltips when planning modes are not supported. - Improved user experience by clarifying the conditions under which planning modes can be utilized.
This commit is contained in:
@@ -53,6 +53,7 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu';
|
} from '@/components/ui/dropdown-menu';
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
import {
|
import {
|
||||||
getAncestors,
|
getAncestors,
|
||||||
formatAncestorContextForPrompt,
|
formatAncestorContextForPrompt,
|
||||||
@@ -492,23 +493,44 @@ export function AddFeatureDialog({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div className="grid gap-3 grid-cols-2">
|
||||||
className={cn(
|
<div className="space-y-1.5">
|
||||||
'grid gap-3',
|
<Label
|
||||||
modelSupportsPlanningMode ? 'grid-cols-2' : 'grid-cols-1'
|
className={cn(
|
||||||
)}
|
'text-xs text-muted-foreground',
|
||||||
>
|
!modelSupportsPlanningMode && 'opacity-50'
|
||||||
{modelSupportsPlanningMode && (
|
)}
|
||||||
<div className="space-y-1.5">
|
>
|
||||||
<Label className="text-xs text-muted-foreground">Planning</Label>
|
Planning
|
||||||
|
</Label>
|
||||||
|
{modelSupportsPlanningMode ? (
|
||||||
<PlanningModeSelect
|
<PlanningModeSelect
|
||||||
mode={planningMode}
|
mode={planningMode}
|
||||||
onModeChange={setPlanningMode}
|
onModeChange={setPlanningMode}
|
||||||
testIdPrefix="add-feature-planning"
|
testIdPrefix="add-feature-planning"
|
||||||
compact
|
compact
|
||||||
/>
|
/>
|
||||||
</div>
|
) : (
|
||||||
)}
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div>
|
||||||
|
<PlanningModeSelect
|
||||||
|
mode="skip"
|
||||||
|
onModeChange={() => {}}
|
||||||
|
testIdPrefix="add-feature-planning"
|
||||||
|
compact
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Planning modes are only available for Claude Provider</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<Label className="text-xs text-muted-foreground">Options</Label>
|
<Label className="text-xs text-muted-foreground">Options</Label>
|
||||||
<div className="flex flex-col gap-2 pt-1">
|
<div className="flex flex-col gap-2 pt-1">
|
||||||
@@ -526,28 +548,32 @@ export function AddFeatureDialog({
|
|||||||
Run tests
|
Run tests
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
{modelSupportsPlanningMode && (
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<Checkbox
|
||||||
<Checkbox
|
id="add-feature-require-approval"
|
||||||
id="add-feature-require-approval"
|
checked={requirePlanApproval}
|
||||||
checked={requirePlanApproval}
|
onCheckedChange={(checked) => setRequirePlanApproval(!!checked)}
|
||||||
onCheckedChange={(checked) => setRequirePlanApproval(!!checked)}
|
disabled={
|
||||||
disabled={planningMode === 'skip' || planningMode === 'lite'}
|
!modelSupportsPlanningMode ||
|
||||||
data-testid="add-feature-require-approval-checkbox"
|
planningMode === 'skip' ||
|
||||||
/>
|
planningMode === 'lite'
|
||||||
<Label
|
}
|
||||||
htmlFor="add-feature-require-approval"
|
data-testid="add-feature-require-approval-checkbox"
|
||||||
className={cn(
|
/>
|
||||||
'text-xs font-normal',
|
<Label
|
||||||
planningMode === 'skip' || planningMode === 'lite'
|
htmlFor="add-feature-require-approval"
|
||||||
? 'cursor-not-allowed text-muted-foreground'
|
className={cn(
|
||||||
: 'cursor-pointer'
|
'text-xs font-normal',
|
||||||
)}
|
!modelSupportsPlanningMode ||
|
||||||
>
|
planningMode === 'skip' ||
|
||||||
Require approval
|
planningMode === 'lite'
|
||||||
</Label>
|
? 'cursor-not-allowed text-muted-foreground'
|
||||||
</div>
|
: 'cursor-pointer'
|
||||||
)}
|
)}
|
||||||
|
>
|
||||||
|
Require approval
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu';
|
} from '@/components/ui/dropdown-menu';
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
import { DependencyTreeDialog } from './dependency-tree-dialog';
|
import { DependencyTreeDialog } from './dependency-tree-dialog';
|
||||||
import { isClaudeModel, supportsReasoningEffort } from '@automaker/types';
|
import { isClaudeModel, supportsReasoningEffort } from '@automaker/types';
|
||||||
|
|
||||||
@@ -516,23 +517,44 @@ export function EditFeatureDialog({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div className="grid gap-3 grid-cols-2">
|
||||||
className={cn(
|
<div className="space-y-1.5">
|
||||||
'grid gap-3',
|
<Label
|
||||||
modelSupportsPlanningMode ? 'grid-cols-2' : 'grid-cols-1'
|
className={cn(
|
||||||
)}
|
'text-xs text-muted-foreground',
|
||||||
>
|
!modelSupportsPlanningMode && 'opacity-50'
|
||||||
{modelSupportsPlanningMode && (
|
)}
|
||||||
<div className="space-y-1.5">
|
>
|
||||||
<Label className="text-xs text-muted-foreground">Planning</Label>
|
Planning
|
||||||
|
</Label>
|
||||||
|
{modelSupportsPlanningMode ? (
|
||||||
<PlanningModeSelect
|
<PlanningModeSelect
|
||||||
mode={planningMode}
|
mode={planningMode}
|
||||||
onModeChange={setPlanningMode}
|
onModeChange={setPlanningMode}
|
||||||
testIdPrefix="edit-feature-planning"
|
testIdPrefix="edit-feature-planning"
|
||||||
compact
|
compact
|
||||||
/>
|
/>
|
||||||
</div>
|
) : (
|
||||||
)}
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div>
|
||||||
|
<PlanningModeSelect
|
||||||
|
mode="skip"
|
||||||
|
onModeChange={() => {}}
|
||||||
|
testIdPrefix="edit-feature-planning"
|
||||||
|
compact
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Planning modes are only available for Claude Provider</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<Label className="text-xs text-muted-foreground">Options</Label>
|
<Label className="text-xs text-muted-foreground">Options</Label>
|
||||||
<div className="flex flex-col gap-2 pt-1">
|
<div className="flex flex-col gap-2 pt-1">
|
||||||
@@ -552,28 +574,32 @@ export function EditFeatureDialog({
|
|||||||
Run tests
|
Run tests
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
{modelSupportsPlanningMode && (
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<Checkbox
|
||||||
<Checkbox
|
id="edit-feature-require-approval"
|
||||||
id="edit-feature-require-approval"
|
checked={requirePlanApproval}
|
||||||
checked={requirePlanApproval}
|
onCheckedChange={(checked) => setRequirePlanApproval(!!checked)}
|
||||||
onCheckedChange={(checked) => setRequirePlanApproval(!!checked)}
|
disabled={
|
||||||
disabled={planningMode === 'skip' || planningMode === 'lite'}
|
!modelSupportsPlanningMode ||
|
||||||
data-testid="edit-feature-require-approval-checkbox"
|
planningMode === 'skip' ||
|
||||||
/>
|
planningMode === 'lite'
|
||||||
<Label
|
}
|
||||||
htmlFor="edit-feature-require-approval"
|
data-testid="edit-feature-require-approval-checkbox"
|
||||||
className={cn(
|
/>
|
||||||
'text-xs font-normal',
|
<Label
|
||||||
planningMode === 'skip' || planningMode === 'lite'
|
htmlFor="edit-feature-require-approval"
|
||||||
? 'cursor-not-allowed text-muted-foreground'
|
className={cn(
|
||||||
: 'cursor-pointer'
|
'text-xs font-normal',
|
||||||
)}
|
!modelSupportsPlanningMode ||
|
||||||
>
|
planningMode === 'skip' ||
|
||||||
Require approval
|
planningMode === 'lite'
|
||||||
</Label>
|
? 'cursor-not-allowed text-muted-foreground'
|
||||||
</div>
|
: 'cursor-pointer'
|
||||||
)}
|
)}
|
||||||
|
>
|
||||||
|
Require approval
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import { modelSupportsThinking } from '@/lib/utils';
|
|||||||
import { Feature, ModelAlias, ThinkingLevel, PlanningMode } from '@/store/app-store';
|
import { Feature, ModelAlias, ThinkingLevel, PlanningMode } from '@/store/app-store';
|
||||||
import { TestingTabContent, PrioritySelect, PlanningModeSelect } from '../shared';
|
import { TestingTabContent, PrioritySelect, PlanningModeSelect } from '../shared';
|
||||||
import { PhaseModelSelector } from '@/components/views/settings-view/model-defaults/phase-model-selector';
|
import { PhaseModelSelector } from '@/components/views/settings-view/model-defaults/phase-model-selector';
|
||||||
import { isCursorModel, type PhaseModelEntry } from '@automaker/types';
|
import { isCursorModel, isClaudeModel, type PhaseModelEntry } from '@automaker/types';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
interface MassEditDialogProps {
|
interface MassEditDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -167,6 +168,7 @@ export function MassEditDialog({ open, onClose, selectedFeatures, onApply }: Mas
|
|||||||
const hasAnyApply = Object.values(applyState).some(Boolean);
|
const hasAnyApply = Object.values(applyState).some(Boolean);
|
||||||
const isCurrentModelCursor = isCursorModel(model);
|
const isCurrentModelCursor = isCursorModel(model);
|
||||||
const modelAllowsThinking = !isCurrentModelCursor && modelSupportsThinking(model);
|
const modelAllowsThinking = !isCurrentModelCursor && modelSupportsThinking(model);
|
||||||
|
const modelSupportsPlanningMode = isClaudeModel(model);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={(open) => !open && onClose()}>
|
<Dialog open={open} onOpenChange={(open) => !open && onClose()}>
|
||||||
@@ -205,30 +207,64 @@ export function MassEditDialog({ open, onClose, selectedFeatures, onApply }: Mas
|
|||||||
<div className="border-t border-border" />
|
<div className="border-t border-border" />
|
||||||
|
|
||||||
{/* Planning Mode */}
|
{/* Planning Mode */}
|
||||||
<FieldWrapper
|
{modelSupportsPlanningMode ? (
|
||||||
label="Planning Mode"
|
<FieldWrapper
|
||||||
isMixed={mixedValues.planningMode || mixedValues.requirePlanApproval}
|
label="Planning Mode"
|
||||||
willApply={applyState.planningMode || applyState.requirePlanApproval}
|
isMixed={mixedValues.planningMode || mixedValues.requirePlanApproval}
|
||||||
onApplyChange={(apply) =>
|
willApply={applyState.planningMode || applyState.requirePlanApproval}
|
||||||
setApplyState((prev) => ({
|
onApplyChange={(apply) =>
|
||||||
...prev,
|
setApplyState((prev) => ({
|
||||||
planningMode: apply,
|
...prev,
|
||||||
requirePlanApproval: apply,
|
planningMode: apply,
|
||||||
}))
|
requirePlanApproval: apply,
|
||||||
}
|
}))
|
||||||
>
|
}
|
||||||
<PlanningModeSelect
|
>
|
||||||
mode={planningMode}
|
<PlanningModeSelect
|
||||||
onModeChange={(newMode) => {
|
mode={planningMode}
|
||||||
setPlanningMode(newMode);
|
onModeChange={(newMode) => {
|
||||||
// Auto-suggest approval based on mode, but user can override
|
setPlanningMode(newMode);
|
||||||
setRequirePlanApproval(newMode === 'spec' || newMode === 'full');
|
// Auto-suggest approval based on mode, but user can override
|
||||||
}}
|
setRequirePlanApproval(newMode === 'spec' || newMode === 'full');
|
||||||
requireApproval={requirePlanApproval}
|
}}
|
||||||
onRequireApprovalChange={setRequirePlanApproval}
|
requireApproval={requirePlanApproval}
|
||||||
testIdPrefix="mass-edit-planning"
|
onRequireApprovalChange={setRequirePlanApproval}
|
||||||
/>
|
testIdPrefix="mass-edit-planning"
|
||||||
</FieldWrapper>
|
/>
|
||||||
|
</FieldWrapper>
|
||||||
|
) : (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'p-3 rounded-lg border transition-colors border-border bg-muted/20 opacity-50 cursor-not-allowed'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between mb-3">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Checkbox checked={false} disabled className="opacity-50" />
|
||||||
|
<Label className="text-sm font-medium text-muted-foreground">
|
||||||
|
Planning Mode
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="opacity-50 pointer-events-none">
|
||||||
|
<PlanningModeSelect
|
||||||
|
mode="skip"
|
||||||
|
onModeChange={() => {}}
|
||||||
|
testIdPrefix="mass-edit-planning"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Planning modes are only available for Claude Provider</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Priority */}
|
{/* Priority */}
|
||||||
<FieldWrapper
|
<FieldWrapper
|
||||||
|
|||||||
Reference in New Issue
Block a user