fix: default values in subordinate entities based on static_filtering, add: button visibility callbacks in entities' forms

This commit is contained in:
Alexander Kalinovsky
2025-01-22 20:04:32 +01:00
parent 9dd0708a5b
commit b40e588379
7 changed files with 129 additions and 77 deletions

View File

@@ -54,6 +54,9 @@ async def time_picker(
):
keyboard_builder = InlineKeyboardBuilder()
if not current_value:
current_value = time(0, 0)
for i in range(12):
keyboard_builder.row(
InlineKeyboardButton(

View File

@@ -167,6 +167,36 @@ async def process_field_edit_callback(message: Message | CallbackQuery, **kwargs
entity_data = state_data.get("entity_data", {})
if callback_data.context == CommandContext.ENTITY_CREATE:
stack = state_data.get("navigation_stack", [])
prev_callback_data = ContextData.unpack(stack[-1]) if stack else None
if (
prev_callback_data
and prev_callback_data.command == CallbackCommand.ENTITY_LIST
and prev_callback_data.entity_name == entity_descriptor.name
):
prev_form_name = (
prev_callback_data.form_params.split("&")[0]
if prev_callback_data.form_params
else "default"
)
prev_form_params = (
prev_callback_data.form_params.split("&")[1:]
if prev_callback_data.form_params
else []
)
prev_form_list = entity_descriptor.lists.get(
prev_form_name or "default", entity_descriptor.default_list
)
for filt in prev_form_list.static_filters:
if filt.value_type == "const":
entity_data[filt.field_name] = filt.value
elif len(prev_form_params) > filt.param_index:
entity_data[filt.field_name] = prev_form_params[
filt.param_index
]
if (
callback_data.context
in [CommandContext.ENTITY_CREATE, CommandContext.ENTITY_EDIT]

View File

@@ -84,78 +84,94 @@ async def entity_item(
callback_data.form_params or "default", entity_descriptor.default_form
)
if can_edit:
for edit_buttons_row in form.form_buttons:
btn_row = []
for button in edit_buttons_row:
if isinstance(button, FieldEditButton):
field_name = button.field_name
btn_caption = button.caption
if field_name in entity_descriptor.fields_descriptors:
field_descriptor = entity_descriptor.fields_descriptors[
field_name
]
field_value = getattr(entity_item, field_descriptor.field_name)
if btn_caption:
btn_text = get_callable_str(
btn_caption, field_descriptor, entity_item, field_value
)
for edit_buttons_row in form.form_buttons:
btn_row = []
for button in edit_buttons_row:
if button.visibility and not button.visibility(entity_item):
continue
if isinstance(button, FieldEditButton) and can_edit:
field_name = button.field_name
btn_caption = button.caption
if field_name in entity_descriptor.fields_descriptors:
field_descriptor = entity_descriptor.fields_descriptors[
field_name
]
field_value = getattr(entity_item, field_descriptor.field_name)
if btn_caption:
btn_text = get_callable_str(
btn_caption, field_descriptor, entity_item, field_value
)
else:
if field_descriptor.type_base is bool:
btn_text = f"{'【✔︎】 ' if field_value else '【 】 '}{
get_callable_str(
field_descriptor.caption,
field_descriptor,
entity_item,
field_value,
)
if field_descriptor.caption
else field_name
}"
else:
if field_descriptor.type_base is bool:
btn_text = f"{'【✔︎】 ' if field_value else '【 】 '}{
btn_text = (
f"✏️ {
get_callable_str(
field_descriptor.caption,
field_descriptor,
entity_item,
field_value,
)
if field_descriptor.caption
else field_name
}"
else:
btn_text = (
f"✏️ {get_callable_str(field_descriptor.caption, field_descriptor, entity_item, field_value)}"
if field_descriptor.caption
else f"✏️ {field_name}"
)
btn_row.append(
InlineKeyboardButton(
text=btn_text,
callback_data=ContextData(
command=CallbackCommand.FIELD_EDITOR,
context=CommandContext.ENTITY_FIELD_EDIT,
entity_name=entity_descriptor.name,
entity_id=str(entity_item.id),
field_name=field_name,
).pack(),
if field_descriptor.caption
else f"✏️ {field_name}"
)
)
elif isinstance(button, CommandButton):
btn_caption = button.caption
if btn_caption:
btn_text = get_callable_str(
btn_caption, entity_descriptor, entity_item
)
else:
btn_text = button.command
btn_row.append(
InlineKeyboardButton(
text=btn_text,
callback_data=(
button.context_data.pack()
if button.context_data
else ContextData(
command=CallbackCommand.USER_COMMAND,
user_command=button.command,
data=str(entity_item.id),
).pack()
),
callback_data=ContextData(
command=CallbackCommand.FIELD_EDITOR,
context=CommandContext.ENTITY_FIELD_EDIT,
entity_name=entity_descriptor.name,
entity_id=str(entity_item.id),
field_name=field_name,
).pack(),
)
)
if btn_row:
keyboard_builder.row(*btn_row)
elif isinstance(button, CommandButton):
btn_caption = button.caption
if btn_caption:
btn_text = get_callable_str(
btn_caption, entity_descriptor, entity_item
)
else:
btn_text = button.command
if isinstance(button.context_data, ContextData):
btn_cdata = button.context_data
elif callable(button.context_data):
btn_cdata = button.context_data(callback_data, entity_item)
else:
btn_cdata = ContextData(
command=CallbackCommand.USER_COMMAND,
user_command=button.command,
data=str(entity_item.id),
)
btn_row.append(
InlineKeyboardButton(
text=btn_text,
callback_data=btn_cdata.pack(),
)
)
if btn_row:
keyboard_builder.row(*btn_row)
edit_delete_row = []
if can_edit and form.show_edit_button:

View File

@@ -45,21 +45,24 @@ async def entities_menu(
entity_metadata = app.entity_metadata
for entity in entity_metadata.entity_descriptors.values():
if entity.full_name_plural.__class__ == EntityCaptionCallable:
caption = entity.full_name_plural(entity) or entity.name
elif entity.full_name_plural.__class__ == LazyProxy:
caption = f"{f'{entity.icon} ' if entity.icon else ''}{entity.full_name_plural.value or entity.name}"
else:
caption = f"{f'{entity.icon} ' if entity.icon else ''}{entity.full_name_plural or entity.name}"
keyboard_builder.row(
InlineKeyboardButton(
text=caption,
callback_data=ContextData(
command=CallbackCommand.ENTITY_LIST, entity_name=entity.name
).pack(),
if entity.show_in_entities_menu:
if entity.full_name_plural.__class__ == EntityCaptionCallable:
caption = entity.full_name_plural(entity) or entity.name
elif entity.full_name_plural.__class__ == LazyProxy:
caption = f"{f'{entity.icon} ' if entity.icon else ''}{entity.full_name_plural.value or entity.name}"
else:
caption = f"{f'{entity.icon} ' if entity.icon else ''}{entity.full_name_plural or entity.name}"
keyboard_builder.row(
InlineKeyboardButton(
text=caption,
callback_data=ContextData(
command=CallbackCommand.ENTITY_LIST, entity_name=entity.name
).pack(),
)
)
)
context = pop_navigation_context(navigation_stack)
if context: