File size: 2,432 Bytes
7eb7f6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import numpy as np
import gradio as gr
from gradio.events import SelectData

# --- Data Handling Functions ---

def initial_state():
    """Returns the initial list of todo tasks."""
    # Structure: List of tuples [(description: str, completed: bool)]
    return [
        ("Buy groceries (milk, eggs)", False),
        ("Read Gradio documentation", True),
        ("Plan weekend trip", False),
    ]

def format_todos(todos: list[tuple[str, bool]]) -> list[list[str]]:
    """Converts the internal todo list structure into a format suitable for gr.Dataframe."""
    if not todos:
        return [["No tasks yet.", ""]]

    formatted = []
    for desc, completed in todos:
        status = "✅ Done" if completed else "⬜ Pending"
        formatted.append([desc, status])
    return formatted

def add_task(todos: list[tuple[str, bool]], new_task: str):
    """Adds a new task to the todo list."""
    if new_task and new_task.strip():
        todos.append((new_task.strip(), False))
    
    # Return updated state, updated dataframe display, and cleared input box
    return todos, format_todos(todos), gr.Textbox(value="")

def _get_selected_index(todos: list[tuple[str, bool]], evt: SelectData) -> int | None:
    """Helper to safely retrieve the selected index from event data."""
    if not todos or evt.value[0] == "No tasks yet.":
        return None
    
    # Assuming the selection is always a single row (index[0] gives row index)
    if evt.index is None or len(evt.index) < 1:
        return None
        
    index = evt.index[0]
    return index if 0 <= index < len(todos) else None

def toggle_complete(todos: list[tuple[str, bool]], evt: SelectData):
    """Toggles the completion status of the selected task."""
    index = _get_selected_index(todos, evt)
    
    if index is not None:
        desc, completed = todos[index]
        todos[index] = (desc, not completed)
    
    # Return updated state and updated dataframe display (with selection cleared)
    return todos, gr.Dataframe(value=format_todos(todos), selected_index=None)

def delete_task(todos: list[tuple[str, bool]], evt: SelectData):
    """Deletes the selected task."""
    index = _get_selected_index(todos, evt)
    
    if index is not None:
        del todos[index]
        
    # Return updated state and updated dataframe display (with selection cleared)
    return todos, gr.Dataframe(value=format_todos(todos), selected_index=None)