build_todo_app / app.py
MarcSkovMadsen's picture
Update app.py
c2f8440 verified
import panel as pn
pn.extension(sizing_mode="stretch_width", design="material")
BUTTON_WIDTH = 125
# We use intslider to avoid teaching users pn.rx. Is that a good thing?
state_changed_count = pn.widgets.IntInput()
tasks = pn.Column()
def update_state_changed_count(*args):
state_changed_count.value += 1
def remove_task(task, *args):
index = tasks.index(task)
tasks.pop(index)
def remove_all_tasks(*args):
tasks.clear()
def create_task(text):
state = pn.widgets.Checkbox(align="center", sizing_mode="fixed")
content = pn.pane.Markdown(text)
remove = pn.widgets.Button(width=BUTTON_WIDTH, icon="trash", sizing_mode="fixed")
task = pn.Row(state, content, remove, sizing_mode="stretch_width")
pn.bind(remove_task, task, remove, watch=True)
# We have to bind the below after the above!
pn.bind(update_state_changed_count, state, remove, watch=True)
return task
def add_task(text, *args):
if not text:
return
new_task = create_task(text)
tasks.append(new_task)
return tasks
def get_state(*args):
total_tasks = len(tasks)
completed_tasks = sum(check[0].value for check in tasks)
return f"{completed_tasks} of {total_tasks} tasks completed"
def can_add(value_input):
return not bool(value_input)
def has_tasks(*args):
return len(tasks) > 0
add_task("Inspect the blades")
add_task("Inspect the nacelle")
add_task("Tighten the bolts")
text_input = pn.widgets.TextInput(name="Task", placeholder="Enter a task")
submit_task = pn.widgets.Button(
name="Add",
align="center",
button_type="primary",
width=BUTTON_WIDTH,
sizing_mode="fixed",
disabled=pn.bind(can_add, text_input.param.value_input)
)
clear = pn.widgets.Button(
name="Remove All",
button_type="primary",
button_style="outline",
width=BUTTON_WIDTH,
sizing_mode="fixed",
visible=pn.bind(has_tasks, state_changed_count)
)
def reset_text_input(*args):
text_input.value = text_input.value_input = ""
pn.bind(add_task, text_input, submit_task, watch=True)
pn.bind(reset_text_input, text_input, submit_task, watch=True)
pn.bind(remove_all_tasks, clear, watch=True)
# We have to bind the below after the above!
pn.bind(update_state_changed_count, text_input, submit_task, clear, watch=True)
status_report = pn.bind(get_state, state_changed_count, tasks.param.objects)
pn.Column(
"## WTG Task List",
status_report,
pn.Row(text_input, submit_task),
tasks,
pn.Row(pn.Spacer(), clear),
max_width=500,
).servable()