Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support replacing route on redirect #3072

Merged
merged 3 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions reflex/.templates/web/utils/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,13 @@ export const applyDelta = (state, delta) => {
export const applyEvent = async (event, socket) => {
// Handle special events
if (event.name == "_redirect") {
if (event.payload.external) window.open(event.payload.path, "_blank");
else Router.push(event.payload.path);
if (event.payload.external) {
window.open(event.payload.path, "_blank");
} else if (event.payload.replace) {
Router.replace(event.payload.path);
} else {
Router.push(event.payload.path);
}
return false;
}

Expand Down
13 changes: 11 additions & 2 deletions reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,18 +467,27 @@ def fn():
)


def redirect(path: str | Var[str], external: Optional[bool] = False) -> EventSpec:
def redirect(
path: str | Var[str],
external: Optional[bool] = False,
replace: Optional[bool] = False,
) -> EventSpec:
"""Redirect to a new path.

Args:
path: The path to redirect to.
external: Whether to open in new tab or not.
replace: If True, the current page will not create a new history entry.

Returns:
An event to redirect to the path.
"""
return server_side(
"_redirect", get_fn_signature(redirect), path=path, external=external
"_redirect",
get_fn_signature(redirect),
path=path,
external=external,
replace=replace,
)


Expand Down
39 changes: 29 additions & 10 deletions tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,29 @@ def test_fn_with_args(_, arg1, arg2):
@pytest.mark.parametrize(
"input,output",
[
(("/path", None), 'Event("_redirect", {path:`/path`,external:false})'),
(("/path", True), 'Event("_redirect", {path:`/path`,external:true})'),
(("/path", False), 'Event("_redirect", {path:`/path`,external:false})'),
(
(Var.create_safe("path"), None),
'Event("_redirect", {path:path,external:false})',
("/path", None, None),
'Event("_redirect", {path:`/path`,external:false,replace:false})',
),
(
("/path", True, None),
'Event("_redirect", {path:`/path`,external:true,replace:false})',
),
(
("/path", False, None),
'Event("_redirect", {path:`/path`,external:false,replace:false})',
),
(
(Var.create_safe("path"), None, None),
'Event("_redirect", {path:path,external:false,replace:false})',
),
(
("/path", None, True),
'Event("_redirect", {path:`/path`,external:false,replace:true})',
),
(
("/path", True, True),
'Event("_redirect", {path:`/path`,external:true,replace:true})',
),
],
)
Expand All @@ -174,11 +191,13 @@ def test_event_redirect(input, output):
input: The input for running the test.
output: The expected output to validate the test.
"""
path, external = input
if external is None:
spec = event.redirect(path)
else:
spec = event.redirect(path, external=external)
path, external, replace = input
kwargs = {}
if external is not None:
kwargs["external"] = external
if replace is not None:
kwargs["replace"] = replace
spec = event.redirect(path, **kwargs)
assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_redirect"

Expand Down
Loading