redesign error boundary screen (#4329)
* redesign error boundary screen * pyi time * add color * i hate python 3.9
This commit is contained in:
parent
7cf3050da0
commit
a1158cdb1c
@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, Tuple
|
||||||
|
|
||||||
from reflex.compiler.compiler import _compile_component
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.el import div, p
|
from reflex.components.datadisplay.logo import svg_logo
|
||||||
from reflex.event import EventHandler
|
from reflex.components.el import a, button, details, div, h2, hr, p, pre, summary
|
||||||
|
from reflex.event import EventHandler, set_clipboard
|
||||||
from reflex.state import FrontendEventExceptionState
|
from reflex.state import FrontendEventExceptionState
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
from reflex.vars.function import ArgsFunctionOperation
|
||||||
|
|
||||||
|
|
||||||
def on_error_spec(
|
def on_error_spec(
|
||||||
@ -40,38 +41,7 @@ class ErrorBoundary(Component):
|
|||||||
on_error: EventHandler[on_error_spec]
|
on_error: EventHandler[on_error_spec]
|
||||||
|
|
||||||
# Rendered instead of the children when an error is caught.
|
# Rendered instead of the children when an error is caught.
|
||||||
Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
|
fallback_render: Var[Component]
|
||||||
_var_type=Component
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_custom_code(self) -> List[str]:
|
|
||||||
"""Add custom Javascript code into the page that contains this component.
|
|
||||||
|
|
||||||
Custom code is inserted at module level, after any imports.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The custom code to add.
|
|
||||||
"""
|
|
||||||
fallback_container = div(
|
|
||||||
p("Ooops...Unknown Reflex error has occured:"),
|
|
||||||
p(
|
|
||||||
Var(_js_expr="error.message"),
|
|
||||||
color="red",
|
|
||||||
),
|
|
||||||
p("Please contact the support."),
|
|
||||||
)
|
|
||||||
|
|
||||||
compiled_fallback = _compile_component(fallback_container)
|
|
||||||
|
|
||||||
return [
|
|
||||||
f"""
|
|
||||||
function Fallback({{ error, resetErrorBoundary }}) {{
|
|
||||||
return (
|
|
||||||
{compiled_fallback}
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props):
|
def create(cls, *children, **props):
|
||||||
@ -86,6 +56,99 @@ class ErrorBoundary(Component):
|
|||||||
"""
|
"""
|
||||||
if "on_error" not in props:
|
if "on_error" not in props:
|
||||||
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
||||||
|
if "fallback_render" not in props:
|
||||||
|
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||||
|
("event_args",),
|
||||||
|
Var.create(
|
||||||
|
div(
|
||||||
|
div(
|
||||||
|
div(
|
||||||
|
h2(
|
||||||
|
"An error occurred while rendering this page.",
|
||||||
|
font_size="1.25rem",
|
||||||
|
font_weight="bold",
|
||||||
|
),
|
||||||
|
p(
|
||||||
|
"This is an error with the application itself.",
|
||||||
|
opacity="0.75",
|
||||||
|
),
|
||||||
|
details(
|
||||||
|
summary("Error message", padding="0.5rem"),
|
||||||
|
div(
|
||||||
|
div(
|
||||||
|
pre(
|
||||||
|
Var(
|
||||||
|
_js_expr="event_args.error.stack",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
padding="0.5rem",
|
||||||
|
width="fit-content",
|
||||||
|
),
|
||||||
|
width="100%",
|
||||||
|
max_height="50vh",
|
||||||
|
overflow="auto",
|
||||||
|
background="#000",
|
||||||
|
color="#fff",
|
||||||
|
border_radius="0.25rem",
|
||||||
|
),
|
||||||
|
button(
|
||||||
|
"Copy",
|
||||||
|
on_click=set_clipboard(
|
||||||
|
Var(_js_expr="event_args.error.stack"),
|
||||||
|
),
|
||||||
|
padding="0.35rem 0.75rem",
|
||||||
|
margin="0.5rem",
|
||||||
|
background="#fff",
|
||||||
|
color="#000",
|
||||||
|
border="1px solid #000",
|
||||||
|
border_radius="0.25rem",
|
||||||
|
font_weight="bold",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
display="flex",
|
||||||
|
flex_direction="column",
|
||||||
|
gap="1rem",
|
||||||
|
max_width="50ch",
|
||||||
|
border="1px solid #888888",
|
||||||
|
border_radius="0.25rem",
|
||||||
|
padding="1rem",
|
||||||
|
),
|
||||||
|
hr(
|
||||||
|
border_color="currentColor",
|
||||||
|
opacity="0.25",
|
||||||
|
),
|
||||||
|
a(
|
||||||
|
div(
|
||||||
|
"Built with ",
|
||||||
|
svg_logo("currentColor"),
|
||||||
|
display="flex",
|
||||||
|
align_items="baseline",
|
||||||
|
justify_content="center",
|
||||||
|
font_family="monospace",
|
||||||
|
gap="0.5rem",
|
||||||
|
),
|
||||||
|
href="https://reflex.dev",
|
||||||
|
),
|
||||||
|
display="flex",
|
||||||
|
flex_direction="column",
|
||||||
|
gap="1rem",
|
||||||
|
),
|
||||||
|
height="100%",
|
||||||
|
width="100%",
|
||||||
|
position="absolute",
|
||||||
|
display="flex",
|
||||||
|
align_items="center",
|
||||||
|
justify_content="center",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_var_type=Component,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||||
|
("event_args",),
|
||||||
|
props["fallback_render"],
|
||||||
|
_var_type=Component,
|
||||||
|
)
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# ------------------- DO NOT EDIT ----------------------
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
from typing import Any, Dict, List, Optional, Tuple, Union, overload
|
from typing import Any, Dict, Optional, Tuple, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import BASE_STATE, EventType
|
||||||
@ -15,13 +15,12 @@ def on_error_spec(
|
|||||||
) -> Tuple[Var[str], Var[str]]: ...
|
) -> Tuple[Var[str], Var[str]]: ...
|
||||||
|
|
||||||
class ErrorBoundary(Component):
|
class ErrorBoundary(Component):
|
||||||
def add_custom_code(self) -> List[str]: ...
|
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
Fallback_component: Optional[Union[Component, Var[Component]]] = None,
|
fallback_render: Optional[Union[Component, Var[Component]]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
id: Optional[Any] = None,
|
id: Optional[Any] = None,
|
||||||
@ -57,7 +56,7 @@ class ErrorBoundary(Component):
|
|||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
on_error: Fired when the boundary catches an error.
|
on_error: Fired when the boundary catches an error.
|
||||||
Fallback_component: Rendered instead of the children when an error is caught.
|
fallback_render: Rendered instead of the children when an error is caught.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
id: The id for the component.
|
id: The id for the component.
|
||||||
|
@ -171,6 +171,14 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def color_mode_cond(light: Any, dark: Any = None) -> Var: ...
|
||||||
|
|
||||||
|
|
||||||
def color_mode_cond(light: Any, dark: Any = None) -> Var | Component:
|
def color_mode_cond(light: Any, dark: Any = None) -> Var | Component:
|
||||||
"""Create a component or Prop based on color_mode.
|
"""Create a component or Prop based on color_mode.
|
||||||
|
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
"""A Reflex logo component."""
|
"""A Reflex logo component."""
|
||||||
|
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
|
|
||||||
|
|
||||||
def logo(**props):
|
def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white")):
|
||||||
"""A Reflex logo.
|
"""A Reflex logo SVG.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
**props: The props to pass to the component.
|
color: The color of the logo.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The logo component.
|
The Reflex logo SVG.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def logo_path(d):
|
def logo_path(d):
|
||||||
return rx.el.svg.path(
|
return rx.el.svg.path(
|
||||||
d=d,
|
d=d,
|
||||||
fill=rx.color_mode_cond("#110F1F", "white"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
paths = [
|
paths = [
|
||||||
@ -28,18 +29,30 @@ def logo(**props):
|
|||||||
"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z",
|
"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
return rx.el.svg(
|
||||||
|
*[logo_path(d) for d in paths],
|
||||||
|
width="56",
|
||||||
|
height="12",
|
||||||
|
viewBox="0 0 56 12",
|
||||||
|
fill=color,
|
||||||
|
xmlns="http://www.w3.org/2000/svg",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def logo(**props):
|
||||||
|
"""A Reflex logo.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
**props: The props to pass to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The logo component.
|
||||||
|
"""
|
||||||
return rx.center(
|
return rx.center(
|
||||||
rx.link(
|
rx.link(
|
||||||
rx.hstack(
|
rx.hstack(
|
||||||
"Built with ",
|
"Built with ",
|
||||||
rx.el.svg(
|
svg_logo(),
|
||||||
*[logo_path(d) for d in paths],
|
|
||||||
width="56",
|
|
||||||
height="12",
|
|
||||||
viewBox="0 0 56 12",
|
|
||||||
fill="none",
|
|
||||||
xmlns="http://www.w3.org/2000/svg",
|
|
||||||
),
|
|
||||||
text_align="center",
|
text_align="center",
|
||||||
align="center",
|
align="center",
|
||||||
padding="1em",
|
padding="1em",
|
||||||
|
@ -899,7 +899,7 @@ def remove_session_storage(key: str) -> EventSpec:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_clipboard(content: str) -> EventSpec:
|
def set_clipboard(content: Union[str, Var[str]]) -> EventSpec:
|
||||||
"""Set the text in content in the clipboard.
|
"""Set the text in content in the clipboard.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
Loading…
Reference in New Issue
Block a user