From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Yew framework devel list at Proxmox <yew-devel@lists.proxmox.com>,
Dietmar Maurer <dietmar@proxmox.com>
Subject: Re: [yew-devel] [RFC yew-comp] refactor: move LoadableComponent state into component implementations
Date: Tue, 9 Dec 2025 19:31:14 +0100 [thread overview]
Message-ID: <edaff8e9-beac-4693-83db-dfed33bbd766@proxmox.com> (raw)
In-Reply-To: <20251209131159.4027954-1-dietmar@proxmox.com>
Am 09.12.25 um 15:36 schrieb Dietmar Maurer:
> Major Refactoring of the `LoadableComponent` system.
>
> Encapsulate component state (loading, error, view_state) into a new
> `LoadableComponentState` struct.
> Instead of `LoadableComponentMaster` managing the state externally,
> the concrete components now own their `LoadableComponentState`.
>
> - Use `impl_deref_mut_property`LoadableComponentState` struct. to implement
> Deref/DerefMut for components, allowing `LoadableComponentMaster` to
> access the state transparently.
> - `LoadableComponentContext` is now a normal yew Scope (removed custom implementation)
> - Migrate all `LoadableComponent` implementations (ACL, ACME, APT, Network,
> User/Token/TFA views, etc.) to the new pattern.
> - Use `link.custom_callback` and `link.send_custom_message` for internal
> messaging (rename is necessaray because of naming conflict with standard
s/necessaray/necessary/
> Scope function).
> - avoid useless Redraw/Datachange/Refresh messages, because `LoadableComponentMaster`
> already implements that.
Besides above typo in the commit message and another typo in the doc-comment
example (see below), this looks OK to me.
> diff --git a/src/loadable_component.rs b/src/loadable_component.rs
> index f0e28a9..43cb7a9 100644
> --- a/src/loadable_component.rs
> +++ b/src/loadable_component.rs
> @@ -1,163 +1,313 @@
> -use anyhow::Error;
> -use serde_json::Value;
> use std::future::Future;
> +use std::ops::DerefMut;
> use std::pin::Pin;
> -use yew_router::scope_ext::RouterScopeExt;
>
> +use anyhow::Error;
> use gloo_timers::callback::Timeout;
>
> +use serde_json::Value;
> use yew::html::Scope;
>
> use pwt::dom::DomVisibilityObserver;
> use pwt::prelude::*;
> -use pwt::state::NavigationContextExt;
> use pwt::widget::{AlertDialog, Column};
> use pwt::AsyncPool;
>
> +#[cfg(doc)]
> +use crate::impl_deref_mut_property;
> +#[cfg(doc)]
> +use pwt::widget::Dialog;
> +
> use crate::{TaskProgress, TaskViewer};
>
> -pub struct LoadableComponentState {
> - loading: usize,
> - last_load_error: Option<String>,
> - repeat_timespan: u32, /* 0 => no repeated loading */
> - task_base_url: Option<AttrValue>,
> -}
> +pub type LoadableComponentContext<L> = Context<LoadableComponentMaster<L>>;
> +pub type LoadableComponentScope<L> = Scope<LoadableComponentMaster<L>>;
> +
> +/// Loadable Components
> +///
> +/// - Load data using an async function [LoadableComponent::load]
> +/// - repeated load possible
> +/// - pause repeated load when component is not visible (uses [DomVisibilityObserver])
> +/// - display the loaded data [LoadableComponent::main_view]
> +/// - display an optional toolbar [LoadableComponent::toolbar]
> +/// - display any errors from failed load.
> +/// - display additional dialogs depening on [LoadableComponent::ViewState]
> +///
> +/// The [LoadableComponentScopeExt] defines available control function on the scope.
> +///
> +/// The [LoadableComponentState] provides acces to load status informations and add the ability
> +/// to spawn tasks.
> +///
> +/// ```
> +/// use proxmox_yew_comp::{LoadableComponent, LoadableComponentState, LoadableComponentContext};
> +/// // include the scope extension for (for `change_view`, `send_custom_message`, ...)
> +/// use proxmox_yew_comp::LoadableComponentScopeExt;
> +/// # use std::pin::Pin;
> +/// # use std::rc::Rc;
> +/// # use std::future::Future;
> +/// # use pwt::prelude::*;
> +/// # use proxmox_yew_comp::http_get;
> +/// # use yew::virtual_dom::{VComp, VNode, Key};
> +///
> +/// // define the component properties
> +/// #[derive(Clone, PartialEq, Properties)]
> +/// pub struct MyComponent {
> +/// key: Option<Key>,
> +/// /* add whatever you need */
> +/// };
> +///
> +/// // define your view states
> +/// #[derive(PartialEq)]
> +/// pub enum ViewState { Add, Edit }
> +///
> +/// // define the component message type
> +/// pub enum Msg { UpdateData(String) }
> +///
> +/// // define the component state
> +/// pub struct MyComponentState {
> +/// // you need to inlucde a LoadableComponentState
typo s/inlucde/include/
> +/// state: LoadableComponentState<ViewState>,
> +/// // Add any other data you need
> +/// loaded_data: Option<String>,
> +/// }
> +///
> +/// // implement DerefMut
> +/// proxmox_yew_comp::impl_deref_mut_property!(
> +/// MyComponentState,
> +/// state,
> +/// LoadableComponentState<ViewState>
> +/// );
> +///
_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
next prev parent reply other threads:[~2025-12-09 18:31 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-09 13:11 Dietmar Maurer
2025-12-09 18:31 ` Thomas Lamprecht [this message]
2025-12-10 7:53 ` Thomas Lamprecht
2025-12-10 9:23 ` Dietmar Maurer
2025-12-10 9:32 ` Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=edaff8e9-beac-4693-83db-dfed33bbd766@proxmox.com \
--to=t.lamprecht@proxmox.com \
--cc=dietmar@proxmox.com \
--cc=yew-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox