"""Functionality for communicating the required user interface for a thing.""" from typing import Any, Optional from pydantic import BaseModel import labthings_fastapi as lt class ActionButton(BaseModel): """The data required for creating an actionButton in Vue. Currently this cannot be used to submitData, or to submitOnEvent. """ thing: str """The Thing "path" for the Thing instance.""" action: str """The name of the action to be triggered.""" poll_interval: int = 1 """The interval for polling in seconds.""" submit_label: str = "Submit" """The label for the action button.""" can_terminate: bool = True """Specify whether the action can be terminated.""" requires_confirmation: bool = False """Specify whether a confirmation modal is needed.""" confirmation_message: str = "Start task?" """The message for the confirmation modal.""" button_primary: bool = True """Specify whether the button is styled as a primary button.""" modal_progress: bool = False """Specify whether to show a progress modal.""" stream_with_modal: bool = False """Specify whether to show a mini stream preview in the progress modal. This option only has an effect if `modal_progress` is True. If `modal_progress` is False, no modal (and therefore no stream preview) is shown. """ notify_on_success: bool = False """Specify whether to a notification on successful completion.""" success_message: str = "Success!" """The message to show on successful completion.""" def action_button_for(thing: lt.Thing, action_name: str, **kwargs: Any) -> ActionButton: """Create a ActionButton data for the specified Thing Action. :param thing: The instance of the thing that has the action. :param action_name: The name of the action to create a button for. :param kwargs: Any attribute of `ActionButton` except for ``thing`` or ``action``. :return: An ActionButton (Pydantic Model) object with all the information the webapp needs to create the action button. """ return ActionButton(thing=thing.name, action=action_name, **kwargs) class PropertyControl(BaseModel): """The data required for creating an actionButton in Vue. Currently this cannot be used to submitData, or to submitOnEvent. """ thing: str """The Thing "path" for the Thing instance.""" property_name: str """The name of the property (or setting).""" label: str """The label to show in the UI""" read_back: bool = False """Whether or not to read back the property after setting. This is useful for hardware settings that may be coerced to the closest value. """ read_back_delay: int = 1000 """The delay in ms before reading back the property.""" options: Optional[dict[str, str | int | float | bool]] = None """A mapping of UI display name to value, used for creating a dropdown. These options aren't validated here in any way. Any invalid values will be rejected when selected. """ step: Optional[int | float] = None """The step size for a numerical input. If the property is not numeric this will be ignored. If this is left as None, then the UI will try to use the ``multipleOf`` field in the property dataSchema. If ``multipleOf`` is not set then the browser default is used. """ def property_control_for( thing: lt.Thing, property_name: str, **kwargs: Any ) -> PropertyControl: """Create an PropertyControl data for the specified Thing Property. :param thing: The instance of the thing that has the property to be controlled. :param property_name: The name of the property to create a control for. :param kwargs: Any attribute of `PropertyControl` except for ``thing`` or ``property_name``. If label is not set here it will be the property name. """ if "label" not in kwargs: kwargs["label"] = property_name return PropertyControl(thing=thing.name, property_name=property_name, **kwargs)