feat: AI flow builder, visibility model, dashboard tabs, fork UI (#88)
- AI flow builder: scaffold → branch detail → assemble → review flow - Generate All one-click branch generation with stop/cancel - Regenerate scaffold suggestions button - 3-action review screen: Start Flow, Open in Editor, Build Another - Fix Publish button gated behind !isDirty - Fix visibility column enforcement in tree access filter - Add ?visibility filter and author_name to GET /trees - Dashboard tabbed flows: My Flows / My Team / Public / All - Create button in My Flows tab, window focus reload (stale data fix) - Fork UI with optional reason modal - Fix account_id nullability in User type and schema - Keep is_public and visibility in sync on updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit was merged in pull request #88.
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import { GitBranch, Layers, CheckCircle, ArrowRight, RotateCcw } from 'lucide-react'
|
||||
import { GitBranch, Layers, CheckCircle, ArrowRight, RotateCcw, Play } from 'lucide-react'
|
||||
import { useAIFlowBuilderStore } from '@/store/aiFlowBuilderStore'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface TreePreviewCardProps {
|
||||
onOpenInEditor: () => void
|
||||
onStartFlow: () => void
|
||||
onBuildAnother: () => void
|
||||
}
|
||||
|
||||
export function TreePreviewCard({ onOpenInEditor }: TreePreviewCardProps) {
|
||||
const { assembledTree, reset, isLoading } = useAIFlowBuilderStore()
|
||||
export function TreePreviewCard({ onOpenInEditor, onStartFlow, onBuildAnother }: TreePreviewCardProps) {
|
||||
const { assembledTree, isLoading } = useAIFlowBuilderStore()
|
||||
|
||||
if (!assembledTree) return null
|
||||
|
||||
@@ -58,27 +60,38 @@ export function TreePreviewCard({ onOpenInEditor }: TreePreviewCardProps) {
|
||||
)}
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex gap-2">
|
||||
<div className="flex flex-col gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onOpenInEditor}
|
||||
onClick={onStartFlow}
|
||||
disabled={isLoading}
|
||||
className={cn(
|
||||
'flex flex-1 items-center justify-center gap-2 rounded-lg bg-gradient-brand py-2.5 text-sm font-medium text-white shadow-lg shadow-primary/20',
|
||||
'hover:opacity-90'
|
||||
'flex w-full items-center justify-center gap-2 rounded-lg bg-gradient-brand py-2.5 text-sm font-medium text-white shadow-lg shadow-primary/20',
|
||||
'hover:opacity-90 disabled:opacity-50'
|
||||
)}
|
||||
>
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
Open in Editor
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={reset}
|
||||
className="flex items-center gap-2 rounded-lg border border-border px-4 py-2.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
Start Over
|
||||
<Play className="h-4 w-4" />
|
||||
Start Flow
|
||||
</button>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onOpenInEditor}
|
||||
disabled={isLoading}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-lg border border-border py-2 text-sm text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-50"
|
||||
>
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
Open in Editor
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onBuildAnother}
|
||||
className="flex items-center gap-2 rounded-lg border border-border px-4 py-2 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
Build Another
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user