Skip to content

Commit

Permalink
feat: add logic for editing a task's parameters (except for the order…
Browse files Browse the repository at this point in the history
…) and deletion
  • Loading branch information
Makcal committed May 25, 2024
1 parent 9009e71 commit f784dbb
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 10 deletions.
1 change: 0 additions & 1 deletion src/bot/dialogs/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ async def on_cancel(callback: CallbackQuery, widget, manager: DialogManager):
@staticmethod
async def on_input(message: Message, widget, manager: DialogManager, text: str):
if not manager.dialog_data["args"].validate(text):
await manager.show(ShowMode.SEND)
return
await manager.done(text, show_mode=ShowMode.NO_UPDATE)

Expand Down
6 changes: 5 additions & 1 deletion src/bot/dialogs/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,17 @@ async def on_process_result(start_data: dict, result: bool | None, manager: Dial
show_mode=ShowMode.SEND,
)

if start_data["intent"] == "view_task":
await Loader.load_tasks(manager)
await manager.show()

@staticmethod
@select_finder("tasks")
async def on_select_task(callback: CallbackQuery, widget, manager: DialogManager, task: TaskRepresentation):
await manager.start(
TaskViewSG.main,
data={
"intent": "view",
"intent": "view_task",
"input": TaskViewDialogStartData(task.id),
},
)
Expand Down
160 changes: 152 additions & 8 deletions src/bot/dialogs/task_view.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,53 @@
import re
from dataclasses import dataclass
from datetime import datetime

from aiogram_dialog import Dialog, Window, DialogManager
from aiogram_dialog.widgets.kbd import Cancel
from aiogram.types import CallbackQuery
from aiogram_dialog import Dialog, Window, DialogManager, ShowMode
from aiogram_dialog.widgets.kbd import Cancel, Row, Button
from aiogram_dialog.widgets.text import Format, Const, List, Multi

from src.api import client
from src.api.schemas.method_input_schemas import ModifyTaskBody
from src.api.schemas.method_output_schemas import UserInfo, TaskInfoResponse
from src.bot.dialogs.dialog_communications import TaskViewDialogStartData
from src.bot.dialogs.states import TaskViewSG
from src.bot.dialogs.dialog_communications import (
TaskViewDialogStartData,
ConfirmationDialogStartData,
PromptDialogStartData,
)
from src.bot.dialogs.states import TaskViewSG, ConfirmationSG, PromptSG


class MainWindowConsts:
TASK_VIEW_FORMAT = """Name: {task.name}
Start date: {task.start_date_repr}
Period (in days): {task.period}
Description: {task.description}"""
Period (in days): {task.period}"""
DESCRIPTION_FORMAT = "Description: {task.description}"
DATE_FORMAT = "%d.%m.%Y %H:%M"
ORDER_HEADER = "Order:"
ORDER_ITEM_FORMAT = "{pos}) {item.fullname}"

NAME_INPUT_PATTERN = re.compile(r".+")
DESCRIPTION_INPUT_PATTERN = re.compile(r".+(?:\n\r?.+)*")

@staticmethod
def period_filter(s: str):
return s.isdecimal() and int(s) > 0

@staticmethod
def start_date_filter(text: str) -> bool:
try:
parse_datetime(text)
except ValueError:
return False

BACK_BUTTON_ID = "back_button"
EDIT_NAME_BUTTON_ID = "edit_name_button"
EDIT_DESCRIPTION_BUTTON_ID = "edit_description_button"
EDIT_START_DATE_BUTTON_ID = "edit_start_date_button"
EDIT_PERIOD_BUTTON_ID = "edit_period_button"
EDIT_ORDER_BUTTON_ID = "edit_order_button"
DELETE_BUTTON_ID = "delete_button"


@dataclass
Expand Down Expand Up @@ -55,10 +82,90 @@ class Events:
@staticmethod
async def on_start(start_data: dict, manager: DialogManager):
args: TaskViewDialogStartData = start_data["input"]
task_id = args.task_id
manager.dialog_data["task_id"] = task_id
manager.dialog_data["task_id"] = args.task_id
await Loader.load_task_info(manager)

@staticmethod
async def on_delete_task(callback: CallbackQuery, widget, manager: DialogManager):
await manager.start(
ConfirmationSG.main,
data={
"intent": "delete",
"input": ConfirmationDialogStartData("delete the task", yes_message="The task has been deleted"),
},
show_mode=ShowMode.SEND,
)

@staticmethod
async def _prompt_string(intent: str, prompt: PromptDialogStartData, manager: DialogManager):
await manager.start(
PromptSG.main,
data={"intent": intent, "input": prompt},
show_mode=ShowMode.SEND,
)

@staticmethod
async def on_edit_name(callback: CallbackQuery, widget, manager: DialogManager):
await Events._prompt_string(
"edit_name", PromptDialogStartData("a new name", filter=MainWindowConsts.NAME_INPUT_PATTERN), manager
)

@staticmethod
async def on_edit_description(callback: CallbackQuery, widget, manager: DialogManager):
await Events._prompt_string(
"edit_description",
PromptDialogStartData("a new description", filter=MainWindowConsts.DESCRIPTION_INPUT_PATTERN),
manager,
)

@staticmethod
async def on_edit_start_date(callback: CallbackQuery, widget, manager: DialogManager):
await Events._prompt_string(
"edit_start_date",
PromptDialogStartData("a new start date", filter=MainWindowConsts.start_date_filter),
manager,
)

@staticmethod
async def on_edit_period(callback: CallbackQuery, widget, manager: DialogManager):
await Events._prompt_string(
"edit_period", PromptDialogStartData("a new period", filter=MainWindowConsts.period_filter), manager
)

@staticmethod
async def on_process_result(start_data: dict, result: bool | str | None, manager: DialogManager):
if not isinstance(start_data, dict):
return

task_id = manager.dialog_data["task_id"]
user_id = manager.event.from_user.id
if start_data["intent"] == "delete":
if result:
await client.delete_task(task_id, user_id)
await manager.done(show_mode=ShowMode.SEND)
return
elif start_data["intent"] == "edit_name":
if result is not None:
await client.modify_task(ModifyTaskBody(id=task_id, name=result), user_id)
await Loader.load_task_info(manager)
elif start_data["intent"] == "edit_description":
if result is not None:
await client.modify_task(ModifyTaskBody(id=task_id, description=result), user_id)
await Loader.load_task_info(manager)
elif start_data["intent"] == "edit_start_date":
if result is not None:
await client.modify_task(ModifyTaskBody(id=task_id, start_date=parse_datetime(result)), user_id)
await Loader.load_task_info(manager)
elif start_data["intent"] == "edit_period":
if result is not None:
await client.modify_task(ModifyTaskBody(id=task_id, period=result), user_id)
await Loader.load_task_info(manager)
await manager.show(ShowMode.SEND)


def parse_datetime(text: str) -> datetime:
return datetime.strptime(text, MainWindowConsts.DATE_FORMAT)


async def getter(dialog_manager: DialogManager, **kwargs):
task: TaskInfoResponse = dialog_manager.dialog_data["task"]
Expand All @@ -73,6 +180,7 @@ async def getter(dialog_manager: DialogManager, **kwargs):
task_view_dialog = Dialog(
Window(
Format(MainWindowConsts.TASK_VIEW_FORMAT),
Format(MainWindowConsts.DESCRIPTION_FORMAT, when=lambda data, w, m: data["task"].description),
Multi(
Const(MainWindowConsts.ORDER_HEADER),
List(
Expand All @@ -81,9 +189,45 @@ async def getter(dialog_manager: DialogManager, **kwargs):
),
when="executors",
),
Row(
Button(
Const("Edit name"),
id=MainWindowConsts.EDIT_NAME_BUTTON_ID,
on_click=Events.on_edit_name,
),
Button(
Const("Edit description"),
id=MainWindowConsts.EDIT_DESCRIPTION_BUTTON_ID,
on_click=Events.on_edit_description,
),
),
Row(
Button(
Const("Edit start date"),
id=MainWindowConsts.EDIT_START_DATE_BUTTON_ID,
on_click=Events.on_edit_start_date,
),
Button(
Const("Edit period"),
id=MainWindowConsts.EDIT_PERIOD_BUTTON_ID,
on_click=Events.on_edit_period,
),
),
Row(
Button(
Const("Delete"),
id=MainWindowConsts.DELETE_BUTTON_ID,
on_click=Events.on_delete_task,
),
Button(
Const("Edit order"),
id=MainWindowConsts.EDIT_ORDER_BUTTON_ID,
),
),
Cancel(Const("Back"), MainWindowConsts.BACK_BUTTON_ID),
state=TaskViewSG.main,
getter=getter,
),
on_start=Events.on_start,
on_process_result=Events.on_process_result,
)

0 comments on commit f784dbb

Please sign in to comment.