'use client' import type { BlockEnum } from '@/app/components/workflow/types' import type { WorkflowGenPlan } from '@/service/workflow-generator' import { memo } from 'react' import { useTranslation } from 'react-i18next' import { SkeletonContainer, SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton' import BlockIcon from '@/app/components/workflow/block-icon' type Props = Readonly<{ /** * The planner result once it has streamed in, or ``null`` while the planner * is still running. Drives the two honest phases of the generation: * "Planning…" (skeleton outline) → plan outline + "Building…". */ plan: WorkflowGenPlan | null }> // Stable keys for the planning skeleton's placeholder rows — avoids array-index // keys while still rendering a fixed-length outline. const SKELETON_ROWS = ['s1', 's2', 's3', 's4'] as const // While the planner runs we render a skeleton shaped like the node list that's // about to arrive, using the shared Skeleton primitives. The pane fills in // place instead of jerking from a centred spinner to a left-aligned list. const PlanningSkeleton = memo(() => { const { t } = useTranslation('workflow') return (
{SKELETON_ROWS.map((key) => (
))}
) }) PlanningSkeleton.displayName = 'PlanningSkeleton' /** * Plan-first loading view for the generator's right pane. * * Replaces the old guessed phase timer (``generation-phases``): the backend now * streams the real planner result, so we show a skeleton outline until it * arrives, then the actual node outline — rendered with the shared workflow * ``BlockIcon`` so each step shows the same icon the user will see on the * canvas — while the builder fills in the graph. */ const GenerationPlan = ({ plan }: Props) => { const { t } = useTranslation('workflow') if (!plan) return return (
{(plan.icon || plan.app_name || plan.title) && (
{plan.icon && ( )}
{plan.app_name || plan.title}
{plan.description && (
{plan.description}
)}
)}
    {plan.nodes.map((node) => (
  1. {node.label} ·{node.node_type}
    {node.purpose && (
    {node.purpose}
    )}
  2. ))}
) } export default memo(GenerationPlan)