reflex/reflex/components/core/banner.py
Masen Furer 7fb9747fa7
Fix missing getEventURL function in connection banner (#2557)
After a previous PR replaced `getEventURL` with `getBackendURL`, the banner
code was not updated, leading to problems rendering the connection banner.
2024-02-08 11:53:38 -08:00

114 lines
3.2 KiB
Python

"""Banner components."""
from __future__ import annotations
from typing import Optional
from reflex.components.base.bare import Bare
from reflex.components.chakra.layout import Box
from reflex.components.chakra.overlay.modal import Modal
from reflex.components.chakra.typography import Text
from reflex.components.component import Component
from reflex.components.core.cond import cond
from reflex.constants import Hooks, Imports
from reflex.utils import imports
from reflex.vars import Var, VarData
connect_error_var_data: VarData = VarData( # type: ignore
imports=Imports.EVENTS,
hooks={Hooks.EVENTS},
)
connection_error: Var = Var.create_safe(
value="(connectError !== null) ? connectError.message : ''",
_var_is_local=False,
_var_is_string=False,
)._replace(merge_var_data=connect_error_var_data)
has_connection_error: Var = Var.create_safe(
value="connectError !== null",
_var_is_string=False,
)._replace(_var_type=bool, merge_var_data=connect_error_var_data)
class WebsocketTargetURL(Bare):
"""A component that renders the websocket target URL."""
def _get_imports(self) -> imports.ImportDict:
return {
"/utils/state.js": [imports.ImportVar(tag="getBackendURL")],
"/env.json": [imports.ImportVar(tag="env", is_default=True)],
}
@classmethod
def create(cls) -> Component:
"""Create a websocket target URL component.
Returns:
The websocket target URL component.
"""
return super().create(contents="{getBackendURL(env.EVENT).href}")
def default_connection_error() -> list[str | Var | Component]:
"""Get the default connection error message.
Returns:
The default connection error message.
"""
return [
"Cannot connect to server: ",
connection_error,
". Check if server is reachable at ",
WebsocketTargetURL.create(),
]
class ConnectionBanner(Component):
"""A connection banner component."""
@classmethod
def create(cls, comp: Optional[Component] = None) -> Component:
"""Create a connection banner component.
Args:
comp: The component to render when there's a server connection error.
Returns:
The connection banner component.
"""
if not comp:
comp = Box.create(
Text.create(
*default_connection_error(),
bg="red",
color="white",
),
textAlign="center",
)
return cond(has_connection_error, comp)
class ConnectionModal(Component):
"""A connection status modal window."""
@classmethod
def create(cls, comp: Optional[Component] = None) -> Component:
"""Create a connection banner component.
Args:
comp: The component to render when there's a server connection error.
Returns:
The connection banner component.
"""
if not comp:
comp = Text.create(*default_connection_error())
return cond(
has_connection_error,
Modal.create(
header="Connection Error",
body=comp,
is_open=has_connection_error,
),
)