File size: 2,631 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import gradio as gr
from utils import (
    initial_state,
    format_todos,
    add_task,
    toggle_complete,
    delete_task
)

# Initialize global constants
INITIAL_TODOS = initial_state()

with gr.Blocks(title="Gradio Todo App") as demo:
    gr.HTML("""
        <div style="text-align: center; max-width: 700px; margin: 0 auto;">
            <h1>Simple Todo List</h1>
            <p style="margin-top: -10px; margin-bottom: 20px;">
                Built with 
                <a href="https://huggingface.co/spaces/akhaliq/anycoder" style="color: var(--primary-500); text-decoration: underline;">anycoder</a>
            </p>
        </div>
    """)

    # --- State Management ---
    todo_state = gr.State(value=INITIAL_TODOS)
    
    # --- Input and Adding Tasks ---
    with gr.Row():
        new_task_input = gr.Textbox(
            placeholder="What needs to be done?", 
            label="New Task",
            scale=3
        )
        add_btn = gr.Button("Add Task", variant="primary", scale=1)

    # --- Todo List Display ---
    # We use Dataframe and rely on the 'select' event to handle actions
    todo_display = gr.Dataframe(
        value=format_todos(INITIAL_TODOS),
        headers=["Task Description", "Status"],
        row_count=(1, "dynamic"),
        col_count=(2, "fixed"),
        datatype=["str", "str"],
        interactive=True,
        label="Tasks",
        show_row_numbers=True,
        wrap=True,
        line_breaks=True,
        height=300
    )

    # --- Action Buttons (triggered by Dataframe selection) ---
    with gr.Row():
        complete_btn = gr.Button("Toggle Complete (Select Row First)", variant="secondary")
        delete_btn = gr.Button("Delete Task (Select Row First)", variant="stop")
    
    # --- Event Handling ---

    # 1. Adding a new task
    add_btn.click(
        fn=add_task,
        inputs=[todo_state, new_task_input],
        outputs=[todo_state, todo_display, new_task_input]
    )
    new_task_input.submit(
        fn=add_task,
        inputs=[todo_state, new_task_input],
        outputs=[todo_state, todo_display, new_task_input]
    )

    # 2. Handling actions upon selection + button click

    # When a user clicks a row and then the Toggle button
    complete_btn.click(
        fn=toggle_complete,
        inputs=[todo_state, todo_display],
        outputs=[todo_state, todo_display]
    )

    # When a user clicks a row and then the Delete button
    delete_btn.click(
        fn=delete_task,
        inputs=[todo_state, todo_display],
        outputs=[todo_state, todo_display]
    )

demo.queue()
if __name__ == "__main__":
    demo.launch()