import * as React from 'react' import { useState } from 'react' import { ChevronDown, FileText, Workflow, Database, HardDrive, Layout, Ruler, Calculator, Variable, Users, Globe } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import { mergeClasses } from '../../utils/classNames' import { TextField } from '../TextField/TextField' import { ParagraphField } from '../ParagraphField/ParagraphField' import { DropdownField } from '../Dropdown/DropdownField' /** * Object types supported by the icon set. */ export type ObjectTypeKey = | "document" | "processModel" | "recordType" | "dataStore" | "interface" | "rule" | "expression" | "constant" | "group" | "site" interface IconConfig { icon: LucideIcon bg: string fg: string } const OBJECT_TYPE_ICONS: Record = { document: { icon: FileText, bg: 'bg-green-50', fg: 'text-green-700' }, processModel: { icon: Workflow, bg: 'bg-purple-50', fg: 'text-purple-700' }, recordType: { icon: Database, bg: 'bg-orange-50', fg: 'text-orange-700' }, dataStore: { icon: HardDrive, bg: 'bg-sky-50', fg: 'text-sky-700' }, interface: { icon: Layout, bg: 'bg-teal-50', fg: 'text-teal-700' }, rule: { icon: Ruler, bg: 'bg-blue-50', fg: 'text-blue-700' }, expression: { icon: Calculator, bg: 'bg-pink-50', fg: 'text-pink-700' }, constant: { icon: Variable, bg: 'bg-gray-100', fg: 'text-gray-700' }, group: { icon: Users, bg: 'bg-blue-50', fg: 'text-blue-700' }, site: { icon: Globe, bg: 'bg-purple-50', fg: 'text-purple-700' }, } const OBJECT_TYPE_OPTIONS: { value: ObjectTypeKey; label: string }[] = [ { value: "recordType", label: "Record Type" }, { value: "processModel", label: "Process Model" }, { value: "interface", label: "Interface" }, { value: "rule", label: "Rule" }, { value: "expression", label: "Expression" }, { value: "constant", label: "Constant" }, { value: "document", label: "Document" }, { value: "dataStore", label: "Data Store" }, { value: "group", label: "Group" }, { value: "site", label: "Site" }, ] function getObjectTypeLabel(objectType: ObjectTypeKey): string { return OBJECT_TYPE_OPTIONS.find((o) => o.value === objectType)?.label ?? objectType } export interface TaskPlanItem { /** Unique identifier */ id: string /** Task name / title */ taskName: string /** Object type for icon display */ objectType: ObjectTypeKey /** Name of the object being created/modified */ objectName: string /** Implementation notes */ notes: string } export interface TaskPlanProps { /** The list of task plan items */ tasks: TaskPlanItem[] /** Whether the plan is in edit mode */ editing?: boolean /** Callback when tasks are updated in edit mode */ onTasksChange?: (tasks: TaskPlanItem[]) => void /** Additional Tailwind classes for prototype-specific styling (not part of SAIL API) */ className?: string } /** * TaskPlan Component * Displays a collapsible list of planned tasks with object type icons and details. * Supports read-only and editable modes for plan review workflows. */ export const TaskPlan: React.FC = ({ tasks, editing = false, onTasksChange, className, }) => { const [openItems, setOpenItems] = useState>( new Set(tasks.map((t) => t.id)) ) const toggleItem = (id: string) => { setOpenItems((prev) => { const next = new Set(prev) if (next.has(id)) { next.delete(id) } else { next.add(id) } return next }) } const updateTask = (id: string, updates: Partial) => { if (!onTasksChange) return onTasksChange( tasks.map((t) => (t.id === id ? { ...t, ...updates } : t)) ) } const sailClasses = 'flex flex-col gap-2' return (
{tasks.map((task, index) => { const isOpen = openItems.has(task.id) const iconConfig = OBJECT_TYPE_ICONS[task.objectType] const Icon = iconConfig.icon return (
{isOpen && (
{editing ? ( updateTask(task.id, updates)} /> ) : ( )}
)}
) })}
) } interface ReadOnlyTaskContentProps { task: TaskPlanItem } const ReadOnlyTaskContent: React.FC = ({ task }) => { return (
Object Type {getObjectTypeLabel(task.objectType)}
Object Name {task.objectName}
Implementation Notes

{task.notes}

) } interface EditableTaskContentProps { task: TaskPlanItem onUpdate: (updates: Partial) => void } const EditableTaskContent: React.FC = ({ task, onUpdate }) => { return (
onUpdate({ taskName: val })} marginBelow="LESS" /> o.label)} choiceValues={OBJECT_TYPE_OPTIONS.map((o) => o.value)} value={task.objectType} saveInto={(val) => onUpdate({ objectType: val as ObjectTypeKey })} marginBelow="LESS" /> onUpdate({ objectName: val })} marginBelow="LESS" /> onUpdate({ notes: val })} height="SHORT" marginBelow="NONE" />
) }