-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature/reflex app maintenance (#234)
# PR Context - harmonize mex-drop setup and style further with mex-editor - so that we can (maybe) have a mex ui-kit repo at some point - setup inspo robert-koch-institut/mex-editor#245 - style inspo robert-koch-institut/mex-editor#241 # Added - update mex-common to version 0.49.3 - BREAKING: you must start the local dev mode simply with `pdm run drop` (no 2nd run) - move custom backend exception handler to its own module - move custom api code to its own package `mex.drop.api` - align general layout functions (page, logo, navbar, etc) with mex-editor - align login component and navbar state handling with mex-editor - update styling with more idiomatic variable syntax and responsive scaling # Fixed - decorate state handlers with `@rx.event` to satisfy new reflex versions
- Loading branch information
1 parent
f5c7004
commit 5684409
Showing
29 changed files
with
595 additions
and
465 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import reflex as rx | ||
from reflex.event import EventSpec | ||
|
||
|
||
def custom_backend_handler(exception: Exception) -> EventSpec: | ||
"""Custom backend exception handler.""" | ||
if str(exception) == "401: Missing authentication header X-API-Key.": | ||
return rx.toast.error("Please enter your API Key.") | ||
if str(exception) == "401: The provided API Key is not recognized.": | ||
return rx.toast.error("Invalid API Key.") | ||
return rx.toast.error(f"Backend Error: {exception}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
from typing import cast | ||
|
||
import reflex as rx | ||
|
||
from mex.drop.models import NavItem, User | ||
from mex.drop.state import State | ||
|
||
|
||
def user_button() -> rx.Component: | ||
"""Return a user button with an icon that indicates their access rights.""" | ||
return rx.button( | ||
rx.icon(tag="user_round_cog"), | ||
variant="ghost", | ||
style={"marginTop": "0"}, | ||
) | ||
|
||
|
||
def user_menu() -> rx.Component: | ||
"""Return a user menu with a trigger, the current X-System and a logout button.""" | ||
return rx.menu.root( | ||
rx.menu.trigger( | ||
user_button(), | ||
custom_attrs={"data-testid": "user-menu"}, | ||
), | ||
rx.menu.content( | ||
rx.menu.item(cast(User, State.user).x_system, disabled=True), | ||
rx.menu.separator(), | ||
rx.menu.item( | ||
"Logout", | ||
on_select=State.logout, | ||
), | ||
), | ||
) | ||
|
||
|
||
def nav_link(item: NavItem) -> rx.Component: | ||
"""Return a link component for the given navigation item.""" | ||
return rx.link( | ||
rx.text(item.title, size="4", weight="medium"), | ||
href=item.path, | ||
underline=item.underline, | ||
class_name="nav-item", | ||
) | ||
|
||
|
||
def app_logo() -> rx.Component: | ||
"""Return the app logo with icon and label.""" | ||
return rx.hstack( | ||
rx.icon( | ||
"droplets", | ||
size=28, | ||
), | ||
rx.heading( | ||
"MEx Drop", | ||
weight="medium", | ||
style={"userSelect": "none"}, | ||
), | ||
custom_attrs={"data-testid": "app-logo"}, | ||
) | ||
|
||
|
||
def nav_bar() -> rx.Component: | ||
"""Return a navigation bar component.""" | ||
return rx.vstack( | ||
rx.box( | ||
style={ | ||
"height": "var(--space-6)", | ||
"width": "100%", | ||
"backdropFilter": " var(--backdrop-filter-panel)", | ||
"backgroundColor": "var(--card-background-color)", | ||
}, | ||
), | ||
rx.card( | ||
rx.hstack( | ||
app_logo(), | ||
rx.divider(orientation="vertical", size="2"), | ||
rx.hstack( | ||
rx.foreach(State.nav_items, nav_link), | ||
justify="start", | ||
spacing="4", | ||
), | ||
rx.divider(orientation="vertical", size="2"), | ||
user_menu(), | ||
rx.spacer(), | ||
rx.color_mode.button(), | ||
justify="between", | ||
align_items="center", | ||
), | ||
size="2", | ||
custom_attrs={"data-testid": "nav-bar"}, | ||
style={ | ||
"width": "100%", | ||
"marginTop": "calc(-1 * var(--base-card-border-width))", | ||
}, | ||
), | ||
spacing="0", | ||
style={ | ||
"maxWidth": "calc(1480px * var(--scaling))", | ||
"minWidth": "calc(800px * var(--scaling))", | ||
"position": "fixed", | ||
"top": "0", | ||
"width": "100%", | ||
"zIndex": "1000", | ||
}, | ||
) | ||
|
||
|
||
def page(*children: rx.Component) -> rx.Component: | ||
"""Return a page fragment with navigation bar and given children.""" | ||
return rx.cond( | ||
State.user, | ||
rx.center( | ||
nav_bar(), | ||
rx.hstack( | ||
*children, | ||
style={ | ||
"maxWidth": "calc(1480px * var(--scaling))", | ||
"minWidth": "calc(800px * var(--scaling))", | ||
"padding": "calc(var(--space-6) * 4) var(--space-6) var(--space-6)", | ||
"width": "100%", | ||
}, | ||
custom_attrs={"data-testid": "page-body"}, | ||
), | ||
), | ||
rx.center( | ||
rx.spinner(size="3"), | ||
style={"marginTop": "40vh"}, | ||
), | ||
) |
Oops, something went wrong.