71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
import inspect
|
|
from dataclasses import dataclass, field
|
|
from typing import Optional
|
|
|
|
from fasthtml.components import Div
|
|
|
|
from myfasthtml.controls.IconsHelper import IconsHelper
|
|
from myfasthtml.controls.helpers import mk
|
|
from myfasthtml.core.dbmanager import DbObject
|
|
from myfasthtml.core.instances import MultipleInstance
|
|
|
|
|
|
@dataclass
|
|
class MenuConf:
|
|
fixed_items: list = field(default_factory=list)
|
|
|
|
|
|
class MenuState(DbObject):
|
|
def __init__(self, owner, save_state):
|
|
with self.initializing():
|
|
super().__init__(owner, save_state=save_state)
|
|
self.last_used: Optional[list] = None
|
|
|
|
|
|
class Menu(MultipleInstance):
|
|
def __init__(self, parent, conf=None, save_state=True, _id=None):
|
|
super().__init__(parent, _id=_id)
|
|
self.conf = conf or MenuConf()
|
|
self._state = MenuState(self, save_state=save_state)
|
|
self.usable_commands = self._get_parent_commands()
|
|
|
|
def _get_parent_commands(self):
|
|
commands_obj = self._parent.commands
|
|
|
|
callables = [
|
|
name
|
|
for name in dir(commands_obj)
|
|
if not name.startswith("_")
|
|
and callable(attr := getattr(commands_obj, name))
|
|
and len(inspect.signature(attr).parameters) == 0
|
|
]
|
|
|
|
return {
|
|
c.name: c for c in [getattr(commands_obj, name)() for name in callables]
|
|
}
|
|
|
|
def _mk_menu(self, command_name):
|
|
if not isinstance(command_name, str):
|
|
return command_name
|
|
|
|
command = self.usable_commands.get(command_name)
|
|
return mk.icon(command.icon or IconsHelper.get("QuestionMark"),
|
|
command=command,
|
|
tooltip=command.description)
|
|
|
|
def render(self):
|
|
return Div(
|
|
Div(
|
|
*[self._mk_menu(command_name) for command_name in self.conf.fixed_items],
|
|
*(
|
|
Div("|"),
|
|
*[self._mk_menu(command_name) for command_name in self._state.last_used[:3]]
|
|
) if self._state.last_used else [],
|
|
cls="flex mb-1"
|
|
),
|
|
id=self._id
|
|
)
|
|
|
|
def __ft__(self):
|
|
return self.render()
|