From e6175d6f5ce0f771f675ba4e2d02b15627fff7e8 Mon Sep 17 00:00:00 2001
From: openhands
Date: Wed, 7 Oct 2026 01:48:38 +0000
Subject: [PATCH] fix(frontend): migrate leptos 0.6 -> 0.8 API
- switch to leptos::prelude and leptos_router hooks/components imports
- replace create_signal/create_rw_signal/create_effect/create_action/store_value
with signal/RwSignal::new/Effect::new/Action::new/StoredValue::new
- replace create_resource with a local_resource helper wrapping LocalResource
(avoids the Send bound that gloo-net futures cannot satisfy)
- route paths via the path! macro and add a Routes fallback
- use Action::new_local for actions whose futures are not Send
- into_view -> into_any for heterogeneous view branches
---
Cargo.lock | 946 ++++++++++--------
crates/frontend/Cargo.toml | 4 +-
crates/frontend/src/api.rs | 20 +
crates/frontend/src/components/nav.rs | 4 +-
crates/frontend/src/components/repo_nav.rs | 19 +-
crates/frontend/src/main.rs | 117 +--
crates/frontend/src/pages/actions.rs | 32 +-
crates/frontend/src/pages/admin.rs | 19 +-
crates/frontend/src/pages/compare.rs | 29 +-
crates/frontend/src/pages/dashboard.rs | 81 +-
crates/frontend/src/pages/discussions.rs | 52 +-
crates/frontend/src/pages/org.rs | 47 +-
crates/frontend/src/pages/packages.rs | 41 +-
crates/frontend/src/pages/projects.rs | 64 +-
crates/frontend/src/pages/release.rs | 49 +-
crates/frontend/src/pages/repo/create.rs | 23 +-
crates/frontend/src/pages/repo/issues.rs | 157 ++-
crates/frontend/src/pages/repo/pulls.rs | 56 +-
crates/frontend/src/pages/repo/repo_detail.rs | 152 +--
crates/frontend/src/pages/repo/settings.rs | 113 ++-
crates/frontend/src/pages/repo/wiki.rs | 57 +-
crates/frontend/src/pages/security.rs | 27 +-
crates/frontend/src/pages/user.rs | 63 +-
23 files changed, 1127 insertions(+), 1045 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index f1e97c6..cfc50d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -20,6 +20,17 @@ dependencies = [
"libc",
]
+[[package]]
+name = "any_spawner"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d"
+dependencies = [
+ "futures",
+ "thiserror 2.0.21",
+ "wasm-bindgen-futures",
+]
+
[[package]]
name = "anyhow"
version = "1.0.100"
@@ -27,16 +38,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
-name = "async-recursion"
-version = "1.1.1"
+name = "async-lock"
+version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.113",
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
]
+[[package]]
+name = "async-once-cell"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a"
+
[[package]]
name = "async-trait"
version = "0.1.89"
@@ -56,32 +73,31 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "attribute-derive"
-version = "0.9.2"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f1ee502851995027b06f99f5ffbeffa1406b38d0b318a1ebfa469332c6cbafd"
+checksum = "d2f9ef7a68684657ce9da341c934c73b63df7a3585a61e366d84c84ed5d3d167"
dependencies = [
"attribute-derive-macro",
- "derive-where",
"manyhow",
"proc-macro2",
"quote",
- "syn 2.0.113",
+ "syn 3.0.6",
]
[[package]]
name = "attribute-derive-macro"
-version = "0.9.2"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3601467f634cfe36c4780ca9c75dea9a5b34529c1f2810676a337e7e0997f954"
+checksum = "300d426e5e73549125bb8e4649bdd5508f82c94ddf898fb0517246e71dfb8e98"
dependencies = [
"collection_literals",
"interpolator",
"manyhow",
- "proc-macro-utils 0.8.0",
+ "proc-macro-utils",
"proc-macro2",
"quote",
"quote-use",
- "syn 2.0.113",
+ "syn 3.0.6",
]
[[package]]
@@ -184,6 +200,12 @@ dependencies = [
"uuid",
]
+[[package]]
+name = "base16"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"
+
[[package]]
name = "base64"
version = "0.22.1"
@@ -202,6 +224,15 @@ version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "block-buffer"
version = "0.12.1"
@@ -266,7 +297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06"
dependencies = [
"cfg-if",
- "cpufeatures",
+ "cpufeatures 0.3.1",
"rand_core",
]
@@ -284,33 +315,6 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "ciborium"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
-dependencies = [
- "ciborium-io",
- "ciborium-ll",
- "serde",
-]
-
-[[package]]
-name = "ciborium-io"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
-
-[[package]]
-name = "ciborium-ll"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
-dependencies = [
- "ciborium-io",
- "half",
-]
-
[[package]]
name = "cmake"
version = "0.1.58"
@@ -326,6 +330,17 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
+[[package]]
+name = "codee"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5"
+dependencies = [
+ "serde",
+ "serde_json",
+ "thiserror 2.0.21",
+]
+
[[package]]
name = "collection_literals"
version = "1.0.3"
@@ -344,15 +359,15 @@ dependencies = [
[[package]]
name = "config"
-version = "0.14.1"
+version = "0.15.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf"
+checksum = "38e9fbc53afcec54441422f1c596cd054655b32e70e1cbac956651b7b175a404"
dependencies = [
- "convert_case",
- "nom",
+ "convert_case 0.6.0",
"pathdiff",
- "serde",
+ "serde_core",
"toml",
+ "winnow",
]
[[package]]
@@ -361,6 +376,12 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
+[[package]]
+name = "const-str"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f"
+
[[package]]
name = "const_format"
version = "0.2.35"
@@ -381,6 +402,12 @@ dependencies = [
"unicode-xid",
]
+[[package]]
+name = "const_str_slice_concat"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b"
+
[[package]]
name = "convert_case"
version = "0.6.0"
@@ -390,6 +417,24 @@ dependencies = [
"unicode-segmentation",
]
+[[package]]
+name = "convert_case"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "convert_case_extras"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589c70f0faf8aa9d17787557d5eae854d7755cac50f5c3d12c81d3d57661cebb"
+dependencies = [
+ "convert_case 0.11.0",
+]
+
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -416,6 +461,15 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "cpufeatures"
version = "0.3.1"
@@ -426,10 +480,14 @@ dependencies = [
]
[[package]]
-name = "crunchy"
-version = "0.2.4"
+name = "crypto-common"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
[[package]]
name = "crypto-common"
@@ -450,27 +508,24 @@ dependencies = [
]
[[package]]
-name = "dashmap"
-version = "5.5.3"
+name = "derive-where"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
+checksum = "2e2b94854e8576378ccda7c8de8a66ed8b4e8acbd2c50ec3418ea6c8aaf4b567"
dependencies = [
- "cfg-if",
- "hashbrown 0.14.5",
- "lock_api",
- "once_cell",
- "parking_lot_core",
+ "proc-macro2",
+ "quote",
+ "syn 3.0.6",
]
[[package]]
-name = "derive-where"
-version = "1.6.0"
+name = "digest"
+version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.113",
+ "block-buffer 0.10.4",
+ "crypto-common 0.1.7",
]
[[package]]
@@ -479,9 +534,9 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
dependencies = [
- "block-buffer",
+ "block-buffer 0.12.1",
"const-oid",
- "crypto-common",
+ "crypto-common 0.2.2",
"ctutils",
]
@@ -514,6 +569,16 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+[[package]]
+name = "either_of"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5060e0a4cbf26a87550792688ade88e6b8aec9208613631a7a363bda7bc2d4cd"
+dependencies = [
+ "paste",
+ "pin-project-lite",
+]
+
[[package]]
name = "encoding_rs"
version = "0.8.35"
@@ -529,6 +594,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+[[package]]
+name = "erased"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1731451909bde27714eacba19c2566362a7f35224f52b153d3f42cf60f72472"
+
[[package]]
name = "errno"
version = "0.3.14"
@@ -539,6 +610,26 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "event-listener"
+version = "5.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2"
+dependencies = [
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
+
[[package]]
name = "fallible-iterator"
version = "0.2.0"
@@ -626,6 +717,7 @@ dependencies = [
"futures-core",
"futures-task",
"futures-util",
+ "num_cpus",
]
[[package]]
@@ -675,6 +767,16 @@ dependencies = [
"slab",
]
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
[[package]]
name = "getrandom"
version = "0.2.16"
@@ -770,6 +872,12 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "guardian"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f"
+
[[package]]
name = "h2"
version = "0.4.13"
@@ -789,28 +897,17 @@ dependencies = [
"tracing",
]
-[[package]]
-name = "half"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
-dependencies = [
- "cfg-if",
- "crunchy",
- "zerocopy",
-]
-
[[package]]
name = "hashbrown"
-version = "0.14.5"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
-name = "hashbrown"
-version = "0.16.1"
+name = "hermit-abi"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284"
[[package]]
name = "hmac"
@@ -818,7 +915,7 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
dependencies = [
- "digest",
+ "digest 0.11.3",
]
[[package]]
@@ -890,6 +987,19 @@ dependencies = [
"typenum",
]
+[[package]]
+name = "hydration_context"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "285b05858fe7d58c5eff059f7b46c228fd86996d996c59eb35fc0340d174f640"
+dependencies = [
+ "futures",
+ "or_poisoned",
+ "pin-project-lite",
+ "serde",
+ "throw_error",
+]
+
[[package]]
name = "hyper"
version = "1.8.1"
@@ -1083,12 +1193,12 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.12.1"
+version = "2.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
+checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
dependencies = [
"equivalent",
- "hashbrown 0.16.1",
+ "hashbrown",
]
[[package]]
@@ -1097,15 +1207,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
-[[package]]
-name = "inventory"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e"
-dependencies = [
- "rustversion",
-]
-
[[package]]
name = "ipnet"
version = "2.11.0"
@@ -1120,9 +1221,9 @@ checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763"
[[package]]
name = "itertools"
-version = "0.12.1"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
@@ -1203,183 +1304,168 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-
[[package]]
name = "leptos"
-version = "0.6.15"
+version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cbb3237c274dadf00dcc27db96c52601b40375117178fb24a991cda073624f0"
+checksum = "713ee6895e3d1126ea9781280d01414f5643f3f201a949b71efffac07d735f00"
dependencies = [
+ "any_spawner",
"cfg-if",
+ "either_of",
+ "futures",
+ "getrandom 0.4.3",
+ "hydration_context",
"leptos_config",
"leptos_dom",
+ "leptos_hot_reload",
"leptos_macro",
- "leptos_reactive",
"leptos_server",
+ "oco_ref",
+ "or_poisoned",
+ "paste",
+ "reactive_graph",
+ "rustc-hash",
+ "rustc_version",
+ "send_wrapper",
+ "serde",
+ "serde_json",
+ "serde_qs",
"server_fn",
- "tracing",
+ "slotmap",
+ "tachys",
+ "thiserror 2.0.21",
+ "throw_error",
"typed-builder",
"typed-builder-macro",
"wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm_split_helpers",
"web-sys",
]
[[package]]
name = "leptos_config"
-version = "0.6.15"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62ed778611380ddea47568ac6ad6ec5158d39b5bd59e6c4dcd24efc15dc3dc0d"
+checksum = "0c06f751315bccc0d193fab302ac01d25bcfcd97474d4676440e7e3250dc3fc3"
dependencies = [
"config",
"regex",
"serde",
- "thiserror 1.0.69",
+ "thiserror 2.0.21",
"typed-builder",
]
[[package]]
name = "leptos_dom"
-version = "0.6.15"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8401c46c86c1f4c16dcb7881ed319fcdca9cda9b9e78a6088955cb423afcf119"
+checksum = "35742e9ed8f8aaf9e549b454c68a7ac0992536e06856365639b111f72ab07884"
dependencies = [
- "async-recursion",
- "cfg-if",
- "drain_filter_polyfill",
- "futures",
- "getrandom 0.2.16",
- "html-escape",
- "indexmap",
- "itertools",
"js-sys",
- "leptos_reactive",
- "once_cell",
- "pad-adapter",
- "paste",
- "rustc-hash 1.1.0",
- "serde",
- "serde_json",
- "server_fn",
- "smallvec",
- "tracing",
+ "or_poisoned",
+ "reactive_graph",
+ "send_wrapper",
+ "tachys",
"wasm-bindgen",
- "wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "leptos_hot_reload"
-version = "0.6.15"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cb53d4794240b684a2f4be224b84bee9e62d2abc498cf2bcd643cd565e01d96"
+checksum = "d84989bd3d604e66adbfe13a32bec2ea47bdcb6c9fcd643f784facbb32f6ef10"
dependencies = [
"anyhow",
"camino",
"indexmap",
- "parking_lot",
+ "or_poisoned",
"proc-macro2",
"quote",
"rstml",
"serde",
- "syn 2.0.113",
+ "syn 3.0.6",
"walkdir",
]
[[package]]
name = "leptos_macro"
-version = "0.6.15"
+version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b13bc3db70715cd8218c4535a5af3ae3c0e5fea6f018531fc339377b36bc0e0"
+checksum = "0902af1e6947ffc7e906b7003a165f76f178dc711a47b74241025090b0c32a72"
dependencies = [
"attribute-derive",
"cfg-if",
- "convert_case",
+ "convert_case 0.11.0",
+ "convert_case_extras",
"html-escape",
"itertools",
"leptos_hot_reload",
"prettyplease",
- "proc-macro-error2",
"proc-macro2",
"quote",
"rstml",
+ "rustc_version",
"server_fn_macro",
- "syn 2.0.113",
- "tracing",
+ "syn 3.0.6",
"uuid",
]
[[package]]
-name = "leptos_reactive"
-version = "0.6.15"
+name = "leptos_router"
+version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4161acbf80f59219d8d14182371f57302bc7ff81ee41aba8ba1ff7295727f23"
+checksum = "f92787ebcb5f25af6a67513dacfd75cbffce5bda3f361e2e947c3fc4e3adc14b"
dependencies = [
- "base64 0.22.1",
- "cfg-if",
+ "any_spawner",
+ "either_of",
"futures",
- "indexmap",
+ "gloo-net 0.6.0",
"js-sys",
- "oco_ref",
- "paste",
- "pin-project",
- "rustc-hash 1.1.0",
- "self_cell",
- "serde",
- "serde-wasm-bindgen",
- "serde_json",
- "slotmap",
- "thiserror 1.0.69",
- "tracing",
+ "leptos",
+ "leptos_router_macro",
+ "or_poisoned",
+ "reactive_graph",
+ "rustc_version",
+ "send_wrapper",
+ "tachys",
+ "thiserror 2.0.21",
+ "url",
"wasm-bindgen",
- "wasm-bindgen-futures",
"web-sys",
]
[[package]]
-name = "leptos_router"
-version = "0.6.15"
+name = "leptos_router_macro"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d71dea7d42c0d29c40842750232d3425ed1cf10e313a1f898076d20871dad32"
+checksum = "1bb5c81012dcab0d5cc032a2da0a364a18ce74a0fbeb88f091e9b53a0679bc85"
dependencies = [
- "cfg-if",
- "gloo-net 0.6.0",
- "itertools",
- "js-sys",
- "lazy_static",
- "leptos",
- "linear-map",
- "once_cell",
- "percent-encoding",
- "send_wrapper",
- "serde",
- "serde_json",
- "serde_qs 0.13.0",
- "thiserror 1.0.69",
- "tracing",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.113",
]
[[package]]
name = "leptos_server"
-version = "0.6.15"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a97eb90a13f71500b831c7119ddd3bdd0d7ae0a6b0487cade4fddeed3b8c03f"
+checksum = "202b2d1261c22d886f307934760a6bb566444f68f39b24f6f10defdc23633049"
dependencies = [
- "inventory",
- "lazy_static",
- "leptos_macro",
- "leptos_reactive",
+ "any_spawner",
+ "base64 0.22.1",
+ "codee",
+ "futures",
+ "hydration_context",
+ "or_poisoned",
+ "reactive_graph",
+ "send_wrapper",
"serde",
+ "serde_json",
"server_fn",
- "thiserror 1.0.69",
- "tracing",
+ "tachys",
]
[[package]]
@@ -1397,16 +1483,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "linear-map"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee"
-dependencies = [
- "serde",
- "serde_test",
-]
-
[[package]]
name = "litemap"
version = "0.8.1"
@@ -1436,23 +1512,23 @@ checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f"
[[package]]
name = "manyhow"
-version = "0.10.4"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91ea592d76c0b6471965708ccff7e6a5d277f676b90ab31f4d3f3fc77fade64"
+checksum = "8c69ea6e469ca785c846b25dd69eac9e9c916b51d8ada1f212866787ee1da12d"
dependencies = [
"manyhow-macros",
"proc-macro2",
"quote",
- "syn 2.0.113",
+ "syn 3.0.6",
]
[[package]]
name = "manyhow-macros"
-version = "0.10.4"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c64621e2c08f2576e4194ea8be11daf24ac01249a4f53cd8befcbb7077120ead"
+checksum = "22fc5c1b2c4000056dae3619fea36e79ce79dabfee4907d2dcad6612b189e370"
dependencies = [
- "proc-macro-utils 0.8.0",
+ "proc-macro-utils",
"proc-macro2",
"quote",
]
@@ -1470,7 +1546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98"
dependencies = [
"cfg-if",
- "digest",
+ "digest 0.11.3",
]
[[package]]
@@ -1495,12 +1571,6 @@ dependencies = [
"unicase",
]
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
[[package]]
name = "mio"
version = "1.1.1"
@@ -1513,14 +1583,10 @@ dependencies = [
]
[[package]]
-name = "nom"
-version = "7.1.3"
+name = "next_tuple"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
+checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28"
[[package]]
name = "num-traits"
@@ -1531,6 +1597,16 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "num_cpus"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
[[package]]
name = "objc2-core-foundation"
version = "0.3.2"
@@ -1551,12 +1627,12 @@ dependencies = [
[[package]]
name = "oco_ref"
-version = "0.1.1"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51ebcefb2f0b9a5e0bea115532c8ae4215d1b01eff176d0f4ba4192895c2708"
+checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d"
dependencies = [
"serde",
- "thiserror 1.0.69",
+ "thiserror 2.0.21",
]
[[package]]
@@ -1572,10 +1648,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
-name = "pad-adapter"
-version = "0.1.1"
+name = "or_poisoned"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56d80efc4b6721e8be2a10a5df21a30fa0b470f1539e53d8b4e6e75faf938b63"
+checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd"
+
+[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
@@ -1689,7 +1771,7 @@ dependencies = [
"md-5",
"memchr",
"rand",
- "sha2",
+ "sha2 0.11.0",
"stringprep",
]
@@ -1715,67 +1797,12 @@ dependencies = [
[[package]]
name = "prettyplease"
-version = "0.2.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
-dependencies = [
- "proc-macro2",
- "syn 2.0.113",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr2"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "proc-macro-error2"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
-dependencies = [
- "proc-macro-error-attr2",
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "proc-macro-utils"
-version = "0.8.0"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8"
+checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0"
dependencies = [
"proc-macro2",
- "quote",
- "smallvec",
+ "syn 3.0.6",
]
[[package]]
@@ -1800,15 +1827,14 @@ dependencies = [
[[package]]
name = "proc-macro2-diagnostics"
-version = "0.10.1"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
+checksum = "df921e1ef974ebc8dd9effdb0c037a96928ae8cbf871438e02d6fd67204b595e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.113",
+ "syn 3.0.6",
"version_check",
- "yansi",
]
[[package]]
@@ -1822,7 +1848,7 @@ dependencies = [
"pin-project-lite",
"quinn-proto",
"quinn-udp",
- "rustc-hash 2.1.3",
+ "rustc-hash",
"rustls",
"socket2",
"thiserror 2.0.21",
@@ -1844,7 +1870,7 @@ dependencies = [
"rand",
"rand_pcg",
"ring",
- "rustc-hash 2.1.3",
+ "rustc-hash",
"rustls",
"rustls-pki-types",
"slab",
@@ -1879,9 +1905,9 @@ dependencies = [
[[package]]
name = "quote-use"
-version = "0.8.4"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e"
+checksum = "48356e493823dc3c1d7e9fc7b3ff204ecec48afbdd718fc4134091b88eb63f3d"
dependencies = [
"quote",
"quote-use-macros",
@@ -1889,14 +1915,14 @@ dependencies = [
[[package]]
name = "quote-use-macros"
-version = "0.8.4"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35"
+checksum = "8cf1c5de6a7cc231c71e03c77aa4c7019097859ea7029156b54d2894a8430704"
dependencies = [
- "proc-macro-utils 0.10.0",
+ "proc-macro-utils",
"proc-macro2",
"quote",
- "syn 2.0.113",
+ "syn 3.0.6",
]
[[package]]
@@ -1931,6 +1957,59 @@ dependencies = [
"rand_core",
]
+[[package]]
+name = "reactive_graph"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79f11fac67625645add76313dab8dae510fca0654d96ef98fd8f961a7d2e22c1"
+dependencies = [
+ "any_spawner",
+ "async-lock",
+ "futures",
+ "guardian",
+ "hydration_context",
+ "indexmap",
+ "or_poisoned",
+ "paste",
+ "pin-project-lite",
+ "rustc-hash",
+ "rustc_version",
+ "send_wrapper",
+ "serde",
+ "slotmap",
+ "thiserror 2.0.21",
+ "web-sys",
+]
+
+[[package]]
+name = "reactive_stores"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a29e469b556f25486678e9f5f65fa21a0351d98affde9a7eea9fee286bf8ebd6"
+dependencies = [
+ "guardian",
+ "indexmap",
+ "itertools",
+ "or_poisoned",
+ "paste",
+ "reactive_graph",
+ "reactive_stores_macro",
+ "rustc-hash",
+ "send_wrapper",
+]
+
+[[package]]
+name = "reactive_stores_macro"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d11f1b82859d94577892b8037c35f8a4f066cbb3864583e22e68def0af49a88"
+dependencies = [
+ "convert_case 0.11.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.113",
+]
+
[[package]]
name = "redox_syscall"
version = "0.5.18"
@@ -2025,24 +2104,18 @@ dependencies = [
[[package]]
name = "rstml"
-version = "0.11.2"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe542870b8f59dd45ad11d382e5339c9a1047cde059be136a7016095bbdefa77"
+checksum = "c6bd1bfba3c4c0b57aae906204d9e5744f3f65800ce6c75bd4cc162f2c26f3aa"
dependencies = [
+ "derive-where",
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
- "syn 2.0.113",
- "syn_derive",
- "thiserror 1.0.69",
+ "syn 3.0.6",
+ "thiserror 2.0.21",
]
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
[[package]]
name = "rustc-hash"
version = "2.1.3"
@@ -2192,12 +2265,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "self_cell"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
-
[[package]]
name = "semver"
version = "1.0.28"
@@ -2223,17 +2290,6 @@ dependencies = [
"serde_derive",
]
-[[package]]
-name = "serde-wasm-bindgen"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
-dependencies = [
- "js-sys",
- "serde",
- "wasm-bindgen",
-]
-
[[package]]
name = "serde_core"
version = "1.0.229"
@@ -2280,42 +2336,22 @@ dependencies = [
[[package]]
name = "serde_qs"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c"
-dependencies = [
- "percent-encoding",
- "serde",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "serde_qs"
-version = "0.13.0"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6"
+checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352"
dependencies = [
"percent-encoding",
"serde",
- "thiserror 1.0.69",
+ "thiserror 2.0.21",
]
[[package]]
name = "serde_spanned"
-version = "0.6.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "serde_test"
-version = "1.0.177"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed"
+checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
dependencies = [
- "serde",
+ "serde_core",
]
[[package]]
@@ -2332,25 +2368,29 @@ dependencies = [
[[package]]
name = "server_fn"
-version = "0.6.15"
+version = "0.8.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe"
+checksum = "be8559dd05af1b5b7e363a150616589d5a88af5187273f7f331ba0dae8922812"
dependencies = [
+ "base64 0.22.1",
"bytes",
- "ciborium",
+ "const-str",
"const_format",
- "dashmap",
"futures",
"gloo-net 0.6.0",
"http",
"js-sys",
- "once_cell",
+ "or_poisoned",
+ "pin-project-lite",
+ "rustc_version",
+ "rustversion",
"send_wrapper",
"serde",
"serde_json",
- "serde_qs 0.12.0",
+ "serde_qs",
"server_fn_macro_default",
- "thiserror 1.0.69",
+ "thiserror 2.0.21",
+ "throw_error",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -2361,26 +2401,38 @@ dependencies = [
[[package]]
name = "server_fn_macro"
-version = "0.6.15"
+version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1"
+checksum = "ce79d7b6ab93f7994e5ff4999eb962f2aea370d7c3b91986eb75da738a8e65f9"
dependencies = [
"const_format",
- "convert_case",
+ "convert_case 0.11.0",
"proc-macro2",
"quote",
- "syn 2.0.113",
+ "rustc_version",
+ "syn 3.0.6",
"xxhash-rust",
]
[[package]]
name = "server_fn_macro_default"
-version = "0.6.15"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440"
+checksum = "d9a4f81a0d855f279c3448243138a55cbfdd9851da9341b9c1e5971b90089e61"
dependencies = [
"server_fn_macro",
- "syn 2.0.113",
+ "syn 3.0.6",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.2.17",
+ "digest 0.10.7",
]
[[package]]
@@ -2390,8 +2442,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
dependencies = [
"cfg-if",
- "cpufeatures",
- "digest",
+ "cpufeatures 0.3.1",
+ "digest 0.11.3",
]
[[package]]
@@ -2452,7 +2504,6 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038"
dependencies = [
- "serde",
"version_check",
]
@@ -2517,18 +2568,6 @@ dependencies = [
"unicode-ident",
]
-[[package]]
-name = "syn_derive"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b"
-dependencies = [
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 2.0.113",
-]
-
[[package]]
name = "sync_wrapper"
version = "1.0.2"
@@ -2570,6 +2609,38 @@ dependencies = [
"libc",
]
+[[package]]
+name = "tachys"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e47e2220bb9d2a3be976a22a0fb7685a0b84499bb11ea5cb3bbc82907675ac68"
+dependencies = [
+ "any_spawner",
+ "async-trait",
+ "const_str_slice_concat",
+ "drain_filter_polyfill",
+ "either_of",
+ "erased",
+ "futures",
+ "html-escape",
+ "indexmap",
+ "itertools",
+ "js-sys",
+ "next_tuple",
+ "oco_ref",
+ "or_poisoned",
+ "paste",
+ "reactive_graph",
+ "reactive_stores",
+ "rustc-hash",
+ "rustc_version",
+ "send_wrapper",
+ "slotmap",
+ "throw_error",
+ "wasm-bindgen",
+ "web-sys",
+]
+
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -2610,6 +2681,15 @@ dependencies = [
"syn 3.0.6",
]
+[[package]]
+name = "throw_error"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc0ed6038fcbc0795aca7c92963ddda636573b956679204e044492d2b13c8f64"
+dependencies = [
+ "pin-project-lite",
+]
+
[[package]]
name = "tinystr"
version = "0.8.2"
@@ -2714,44 +2794,42 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.8.23"
+version = "1.1.6+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
+checksum = "920602543f0911ab71da12c50d59701da54c196d1a2bf5cb4b75667f137a406a"
dependencies = [
- "serde",
+ "indexmap",
+ "serde_core",
"serde_spanned",
"toml_datetime",
- "toml_edit",
+ "toml_parser",
+ "toml_writer",
+ "winnow",
]
[[package]]
name = "toml_datetime"
-version = "0.6.11"
+version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
+checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
dependencies = [
- "serde",
+ "serde_core",
]
[[package]]
-name = "toml_edit"
-version = "0.22.27"
+name = "toml_parser"
+version = "1.1.3+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
+checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
dependencies = [
- "indexmap",
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_write",
"winnow",
]
[[package]]
-name = "toml_write"
-version = "0.1.2"
+name = "toml_writer"
+version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
+checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
[[package]]
name = "tower"
@@ -2832,21 +2910,9 @@ checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"log",
"pin-project-lite",
- "tracing-attributes",
"tracing-core",
]
-[[package]]
-name = "tracing-attributes"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.113",
-]
-
[[package]]
name = "tracing-core"
version = "0.1.36"
@@ -2864,18 +2930,18 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typed-builder"
-version = "0.18.2"
+version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77739c880e00693faef3d65ea3aad725f196da38b22fdc7ea6ded6e1ce4d3add"
+checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda"
dependencies = [
"typed-builder-macro",
]
[[package]]
name = "typed-builder-macro"
-version = "0.18.2"
+version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63"
+checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26"
dependencies = [
"proc-macro2",
"quote",
@@ -3089,9 +3155,9 @@ dependencies = [
[[package]]
name = "wasm-streams"
-version = "0.4.2"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
+checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
dependencies = [
"futures-util",
"js-sys",
@@ -3100,6 +3166,28 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "wasm_split_helpers"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab578aae2fe2916edaea06843187d50f87b0965622da0ceef648edca27b385ba"
+dependencies = [
+ "async-once-cell",
+ "wasm_split_macros",
+]
+
+[[package]]
+name = "wasm_split_macros"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e653af7ee4a9ef0fce481a9ec6f43cb78de20d0cdb4f4f5862e1dc6e407e6c8"
+dependencies = [
+ "base16",
+ "quote",
+ "sha2 0.10.9",
+ "syn 2.0.113",
+]
+
[[package]]
name = "web-sys"
version = "0.3.104"
@@ -3379,9 +3467,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
-version = "0.7.14"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
+checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
dependencies = [
"memchr",
]
@@ -3404,12 +3492,6 @@ version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "550a2b930b62486a393c52d5c3b84bff264b28aa437ed64694d31e93b1757af7"
-[[package]]
-name = "yansi"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
-
[[package]]
name = "yoke"
version = "0.8.1"
@@ -3433,26 +3515,6 @@ dependencies = [
"synstructure",
]
-[[package]]
-name = "zerocopy"
-version = "0.8.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.113",
-]
-
[[package]]
name = "zerofrom"
version = "0.1.6"
diff --git a/crates/frontend/Cargo.toml b/crates/frontend/Cargo.toml
index 82bc816..09e6201 100644
--- a/crates/frontend/Cargo.toml
+++ b/crates/frontend/Cargo.toml
@@ -6,8 +6,8 @@ license.workspace = true
repository.workspace = true
[dependencies]
-leptos = { version = "0.6", features = ["csr"] }
-leptos_router = { version = "0.6", features = ["csr"] }
+leptos = { version = "0.8", features = ["csr"] }
+leptos_router = { version = "0.8" }
serde.workspace = true
serde_json.workspace = true
shared = { path = "../shared" }
diff --git a/crates/frontend/src/api.rs b/crates/frontend/src/api.rs
index d2560a3..232b5f7 100644
--- a/crates/frontend/src/api.rs
+++ b/crates/frontend/src/api.rs
@@ -16,10 +16,30 @@
//! place rather than being hand-written at every call site.
use gloo_net::http::Request;
+use leptos::prelude::LocalResource;
use serde::{de::DeserializeOwned, Serialize};
+use std::future::Future;
pub const BASE_URL: &str = "/api/v1";
+/// Reactive async resource for client-side rendering.
+///
+/// `LocalResource` never has to cross a thread boundary, so unlike `Resource`
+/// it accepts a non-`Send` future, which is what `gloo_net` request futures
+/// are. `source` is tracked reactively; when it yields a new value the
+/// `fetcher` runs again.
+pub fn local_resource(
+ source: impl Fn() -> S + 'static,
+ fetcher: impl Fn(S) -> Fut + 'static,
+) -> LocalResource
+where
+ S: PartialEq + 'static,
+ T: 'static,
+ Fut: Future
}>
{move || repos.get().map(|list| {
if list.is_empty() {
- view! { "No repositories yet."
}.into_view()
+ view! { "No repositories yet."
}.into_any()
} else {
view! {
impl IntoView {
}
}/>
- }.into_view()
+ }.into_any()
}
})}
@@ -211,17 +212,17 @@ pub fn Explore() -> impl IntoView {
#[component]
pub fn Search() -> impl IntoView {
let query_map = use_query_map();
- let initial = query_map.with(|q| q.get("q").cloned().unwrap_or_default());
- let (query, set_query) = create_signal(initial);
- let (search_type, set_search_type) = create_signal("repos".to_string()); // repos | issues
+ let initial = query_map.with(|q| q.get("q").unwrap_or_default());
+ let (query, set_query) = signal(initial);
+ let (search_type, set_search_type) = signal("repos".to_string()); // repos | issues
- let (repo_results, set_repo_results) = create_signal(vec![]);
- let (issue_results, set_issue_results) = create_signal(vec![]);
+ let (repo_results, set_repo_results) = signal(vec![]);
+ let (issue_results, set_issue_results) = signal(vec![]);
// Monotonic request generation. A slow earlier request must not overwrite
// the results of a newer one, so each response is applied only if no newer
// search has started since it was issued.
- let generation = create_rw_signal(0u64);
+ let generation = RwSignal::new(0u64);
let run_search = move |q: String, t: String| {
let current = generation.get_untracked() + 1;
@@ -257,8 +258,8 @@ pub fn Search() -> impl IntoView {
// `q` (a cleared header search must clear the box and previous results).
// This single effect drives every load, so there is no duplicate initial
// request racing the mount-time one.
- create_effect(move |_| {
- let q = query_map.with(|q| q.get("q").cloned().unwrap_or_default());
+ Effect::new(move |_| {
+ let q = query_map.with(|q| q.get("q").unwrap_or_default());
set_query.set(q.clone());
run_search(q, search_type.get_untracked());
});
@@ -303,7 +304,7 @@ pub fn Search() -> impl IntoView {
}
}/>
- }.into_view()
+ }.into_any()
} else {
view! {
@@ -317,7 +318,7 @@ pub fn Search() -> impl IntoView {
}
}/>
- }.into_view()
+ }.into_any()
}}
@@ -326,9 +327,9 @@ pub fn Search() -> impl IntoView {
#[component]
pub fn NotificationList() -> impl IntoView {
- let (refresh, set_refresh) = create_signal(0);
- let (action_error, set_action_error) = create_signal(Option::::None);
- let notifs = create_resource(
+ let (refresh, set_refresh) = signal(0);
+ let (action_error, set_action_error) = signal(Option::::None);
+ let notifs = local_resource(
move || refresh.get(),
|_| async move { get::>("/api/v1/notifications").await },
);
@@ -356,7 +357,7 @@ pub fn NotificationList() -> impl IntoView {
"Loading…" }>
{move || notifs.get().map(|list| {
if list.is_empty() {
- view! { "You have no notifications." }.into_view()
+ view! { "You have no notifications." }.into_any()
} else {
view! {
impl IntoView {
{n.subject.clone()}
{if unread {
- view! { " (Unread)" }.into_view()
+ view! { " (Unread)" }.into_any()
} else {
- view! { " (Read)" }.into_view()
+ view! { " (Read)" }.into_any()
}}
{if unread {
- view! { }.into_view()
+ view! { }.into_any()
} else {
- view! { "Read" }.into_view()
+ view! { "Read" }.into_any()
}}
}
}/>
- }.into_view()
+ }.into_any()
}
})}
diff --git a/crates/frontend/src/pages/discussions.rs b/crates/frontend/src/pages/discussions.rs
index 1ec3e76..d15f376 100644
--- a/crates/frontend/src/pages/discussions.rs
+++ b/crates/frontend/src/pages/discussions.rs
@@ -1,7 +1,8 @@
-use crate::api::{api_url, get, get_or, post_json, WRITE_ERROR};
+use crate::api::{api_url, get, get_or, local_resource, post_json, WRITE_ERROR};
use crate::components::RepoNav;
-use leptos::*;
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{
CreateDiscussionCommentOption, CreateDiscussionOption, Discussion, DiscussionComment,
};
@@ -9,17 +10,17 @@ use shared::{
#[component]
pub fn DiscussionList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (show_create, set_show_create) = create_signal(false);
- let (refresh, set_refresh) = create_signal(0);
- let (new_title, set_new_title) = create_signal("".to_string());
- let (new_body, set_new_body) = create_signal("".to_string());
- let (new_category, set_new_category) = create_signal("General".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (show_create, set_show_create) = signal(false);
+ let (refresh, set_refresh) = signal(0);
+ let (new_title, set_new_title) = signal("".to_string());
+ let (new_body, set_new_body) = signal("".to_string());
+ let (new_category, set_new_category) = signal("General".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
- let discussions = create_resource(
+ let discussions = local_resource(
move || (owner(), repo_name(), refresh.get()),
|(o, r, _)| async move {
let url = api_url(&format!("/repos/{}/{}/discussions", o, r));
@@ -76,16 +77,16 @@ pub fn DiscussionList() -> impl IntoView {
{msg}
})}
- }.into_view()
+ }.into_any()
} else {
- view! { }.into_view()
+ view! { }.into_any()
}}
"Loading discussions..." }>
{move || discussions.get().map(|list| {
if list.is_empty() {
- view! { - "No discussions found."
}.into_view()
+ view! { - "No discussions found."
}.into_any()
} else {
view! {
impl IntoView {
}
}/>
- }.into_view()
+ }.into_any()
}
})}
@@ -111,24 +112,23 @@ pub fn DiscussionList() -> impl IntoView {
#[component]
pub fn DiscussionDetail() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
let id = move || {
params.with(|params| {
params
.get("id")
- .cloned()
.unwrap_or_default()
.parse::()
.unwrap_or_default()
})
};
- let (refresh_comments, set_refresh_comments) = create_signal(0);
- let (new_comment_body, set_new_comment_body) = create_signal("".to_string());
- let (comment_error, set_comment_error) = create_signal(Option::::None);
+ let (refresh_comments, set_refresh_comments) = signal(0);
+ let (new_comment_body, set_new_comment_body) = signal("".to_string());
+ let (comment_error, set_comment_error) = signal(Option::::None);
- let discussion = create_resource(
+ let discussion = local_resource(
move || (owner(), repo_name(), id()),
|(o, r, i)| async move {
let url = api_url(&format!("/repos/{}/{}/discussions/{}", o, r, i));
@@ -136,7 +136,7 @@ pub fn DiscussionDetail() -> impl IntoView {
},
);
- let comments = create_resource(
+ let comments = local_resource(
move || (owner(), repo_name(), id(), refresh_comments.get()),
|(o, r, i, _)| async move {
let url = api_url(&format!("/repos/{}/{}/discussions/{}/comments", o, r, i));
@@ -222,9 +222,9 @@ pub fn DiscussionDetail() -> impl IntoView {
})}
- }.into_view()
+ }.into_any()
},
- None => view! { "Discussion Not Found"
}.into_view()
+ None => view! { "Discussion Not Found"
}.into_any()
})}
diff --git a/crates/frontend/src/pages/org.rs b/crates/frontend/src/pages/org.rs
index d144650..8283b5f 100644
--- a/crates/frontend/src/pages/org.rs
+++ b/crates/frontend/src/pages/org.rs
@@ -1,6 +1,7 @@
-use crate::api::{get, get_or, post_json, put_json, WRITE_ERROR};
-use leptos::*;
-use leptos_router::*;
+use crate::api::{get, get_or, local_resource, post_json, put_json, WRITE_ERROR};
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{
AuditLog, CreateOrgOption, CreateTeamOption, OrgMember, Organization, Repository, Team,
UpdateMemberRoleOption,
@@ -9,17 +10,17 @@ use shared::{
#[component]
pub fn OrgProfile() -> impl IntoView {
let params = use_params_map();
- let org_name = move || params.with(|params| params.get("org").cloned().unwrap_or_default());
+ let org_name = move || params.with(|params| params.get("org").unwrap_or_default());
- let (active_tab, set_active_tab) = create_signal("repos".to_string());
- let (refresh, set_refresh) = create_signal(0);
- let (action_error, set_action_error) = create_signal(Option::::None);
+ let (active_tab, set_active_tab) = signal("repos".to_string());
+ let (refresh, set_refresh) = signal(0);
+ let (action_error, set_action_error) = signal(Option::::None);
- let org = create_resource(org_name, |name| async move {
+ let org = local_resource(org_name, |name| async move {
get_or::
- }.into_view(),
+ }.into_any(),
"people" => view! {
"Members & Role Management"
@@ -149,10 +150,10 @@ pub fn OrgProfile() -> impl IntoView {
- }.into_view(),
+ }.into_any(),
"audit" => view! {
- }.into_view(),
+ }.into_any(),
"teams" => view! {
@@ -172,12 +173,12 @@ pub fn OrgProfile() -> impl IntoView {
})}
- }.into_view(),
- _ => view! { }.into_view()
+ }.into_any(),
+ _ => view! { }.into_any()
}}
- }.into_view(),
- _ => view! { "Organization Not Found"
}.into_view()
+ }.into_any(),
+ _ => view! { "Organization Not Found"
}.into_any()
}}
@@ -186,7 +187,7 @@ pub fn OrgProfile() -> impl IntoView {
#[component]
pub fn OrgAuditLogs(org_name: String) -> impl IntoView {
- let logs = create_resource(
+ let logs = local_resource(
move || org_name.clone(),
|name| async move { get::>(&format!("/api/v1/orgs/{}/audit-logs", name)).await },
);
@@ -220,9 +221,9 @@ pub fn OrgAuditLogs(org_name: String) -> impl IntoView {
#[component]
pub fn CreateOrg() -> impl IntoView {
- let (name, set_name) = create_signal("".to_string());
- let (desc, set_desc) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (name, set_name) = signal("".to_string());
+ let (desc, set_desc) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
diff --git a/crates/frontend/src/pages/packages.rs b/crates/frontend/src/pages/packages.rs
index f9c3d3a..c91af52 100644
--- a/crates/frontend/src/pages/packages.rs
+++ b/crates/frontend/src/pages/packages.rs
@@ -1,17 +1,18 @@
-use crate::api::{get, get_or, post_json, WRITE_ERROR};
-use leptos::*;
-use leptos_router::*;
+use crate::api::{get, get_or, local_resource, post_json, WRITE_ERROR};
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{CreatePackageOption, Package};
#[component]
pub fn PackageList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
- let (show_upload, set_show_upload) = create_signal(false);
- let (refresh, set_refresh) = create_signal(0);
+ let (show_upload, set_show_upload) = signal(false);
+ let (refresh, set_refresh) = signal(0);
- let packages = create_resource(
+ let packages = local_resource(
move || (owner(), refresh.get()),
|(owner_name, _)| async move {
get::>(&format!("/api/v1/packages/{}", owner_name)).await
@@ -28,9 +29,9 @@ pub fn PackageList() -> impl IntoView {
{move || if show_upload.get() {
- view! { }.into_view()
+ view! { }.into_any()
} else {
- view! { }.into_view()
+ view! { }.into_any()
}}
@@ -57,10 +58,10 @@ fn UploadPackageForm(owner: String, on_success: F) -> impl IntoView
where
F: Fn() + Clone + 'static,
{
- let (name, set_name) = create_signal("".to_string());
- let (version, set_version) = create_signal("".to_string());
- let (pkg_type, set_pkg_type) = create_signal("npm".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (name, set_name) = signal("".to_string());
+ let (version, set_version) = signal("".to_string());
+ let (pkg_type, set_pkg_type) = signal("npm".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
@@ -109,12 +110,12 @@ where
#[component]
pub fn PackageDetail() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let name = move || params.with(|params| params.get("name").cloned().unwrap_or_default());
- let version = move || params.with(|params| params.get("version").cloned().unwrap_or_default());
- let pkg_type = move || params.with(|params| params.get("type").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let name = move || params.with(|params| params.get("name").unwrap_or_default());
+ let version = move || params.with(|params| params.get("version").unwrap_or_default());
+ let pkg_type = move || params.with(|params| params.get("type").unwrap_or_default());
- let package = create_resource(
+ let package = local_resource(
move || (owner(), pkg_type(), name(), version()),
|(o, t, n, v)| async move {
get_or:: }
+ view! { {username.clone()} }
}/>
@@ -723,8 +723,8 @@ pub fn IssueDetail() -> impl IntoView {
- }.into_view() },
- _ => view! { "Issue not found"
}.into_view()
+ }.into_any() },
+ _ => view! { "Issue not found"
}.into_any()
}}
@@ -757,9 +757,9 @@ pub fn IssueDetail() -> impl IntoView {
- }.into_view()
+ }.into_any()
} else {
- view! { {c.body.clone()}
}.into_view()
+ view! { {c.body.clone()}
}.into_any()
}}
@@ -244,15 +244,15 @@ pub fn PullRequestDetail() -> impl IntoView {
- }.into_view()
+ }.into_any()
} else {
- view! { {pr.body.clone().unwrap_or_default()}
}.into_view()
+ view! { {pr.body.clone().unwrap_or_default()}
}.into_any()
}}
}
- }.into_view(),
- _ => view! { "Pull Request not found"
}.into_view()
+ }.into_any(),
+ _ => view! { "Pull Request not found"
}.into_any()
}}
@@ -300,7 +300,7 @@ pub fn PullRequestDetail() -> impl IntoView {
"APPROVED" => "green",
"CHANGES_REQUESTED" => "red",
_ => "gray"
- })>{r.state}
+ })>{r.state.clone()}
" on " {r.created_at}
diff --git a/crates/frontend/src/pages/repo/repo_detail.rs b/crates/frontend/src/pages/repo/repo_detail.rs
index 54223b5..f71a7a2 100644
--- a/crates/frontend/src/pages/repo/repo_detail.rs
+++ b/crates/frontend/src/pages/repo/repo_detail.rs
@@ -1,9 +1,11 @@
//! Repository overview, source browser, commits, branches and tags.
-use crate::api::{get, get_or, get_text, post_json, put, put_json, WRITE_ERROR};
+use crate::api::{get, get_or, get_text, local_resource, post_json, put, put_json, WRITE_ERROR};
use crate::components::{RepoNav, RepoRefresh};
-use leptos::*;
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
+use leptos_router::NavigateOptions;
use shared::{
Branch, CodeSearchResult, Collaborator, Commit, CommitStatus, DiffFile, FileEntry,
LanguageStat, MigrateRepoOption, RepoPulseStats, RepoTopicOptions, Repository, Tag,
@@ -13,38 +15,38 @@ use shared::{
#[component]
pub fn RepoDetail() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let trigger_refresh = create_rw_signal(0u32);
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let trigger_refresh = RwSignal::new(0u32);
// Share the invalidation trigger with RepoNav so a star/watch action (which
// changes the server-side counts) refreshes both the header and this
// overview instead of leaving the overview stats stale.
provide_context(RepoRefresh(trigger_refresh));
- let repo = create_resource(
+ let repo = local_resource(
move || (owner(), repo_name(), trigger_refresh.get()),
|(o, r, _)| async move {
get_or::
>(&format!("/api/v1/repos/{}/{}", o, r), None).await
},
);
- let languages = create_resource(
+ let languages = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move {
get::>(&format!("/api/v1/repos/{}/{}/languages", o, r)).await
},
);
- let topics = create_resource(
+ let topics = local_resource(
move || (owner(), repo_name(), trigger_refresh.get()),
|(o, r, _)| async move {
get::>(&format!("/api/v1/repos/{}/{}/topics", o, r)).await
},
);
- let (is_editing_topics, set_is_editing_topics) = create_signal(false);
- let (topics_input, set_topics_input) = create_signal("".to_string());
- let (topics_error, set_topics_error) = create_signal(Option::::None);
+ let (is_editing_topics, set_is_editing_topics) = signal(false);
+ let (topics_input, set_topics_input) = signal("".to_string());
+ let (topics_error, set_topics_error) = signal(Option::::None);
let start_editing_topics = move |_| {
let current_topics = topics.get().unwrap_or_default();
@@ -125,7 +127,7 @@ pub fn RepoDetail() -> impl IntoView {
{move || topics_error.get().map(|msg| view! {
{msg}
})}
- }.into_view()
+ }.into_any()
} else {
view! {
}>
@@ -139,7 +141,7 @@ pub fn RepoDetail() -> impl IntoView {
- }.into_view()
+ }.into_any()
}}
@@ -155,8 +157,8 @@ pub fn RepoDetail() -> impl IntoView {
"Clone URL: "
"https://codeza.com/" {r.owner} "/" {r.name} ".git"
- }.into_view(),
- _ => view! { "Repository not found."
}.into_view()
+ }.into_any(),
+ _ => view! { "Repository not found."
}.into_any()
}}
@@ -166,12 +168,12 @@ pub fn RepoDetail() -> impl IntoView {
#[component]
pub fn RepoPulse() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (period, set_period) = create_signal("weekly".to_string());
+ let (period, set_period) = signal("weekly".to_string());
- let stats = create_resource(
+ let stats = local_resource(
move || (owner(), repo_name(), period.get()),
|(o, r, p)| async move {
get_or::(
@@ -228,7 +230,7 @@ pub fn RepoPulse() -> impl IntoView {
"Active Contributors"
{if s.active_authors.is_empty() {
- view! {
"No active contributors in this period."
}.into_view()
+ view! {
"No active contributors in this period."
}.into_any()
} else {
view! {
@@ -236,7 +238,7 @@ pub fn RepoPulse() -> impl IntoView {
view! { - {u.username}
}
}/>
- }.into_view()
+ }.into_any()
}}
})}
@@ -250,17 +252,17 @@ pub fn RepoCode() -> impl IntoView {
let params = use_params_map();
let query = use_query_map();
let navigate = use_navigate();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let path = move || params.with(|params| params.get("path").cloned().unwrap_or_default());
- let branch_ref = move || query.with(|q| q.get("ref").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let path = move || params.with(|params| params.get("path").unwrap_or_default());
+ let branch_ref = move || query.with(|q| q.get("ref").unwrap_or_default());
- let branches = create_resource(
+ let branches = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/branches", o, r)).await },
);
- let contents = create_resource(
+ let contents = local_resource(
move || (owner(), repo_name(), path(), branch_ref()),
|(o, r, p, b)| async move {
let mut url = if p.is_empty() {
@@ -275,17 +277,17 @@ pub fn RepoCode() -> impl IntoView {
},
);
- let repo_meta = create_resource(
+ let repo_meta = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move {
get_or::>(&format!("/api/v1/repos/{}/{}", o, r), None).await
},
);
- let nav_ref = store_value(navigate);
- let owner_ref = store_value(owner);
- let repo_ref = store_value(repo_name);
- let path_ref = store_value(path);
+ let nav_ref = StoredValue::new(navigate);
+ let owner_ref = StoredValue::new(owner);
+ let repo_ref = StoredValue::new(repo_name);
+ let path_ref = StoredValue::new(path);
view! {
@@ -312,7 +314,7 @@ pub fn RepoCode() -> impl IntoView {
}>
{b.name} }
+ view! { {b.name.clone()} }
}/>
}
@@ -328,7 +330,7 @@ pub fn RepoCode() -> impl IntoView {
"Loading files..." }>
{move || contents.get().map(|files| {
if files.is_empty() {
- view! { - "No files found or empty directory."
}.into_view()
+ view! { - "No files found or empty directory."
}.into_any()
} else {
view! {
impl IntoView {
{if !is_dir {
let edit_link = format!("/repos/{}/{}/edit/{}", owner(), repo_name(), f.path);
let final_edit_link = if branch_ref().is_empty() { edit_link } else { format!("{}?ref={}", edit_link, branch_ref()) };
- view! { "Edit" }.into_view()
+ view! { "Edit" }.into_any()
} else {
- view! { }.into_view()
+ view! { }.into_any()
}}
}
}/>
- }.into_view()
+ }.into_any()
}
})}
@@ -369,16 +371,16 @@ pub fn RepoCode() -> impl IntoView {
pub fn FileEdit() -> impl IntoView {
let params = use_params_map();
let query = use_query_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let path = move || params.with(|params| params.get("path").cloned().unwrap_or_default());
- let branch_ref = move || query.with(|q| q.get("ref").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let path = move || params.with(|params| params.get("path").unwrap_or_default());
+ let branch_ref = move || query.with(|q| q.get("ref").unwrap_or_default());
- let (content, set_content) = create_signal("".to_string());
- let (message, set_message) = create_signal("Update file".to_string());
- let (save_error, set_save_error) = create_signal(Option::::None);
+ let (content, set_content) = signal("".to_string());
+ let (message, set_message) = signal("Update file".to_string());
+ let (save_error, set_save_error) = signal(Option::::None);
- let _ = create_resource(
+ let _ = local_resource(
move || (owner(), repo_name(), path(), branch_ref()),
move |(o, r, p, b)| async move {
let mut url = format!("/api/v1/repos/{}/{}/raw/{}", o, r, p);
@@ -439,10 +441,10 @@ pub fn FileEdit() -> impl IntoView {
#[component]
pub fn CommitList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let commits = create_resource(
+ let commits = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/commits", o, r)).await },
);
@@ -478,11 +480,11 @@ pub fn CommitList() -> impl IntoView {
#[component]
pub fn CommitDiff() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let sha = move || params.with(|params| params.get("sha").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let sha = move || params.with(|params| params.get("sha").unwrap_or_default());
- let diffs = create_resource(
+ let diffs = local_resource(
move || (owner(), repo_name(), sha()),
|(o, r, s)| async move {
get::>(&format!("/api/v1/repos/{}/{}/commits/{}/diff", o, r, s)).await
@@ -529,10 +531,10 @@ pub fn CommitDiff() -> impl IntoView {
#[component]
pub fn BranchList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let branches = create_resource(
+ let branches = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/branches", o, r)).await },
);
@@ -563,10 +565,10 @@ pub fn BranchList() -> impl IntoView {
#[component]
pub fn TagList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let tags = create_resource(
+ let tags = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/tags", o, r)).await },
);
@@ -596,12 +598,12 @@ pub fn TagList() -> impl IntoView {
#[component]
pub fn CollaboratorList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let (new_collab, set_new_collab) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let (new_collab, set_new_collab) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
- let collabs = create_resource(
+ let collabs = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move {
get::>(&format!("/api/v1/repos/{}/{}/collaborators", o, r)).await
@@ -650,12 +652,12 @@ pub fn CollaboratorList() -> impl IntoView {
#[component]
pub fn RepoCodeSearch() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let (query, set_query) = create_signal("".to_string());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let (query, set_query) = signal("".to_string());
// Trigger resource when query changes (and is not empty)
- let search_results = create_resource(
+ let search_results = local_resource(
move || (owner(), repo_name(), query.get()),
|(o, r, q)| async move {
if q.is_empty() {
@@ -700,7 +702,7 @@ pub fn RepoCodeSearch() -> impl IntoView {
#[component]
pub fn CommitStatusList(owner: String, repo: String, sha: String) -> impl IntoView {
- let statuses = create_resource(
+ let statuses = local_resource(
move || (owner.clone(), repo.clone(), sha.clone()),
|(o, r, s)| async move {
get::>(&format!("/api/v1/repos/{}/{}/commits/{}/statuses", o, r, s))
@@ -714,7 +716,7 @@ pub fn CommitStatusList(owner: String, repo: String, sha: String) -> impl IntoVi
"Loading checks..." }>
{move || statuses.get().map(|list| {
if list.is_empty() {
- view! { "No checks run."
}.into_view()
+ view! { "No checks run."
}.into_any()
} else {
view! {
@@ -738,7 +740,7 @@ pub fn CommitStatusList(owner: String, repo: String, sha: String) -> impl IntoVi
}
}/>
- }.into_view()
+ }.into_any()
}
})}
@@ -748,10 +750,10 @@ pub fn CommitStatusList(owner: String, repo: String, sha: String) -> impl IntoVi
#[component]
pub fn MigrateRepo() -> impl IntoView {
- let (clone_addr, set_clone_addr) = create_signal("".to_string());
- let (repo_name, set_repo_name) = create_signal("".to_string());
- let (service, set_service) = create_signal("git".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (clone_addr, set_clone_addr) = signal("".to_string());
+ let (repo_name, set_repo_name) = signal("".to_string());
+ let (service, set_service) = signal("git".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
let navigate = use_navigate();
let on_submit = move |ev: leptos::ev::SubmitEvent| {
diff --git a/crates/frontend/src/pages/repo/settings.rs b/crates/frontend/src/pages/repo/settings.rs
index 22d20f8..4bb2118 100644
--- a/crates/frontend/src/pages/repo/settings.rs
+++ b/crates/frontend/src/pages/repo/settings.rs
@@ -1,9 +1,12 @@
//! Repository settings, branches, webhooks, secrets and deploy keys.
-use crate::api::{get, get_then, patch_json, post, post_json, put_json, WRITE_ERROR};
+use crate::api::{
+ get, get_then, local_resource, patch_json, post, post_json, put_json, WRITE_ERROR,
+};
use crate::components::RepoNav;
-use leptos::*;
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{
CreateHookOption, CreateKeyOption, CreateProtectedBranchOption, CreateSecretOption, DeployKey,
LfsLock, ProtectedBranch, RepoSettingsOption, RepoTopicOptions, Secret, TransferRepoOption,
@@ -13,26 +16,26 @@ use shared::{
#[component]
pub fn RepoSettings() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
-
- let (desc, set_desc) = create_signal("".to_string());
- let (website, set_website) = create_signal("".to_string());
- let (default_branch, set_default_branch) = create_signal("main".to_string());
- let (private, set_private) = create_signal(false);
- let (rebase, set_rebase) = create_signal(true);
- let (squash, set_squash) = create_signal(true);
- let (merge, set_merge) = create_signal(true);
- let (issues, set_issues) = create_signal(true);
- let (wiki, set_wiki) = create_signal(true);
- let (projects, set_projects) = create_signal(true);
-
- let (transfer_to, set_transfer_to) = create_signal("".to_string());
- let (topics, set_topics) = create_signal("".to_string());
- let (save_error, set_save_error) = create_signal(Option::::None);
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+
+ let (desc, set_desc) = signal("".to_string());
+ let (website, set_website) = signal("".to_string());
+ let (default_branch, set_default_branch) = signal("main".to_string());
+ let (private, set_private) = signal(false);
+ let (rebase, set_rebase) = signal(true);
+ let (squash, set_squash) = signal(true);
+ let (merge, set_merge) = signal(true);
+ let (issues, set_issues) = signal(true);
+ let (wiki, set_wiki) = signal(true);
+ let (projects, set_projects) = signal(true);
+
+ let (transfer_to, set_transfer_to) = signal("".to_string());
+ let (topics, set_topics) = signal("".to_string());
+ let (save_error, set_save_error) = signal(Option::::None);
// Load initial settings
- let _ = create_resource(
+ let _ = local_resource(
move || (owner(), repo_name()),
move |(o, r)| async move {
get_then::(
@@ -200,13 +203,13 @@ pub fn CreateProtectedBranch(
repo: Signal,
on_success: Action<(), ()>,
) -> impl IntoView {
- let (name, set_name) = create_signal(String::new());
- let (enable_push, set_enable_push) = create_signal(false);
- let (enable_force_push, set_enable_force_push) = create_signal(false);
- let (status_checks, set_status_checks) = create_signal(String::new());
- let (branch_error, set_branch_error) = create_signal(Option::::None);
+ let (name, set_name) = signal(String::new());
+ let (enable_push, set_enable_push) = signal(false);
+ let (enable_force_push, set_enable_force_push) = signal(false);
+ let (status_checks, set_status_checks) = signal(String::new());
+ let (branch_error, set_branch_error) = signal(Option::::None);
- let create_action = create_action(move |_: &()| {
+ let create_action = Action::new_local(move |_: &()| {
let name_val = name.get();
let enable_push_val = enable_push.get();
let enable_force_push_val = enable_force_push.get();
@@ -293,14 +296,14 @@ pub fn CreateProtectedBranch(
#[component]
pub fn ProtectedBranchList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
let owner_sig = Signal::derive(owner);
let repo_sig = Signal::derive(repo_name);
- let (refetch_trigger, set_refetch_trigger) = create_signal(0);
+ let (refetch_trigger, set_refetch_trigger) = signal(0);
- let branches = create_resource(
+ let branches = local_resource(
move || (owner(), repo_name(), refetch_trigger.get()),
|(o, r, _)| async move {
get::>(&format!("/api/v1/repos/{}/{}/branch_protections", o, r))
@@ -308,7 +311,7 @@ pub fn ProtectedBranchList() -> impl IntoView {
},
);
- let on_success = create_action(move |_: &()| {
+ let on_success = Action::new_local(move |_: &()| {
set_refetch_trigger.update(|v| *v += 1);
async {}
});
@@ -348,10 +351,10 @@ pub fn ProtectedBranchList() -> impl IntoView {
#[component]
pub fn LfsLockList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let locks = create_resource(
+ let locks = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move {
get::>(&format!("/api/v1/repos/{}/{}/git/lfs/locks", o, r)).await
@@ -378,13 +381,13 @@ pub fn LfsLockList() -> impl IntoView {
#[component]
pub fn WebhookList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (url, set_url) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (url, set_url) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
- let hooks = create_resource(
+ let hooks = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/hooks", o, r)).await },
);
@@ -419,7 +422,7 @@ pub fn WebhookList() -> impl IntoView {
let hook_id = h.id;
let o = owner();
let r = repo_name();
- let deliveries = create_resource(
+ let deliveries = local_resource(
move || (o.clone(), r.clone(), hook_id),
|(o, r, id)| async move {
get::>(&format!("/api/v1/repos/{}/{}/hooks/{}/deliveries", o, r, id)).await
@@ -436,7 +439,7 @@ pub fn WebhookList() -> impl IntoView {
"..." }>
{move || deliveries.get().map(|list| {
if list.is_empty() {
- view! { "No deliveries yet"
}.into_view()
+ view! { "No deliveries yet"
}.into_any()
} else {
view! {
@@ -444,7 +447,7 @@ pub fn WebhookList() -> impl IntoView {
view! { - {d.delivered_at} " - " {d.event} " - " {d.status} " (" {d.response_status} ")"
}
}/>
- }.into_view()
+ }.into_any()
}
})}
@@ -470,14 +473,14 @@ pub fn WebhookList() -> impl IntoView {
#[component]
pub fn SecretList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (name, set_name) = create_signal("".to_string());
- let (data, set_data) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (name, set_name) = signal("".to_string());
+ let (data, set_data) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
- let secrets = create_resource(
+ let secrets = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/secrets", o, r)).await },
);
@@ -530,14 +533,14 @@ pub fn SecretList() -> impl IntoView {
#[component]
pub fn DeployKeyList() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (title, set_title) = create_signal("".to_string());
- let (key, set_key) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (title, set_title) = signal("".to_string());
+ let (key, set_key) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
- let keys = create_resource(
+ let keys = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move { get::>(&format!("/api/v1/repos/{}/{}/keys", o, r)).await },
);
diff --git a/crates/frontend/src/pages/repo/wiki.rs b/crates/frontend/src/pages/repo/wiki.rs
index d584493..2e8e063 100644
--- a/crates/frontend/src/pages/repo/wiki.rs
+++ b/crates/frontend/src/pages/repo/wiki.rs
@@ -1,26 +1,21 @@
//! Repository wiki pages.
-use crate::api::{get, get_opt, get_or, post_json, put_json, WRITE_ERROR};
+use crate::api::{get, get_opt, get_or, local_resource, post_json, put_json, WRITE_ERROR};
use crate::components::RepoNav;
-use leptos::*;
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{CreateWikiPageOption, WikiPage};
#[component]
pub fn Wiki() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let page_name = move || {
- params.with(|params| {
- params
- .get("page_name")
- .cloned()
- .unwrap_or("Home".to_string())
- })
- };
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let page_name =
+ move || params.with(|params| params.get("page_name").unwrap_or("Home".to_string()));
- let wiki_page = create_resource(
+ let wiki_page = local_resource(
move || (owner(), repo_name(), page_name()),
move |(o, r, p)| async move {
get_or::>(&format!("/api/v1/repos/{}/{}/wiki/pages/{}", o, r, p), None)
@@ -28,7 +23,7 @@ pub fn Wiki() -> impl IntoView {
},
);
- let wiki_pages = create_resource(
+ let wiki_pages = local_resource(
move || (owner(), repo_name()),
|(o, r)| async move {
get::>(&format!("/api/v1/repos/{}/{}/wiki/pages", o, r)).await
@@ -65,18 +60,18 @@ pub fn Wiki() -> impl IntoView {
- }.into_view()
+ }.into_any()
},
_ => {
let p = page_name();
view! {
- }.into_view()
+ }.into_any()
}
}}
@@ -89,24 +84,18 @@ pub fn Wiki() -> impl IntoView {
#[component]
pub fn WikiEdit() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
- let page_name = move || {
- params.with(|params| {
- params
- .get("page_name")
- .cloned()
- .unwrap_or("Home".to_string())
- })
- };
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
+ let page_name =
+ move || params.with(|params| params.get("page_name").unwrap_or("Home".to_string()));
- let (content, set_content) = create_signal("".to_string());
- let (message, set_message) = create_signal("".to_string());
- let (is_new, set_is_new) = create_signal(true);
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (content, set_content) = signal("".to_string());
+ let (message, set_message) = signal("".to_string());
+ let (is_new, set_is_new) = signal(true);
+ let (form_error, set_form_error) = signal(Option::::None);
// Load existing content if available
- let _ = create_resource(
+ let _ = local_resource(
move || (owner(), repo_name(), page_name()),
move |(o, r, p)| async move {
if let Some(Some(page)) =
diff --git a/crates/frontend/src/pages/security.rs b/crates/frontend/src/pages/security.rs
index dc4d28e..cff33d8 100644
--- a/crates/frontend/src/pages/security.rs
+++ b/crates/frontend/src/pages/security.rs
@@ -1,20 +1,21 @@
-use crate::api::{get_opt, post, WRITE_ERROR};
+use crate::api::{get_opt, local_resource, post, WRITE_ERROR};
use crate::components::RepoNav;
-use leptos::*;
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::SecurityScanReport;
#[component]
pub fn SecurityDashboard() -> impl IntoView {
let params = use_params_map();
- let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default());
- let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default());
+ let owner = move || params.with(|params| params.get("owner").unwrap_or_default());
+ let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default());
- let (scanning, set_scanning) = create_signal(false);
- let (refresh, set_refresh) = create_signal(0);
- let (scan_error, set_scan_error) = create_signal(Option::::None);
+ let (scanning, set_scanning) = signal(false);
+ let (refresh, set_refresh) = signal(0);
+ let (scan_error, set_scan_error) = signal(Option::::None);
- let report = create_resource(
+ let report = local_resource(
move || (owner(), repo_name(), refresh.get()),
|(o, r, _)| async move {
get_opt::(&format!("/api/v1/repos/{}/{}/security/scan", o, r)).await
@@ -75,7 +76,7 @@ pub fn SecurityDashboard() -> impl IntoView {
"✅ No vulnerabilities or secret leaks detected in repository!"
- }.into_view()
+ }.into_any()
} else {
view! {
@@ -107,12 +108,12 @@ pub fn SecurityDashboard() -> impl IntoView {
}
}/>
- }.into_view()
+ }.into_any()
}}
- }.into_view()
+ }.into_any()
},
- None => view! { "Failed to load scan report."
}.into_view(),
+ None => view! { "Failed to load scan report."
}.into_any(),
})}
diff --git a/crates/frontend/src/pages/user.rs b/crates/frontend/src/pages/user.rs
index 78a0526..1425c7a 100644
--- a/crates/frontend/src/pages/user.rs
+++ b/crates/frontend/src/pages/user.rs
@@ -1,6 +1,7 @@
-use crate::api::{delete, get, get_or, patch_json, post_json, WRITE_ERROR};
-use leptos::*;
-use leptos_router::*;
+use crate::api::{delete, get, get_or, local_resource, patch_json, post_json, WRITE_ERROR};
+use leptos::prelude::*;
+use leptos::task::spawn_local;
+use leptos_router::hooks::*;
use shared::{
Contribution, CreateGpgKeyOption, CreateKeyOption, GpgKey, LoginOption, PublicKey,
RegisterOption, User, UserSettingsOption,
@@ -8,9 +9,9 @@ use shared::{
#[component]
pub fn Login() -> impl IntoView {
- let (username, set_username) = create_signal("".to_string());
- let (password, set_password) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (username, set_username) = signal("".to_string());
+ let (password, set_password) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
@@ -47,10 +48,10 @@ pub fn Login() -> impl IntoView {
#[component]
pub fn Register() -> impl IntoView {
- let (username, set_username) = create_signal("".to_string());
- let (email, set_email) = create_signal("".to_string());
- let (password, set_password) = create_signal("".to_string());
- let (form_error, set_form_error) = create_signal(Option::::None);
+ let (username, set_username) = signal("".to_string());
+ let (email, set_email) = signal("".to_string());
+ let (password, set_password) = signal("".to_string());
+ let (form_error, set_form_error) = signal(Option::::None);
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
@@ -88,10 +89,9 @@ pub fn Register() -> impl IntoView {
#[component]
pub fn UserProfile() -> impl IntoView {
let params = use_params_map();
- let username =
- move || params.with(|params| params.get("username").cloned().unwrap_or_default());
+ let username = move || params.with(|params| params.get("username").unwrap_or_default());
- let user = create_resource(username, |u| async move {
+ let user = local_resource(username, |u| async move {
get_or::>(&format!("/api/v1/users/{}", u), None).await
});
@@ -108,8 +108,8 @@ pub fn UserProfile() -> impl IntoView {
"Email: " {u.email.unwrap_or("Hidden".to_string())}
- }.into_view(),
- _ => view! { "User not found"
}.into_view()
+ }.into_any(),
+ _ => view! { "User not found"
}.into_any()
}}
@@ -119,9 +119,8 @@ pub fn UserProfile() -> impl IntoView {
#[component]
pub fn UserHeatmap() -> impl IntoView {
let params = use_params_map();
- let username =
- move || params.with(|params| params.get("username").cloned().unwrap_or_default());
- let data = create_resource(username, |u| async move {
+ let username = move || params.with(|params| params.get("username").unwrap_or_default());
+ let data = local_resource(username, |u| async move {
get::>(&format!("/api/v1/users/{}/heatmap", u)).await
});
@@ -145,9 +144,8 @@ pub fn UserHeatmap() -> impl IntoView {
#[component]
pub fn UserFollowers() -> impl IntoView {
let params = use_params_map();
- let username =
- move || params.with(|params| params.get("username").cloned().unwrap_or_default());
- let users = create_resource(username, |u| async move {
+ let username = move || params.with(|params| params.get("username").unwrap_or_default());
+ let users = local_resource(username, |u| async move {
get::>(&format!("/api/v1/users/{}/followers", u)).await
});
@@ -170,9 +168,8 @@ pub fn UserFollowers() -> impl IntoView {
#[component]
pub fn UserFollowing() -> impl IntoView {
let params = use_params_map();
- let username =
- move || params.with(|params| params.get("username").cloned().unwrap_or_default());
- let users = create_resource(username, |u| async move {
+ let username = move || params.with(|params| params.get("username").unwrap_or_default());
+ let users = local_resource(username, |u| async move {
get::>(&format!("/api/v1/users/{}/following", u)).await
});
@@ -194,7 +191,7 @@ pub fn UserFollowing() -> impl IntoView {
#[component]
pub fn UserSettings() -> impl IntoView {
- let settings = create_resource(
+ let settings = local_resource(
|| (),
|_| async move {
get_or::(
@@ -210,25 +207,25 @@ pub fn UserSettings() -> impl IntoView {
},
);
- let (refresh, set_refresh) = create_signal(0);
+ let (refresh, set_refresh) = signal(0);
- let keys = create_resource(
+ let keys = local_resource(
move || refresh.get(),
|_| async move { get::>("/api/v1/user/keys").await },
);
- let gpg_keys = create_resource(
+ let gpg_keys = local_resource(
move || refresh.get(),
|_| async move { get::>("/api/v1/user/gpg_keys").await },
);
- let (full_name, set_full_name) = create_signal("".to_string());
+ let (full_name, set_full_name) = signal("".to_string());
- let (ssh_title, set_ssh_title) = create_signal("".to_string());
- let (ssh_key, set_ssh_key) = create_signal("".to_string());
+ let (ssh_title, set_ssh_title) = signal("".to_string());
+ let (ssh_key, set_ssh_key) = signal("".to_string());
- let (gpg_key_content, set_gpg_key_content) = create_signal("".to_string());
- let (key_error, set_key_error) = create_signal(Option::::None);
+ let (gpg_key_content, set_gpg_key_content) = signal("".to_string());
+ let (key_error, set_key_error) = signal(Option::::None);
let on_add_ssh_key = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
"This conversation is locked"
}.into_view() + view! {"This conversation is locked"
}.into_any() }, _ => { view! { @@ -805,7 +805,7 @@ pub fn IssueDetail() -> impl IntoView {{msg}
})} - }.into_view() + }.into_any() } } } @@ -818,15 +818,15 @@ pub fn IssueDetail() -> impl IntoView { #[component] pub fn LabelList() -> impl IntoView { let params = use_params_map(); - let owner = move || params.with(|params| params.get("owner").cloned().unwrap_or_default()); - let repo_name = move || params.with(|params| params.get("repo").cloned().unwrap_or_default()); + let owner = move || params.with(|params| params.get("owner").unwrap_or_default()); + let repo_name = move || params.with(|params| params.get("repo").unwrap_or_default()); - let (name, set_name) = create_signal("".to_string()); - let (form_error, set_form_error) = create_signal(Option::"Milestone: " {m.title}
{m.description.unwrap_or_default()}
"State: " {m.state}
- }.into_view(), - _ => view! {"Milestone not found"
}.into_view() + }.into_any(), + _ => view! {"Milestone not found"
}.into_any() }}"Pull Request #" {index} ": " {pr.title.clone()}
}.into_view() + view! {"Pull Request #" {index} ": " {pr.title.clone()}
}.into_any() }} {pr.state.clone()} " opened by " {pr.user.username} @@ -231,9 +231,9 @@ pub fn PullRequestDetail() -> impl IntoView { {if state_clone == "open" { "Close PR" } else { "Reopen PR" }} {if !is_editing.get() { - view! { }.into_view() + view! { }.into_any() } else { - view! { }.into_view() + view! { }.into_any() }}