- { move || before().map(|i| i.into_any(before_click_callback)) }
+ { move || before().map(move |i| view! {
+
+ }) }
- { move || after().map(|i| i.into_any(after_click_callback)) }
+ { move || after().map(move |i| view! {
+
+ }) }
{ move || error_hint().map(|e| view! {
diff --git a/crates/site-app/src/components/input_field/icon.rs b/crates/site-app/src/components/input_field/icon.rs
index 833f8ebe..f7ad7c4c 100644
--- a/crates/site-app/src/components/input_field/icon.rs
+++ b/crates/site-app/src/components/input_field/icon.rs
@@ -1,58 +1,45 @@
-use leptos::{ev::MouseEvent, prelude::*};
+use leptos::{either::EitherOf11, prelude::*};
use crate::components::{
- icons::LockClosedHeroIcon, ArchiveBoxHeroIcon, EnvelopeHeroIcon, EyeHeroIcon,
- EyeSlashHeroIcon, GlobeAltHeroIcon, KeyHeroIcon, UserHeroIcon,
+ icons::LockClosedHeroIcon, ArchiveBoxHeroIcon, ArrowPathHeroIcon,
+ CheckHeroIcon, EnvelopeHeroIcon, EyeHeroIcon, EyeSlashHeroIcon,
+ GlobeAltHeroIcon, KeyHeroIcon, UserHeroIcon, XMarkHeroIcon,
};
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
pub enum InputIcon {
ArchiveBox,
+ Check,
Envelope,
Eye,
EyeSlash,
GlobeAlt,
Key,
+ Loading,
LockClosed,
User,
+ XMark,
}
-macro_rules! icon_match {
- ($self_expr:expr, $click_handler:expr, $icon_class:expr, {
- $($variant:ident => $component:ident),* $(,)?
- }) => {
-match $self_expr {
- $(
- InputIcon::$variant => view! {
- <$component {..} class=$icon_class on:click=$click_handler />
- }.into_any(),
- )*
-}
+#[component]
+pub fn InputIconComponent(icon: InputIcon) -> impl IntoView {
+ let icon = match icon {
+ InputIcon::ArchiveBox => EitherOf11::A(view! {
}),
+ InputIcon::Check => EitherOf11::B(view! {
}),
+ InputIcon::Envelope => EitherOf11::C(view! {
}),
+ InputIcon::Eye => EitherOf11::D(view! {
}),
+ InputIcon::EyeSlash => EitherOf11::E(view! {
}),
+ InputIcon::GlobeAlt => EitherOf11::F(view! {
}),
+ InputIcon::Key => EitherOf11::G(view! {
}),
+ InputIcon::Loading => EitherOf11::H(view! {
}),
+ InputIcon::LockClosed => EitherOf11::I(view! {
}),
+ InputIcon::User => EitherOf11::J(view! {
}),
+ InputIcon::XMark => EitherOf11::K(view! {
}),
};
-}
-
-impl InputIcon {
- pub fn into_any(
- self,
- click_handler: Option
>,
- ) -> AnyView {
- const ICON_CLASS: &str = "size-6";
-
- let click_handler = move |e| {
- if let Some(h) = click_handler {
- h.run(e)
- }
- };
- icon_match!(self, click_handler, ICON_CLASS, {
- ArchiveBox => ArchiveBoxHeroIcon,
- Envelope => EnvelopeHeroIcon,
- Eye => EyeHeroIcon,
- EyeSlash => EyeSlashHeroIcon,
- GlobeAlt => GlobeAltHeroIcon,
- Key => KeyHeroIcon,
- LockClosed => LockClosedHeroIcon,
- User => UserHeroIcon,
- })
+ view! {
+
+ { icon }
+
}
}
diff --git a/crates/site-app/src/components/navbar/org_selector.rs b/crates/site-app/src/components/navbar/org_selector.rs
index fd0251ee..af7f2f91 100644
--- a/crates/site-app/src/components/navbar/org_selector.rs
+++ b/crates/site-app/src/components/navbar/org_selector.rs
@@ -45,7 +45,7 @@ pub(super) fn OrgSelectorPopover(user: AuthUser) -> impl IntoView {
{ user.name.to_string() }
-
+
{ move || Suspend::new(active_org_descriptor) }
diff --git a/crates/site-app/src/pages/create_cache.rs b/crates/site-app/src/pages/create_cache.rs
index 6a8efe47..cda6daaf 100644
--- a/crates/site-app/src/pages/create_cache.rs
+++ b/crates/site-app/src/pages/create_cache.rs
@@ -37,12 +37,23 @@ pub fn CreateCachePage() -> impl IntoView {
let (read_name, write_name) = touched_input_bindings(name);
let visibility = RwSignal::new(Visibility::Private);
+ let query_client = expect_context::();
+ let is_available_key_fn = move || sanitized_name().map(|n| n.to_string());
let is_available_query_scope =
crate::resources::cache::cache_name_is_available_query_scope();
let is_available_resource = expect_context::()
- .local_resource(is_available_query_scope, move || {
- sanitized_name().map(|n| n.to_string())
- });
+ .local_resource(is_available_query_scope.clone(), is_available_key_fn);
+ let is_available_fetching = query_client
+ .subscribe_is_fetching(is_available_query_scope, is_available_key_fn);
+
+ let name_after_icon = Memo::new(move |_| {
+ match (is_available_fetching(), is_available_resource.get()) {
+ (true, _) => Some(InputIcon::Loading),
+ (_, Some(Some(Ok(true)))) => Some(InputIcon::Check),
+ (_, Some(Some(Ok(false)))) => Some(InputIcon::XMark),
+ _ => None,
+ }
+ });
let action = ServerAction::::new();
let loading = {
@@ -63,12 +74,14 @@ pub fn CreateCachePage() -> impl IntoView {
None
});
let name_error_hint = MaybeProp::derive(move || {
- if let (Some(Some(Ok(false))), Some(sanitized_name)) =
- (is_available_resource.get(), sanitized_name())
- {
- Some(format!("The name \"{sanitized_name}\" is unavailable."))
- } else {
- None
+ match (is_available_resource.get(), sanitized_name()) {
+ (Some(Some(Ok(false))), Some(sanitized_name)) => {
+ Some(format!("The name \"{sanitized_name}\" is unavailable."))
+ }
+ (Some(Some(Err(_))), _) => {
+ Some("Sorry, something went wrong.".to_owned())
+ }
+ _ => None,
}
});
@@ -107,6 +120,7 @@ pub fn CreateCachePage() -> impl IntoView {
diff --git a/crates/site-app/style/src/main.css b/crates/site-app/style/src/main.css
index f97db741..b467223a 100644
--- a/crates/site-app/style/src/main.css
+++ b/crates/site-app/style/src/main.css
@@ -42,8 +42,8 @@
rgba(27, 50, 73, 0.08) 0px 2px 12px 0px;
/* animations */
- --animate-fade-in: fade-in 0.15s ease-out;
- --animate-fade-out: fade-out 0.15s ease-in;
+ --animate-fade-in: fade-in 0.15s linear;
+ --animate-fade-down: fade-down 0.10s linear;
/* custom grid template columns */
--form-grid-cols: calc(48 * var(--spacing)) minmax(0, 1fr)
@@ -62,12 +62,14 @@
}
}
-@keyframes fade-out {
+@keyframes fade-down {
from {
- opacity: 1;
+ opacity: 0;
+ transform: scaleY(0);
}
to {
- opacity: 0;
+ opacity: 1;
+ transform: scaleY(1);
}
}