summaryrefslogtreecommitdiff
path: root/makima/frontend/src/components/contracts/TaskDerivationPreview.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src/components/contracts/TaskDerivationPreview.tsx')
-rw-r--r--makima/frontend/src/components/contracts/TaskDerivationPreview.tsx221
1 files changed, 0 insertions, 221 deletions
diff --git a/makima/frontend/src/components/contracts/TaskDerivationPreview.tsx b/makima/frontend/src/components/contracts/TaskDerivationPreview.tsx
deleted file mode 100644
index 07421ef..0000000
--- a/makima/frontend/src/components/contracts/TaskDerivationPreview.tsx
+++ /dev/null
@@ -1,221 +0,0 @@
-import { useState, useCallback } from "react";
-
-export interface ParsedTask {
- name: string;
- description?: string;
- group?: string;
- order: number;
- completed: boolean;
- dependencies: string[];
-}
-
-interface TaskDerivationPreviewProps {
- tasks: ParsedTask[];
- groups: string[];
- fileName: string;
- onCreateTasks: (selectedTasks: ParsedTask[]) => void;
- onCancel: () => void;
- loading?: boolean;
-}
-
-export function TaskDerivationPreview({
- tasks,
- groups,
- fileName,
- onCreateTasks,
- onCancel,
- loading = false,
-}: TaskDerivationPreviewProps) {
- const [selectedIndices, setSelectedIndices] = useState<Set<number>>(
- new Set(tasks.map((_, i) => i)) // Select all by default
- );
-
- const toggleTask = useCallback((index: number) => {
- setSelectedIndices((prev) => {
- const newSet = new Set(prev);
- if (newSet.has(index)) {
- newSet.delete(index);
- } else {
- newSet.add(index);
- }
- return newSet;
- });
- }, []);
-
- const selectAll = useCallback(() => {
- setSelectedIndices(new Set(tasks.map((_, i) => i)));
- }, [tasks]);
-
- const selectNone = useCallback(() => {
- setSelectedIndices(new Set());
- }, []);
-
- const handleCreate = useCallback(() => {
- const selectedTasks = tasks.filter((_, i) => selectedIndices.has(i));
- onCreateTasks(selectedTasks);
- }, [tasks, selectedIndices, onCreateTasks]);
-
- // Group tasks by their group property
- const tasksByGroup = tasks.reduce((acc, task, index) => {
- const groupKey = task.group || "Ungrouped";
- if (!acc[groupKey]) {
- acc[groupKey] = [];
- }
- acc[groupKey].push({ task, index });
- return acc;
- }, {} as Record<string, { task: ParsedTask; index: number }[]>);
-
- const selectedCount = selectedIndices.size;
- const totalCount = tasks.length;
-
- return (
- <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
- <div className="w-full max-w-2xl p-6 bg-[#0a1628] border border-[rgba(117,170,252,0.3)] max-h-[80vh] flex flex-col">
- {/* Header */}
- <div className="flex items-center justify-between mb-4">
- <div>
- <h3 className="font-mono text-sm text-[#75aafc] uppercase">
- Create Tasks from Document
- </h3>
- <p className="font-mono text-xs text-[#555] mt-1">
- Source: {fileName}
- </p>
- </div>
- <div className="flex items-center gap-2">
- <button
- onClick={selectAll}
- className="font-mono text-[10px] text-[#75aafc] hover:text-[#9bc3ff] transition-colors"
- >
- Select All
- </button>
- <span className="text-[#555]">|</span>
- <button
- onClick={selectNone}
- className="font-mono text-[10px] text-[#75aafc] hover:text-[#9bc3ff] transition-colors"
- >
- Select None
- </button>
- </div>
- </div>
-
- {/* Task List */}
- <div className="flex-1 overflow-y-auto space-y-4 mb-4">
- {groups.length > 0 ? (
- // Grouped view
- Object.entries(tasksByGroup).map(([groupName, groupTasks]) => (
- <div key={groupName} className="space-y-2">
- <h4 className="font-mono text-xs text-[#9bc3ff] uppercase border-b border-[rgba(117,170,252,0.2)] pb-1">
- {groupName}
- </h4>
- {groupTasks.map(({ task, index }) => (
- <TaskItem
- key={index}
- task={task}
- index={index}
- selected={selectedIndices.has(index)}
- onToggle={() => toggleTask(index)}
- />
- ))}
- </div>
- ))
- ) : (
- // Flat view
- tasks.map((task, index) => (
- <TaskItem
- key={index}
- task={task}
- index={index}
- selected={selectedIndices.has(index)}
- onToggle={() => toggleTask(index)}
- />
- ))
- )}
- </div>
-
- {/* Footer */}
- <div className="flex items-center justify-between pt-4 border-t border-[rgba(117,170,252,0.2)]">
- <span className="font-mono text-xs text-[#555]">
- {selectedCount} of {totalCount} tasks selected
- </span>
- <div className="flex gap-2">
- <button
- onClick={onCancel}
- disabled={loading}
- className="px-4 py-2 font-mono text-xs text-[#9bc3ff] hover:text-[#dbe7ff] transition-colors disabled:opacity-50"
- >
- Cancel
- </button>
- <button
- onClick={handleCreate}
- disabled={loading || selectedCount === 0}
- className="px-4 py-2 font-mono text-xs text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
- >
- {loading ? "Creating..." : `Create ${selectedCount} Task${selectedCount !== 1 ? "s" : ""}`}
- </button>
- </div>
- </div>
-
- {/* Chaining info */}
- {selectedCount > 1 && (
- <p className="font-mono text-[10px] text-[#555] mt-2 text-center">
- Tasks will be chained: each task continues from the previous one's work
- </p>
- )}
- </div>
- </div>
- );
-}
-
-function TaskItem({
- task,
- index,
- selected,
- onToggle,
-}: {
- task: ParsedTask;
- index: number;
- selected: boolean;
- onToggle: () => void;
-}) {
- return (
- <button
- onClick={onToggle}
- className={`w-full text-left p-3 border transition-colors ${
- selected
- ? "border-[#75aafc] bg-[rgba(117,170,252,0.1)]"
- : "border-[rgba(117,170,252,0.15)] hover:border-[rgba(117,170,252,0.3)]"
- }`}
- >
- <div className="flex items-start gap-2">
- <span
- className={`font-mono text-xs mt-0.5 ${
- selected ? "text-[#75aafc]" : "text-[#555]"
- }`}
- >
- {selected ? "[x]" : "[ ]"}
- </span>
- <div className="flex-1 min-w-0">
- <div className="flex items-center gap-2">
- <span className="font-mono text-[10px] text-[#555]">#{index + 1}</span>
- <span className="font-mono text-sm text-[#dbe7ff]">{task.name}</span>
- {task.completed && (
- <span className="font-mono text-[9px] text-green-400 uppercase">
- done in source
- </span>
- )}
- </div>
- {task.description && (
- <p className="font-mono text-xs text-[#555] mt-1 truncate">
- {task.description}
- </p>
- )}
- {task.dependencies.length > 0 && (
- <p className="font-mono text-[10px] text-[#75aafc] mt-1">
- Depends on: {task.dependencies.join(", ")}
- </p>
- )}
- </div>
- </div>
- </button>
- );
-}