public inbox for yew-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store
@ 2025-10-29 13:30 Shannon Sterz
  2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-widget-toolkit 1/1] store: add helper methods to extract a record via a selection Shannon Sterz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Shannon Sterz @ 2025-10-29 13:30 UTC (permalink / raw)
  To: yew-devel

a very common pattern is to use a `Store` combined with a `Selection`.
however, to get the record from a `Store` that has the same `Key` as is
selected by the `Selection` is a little cumbersome as it requires
dealing with several optional values. so many components implement a
helper for that. it usually looks like this:

```rust
fn get_selected_record(&self) -> Option<ApiToken> {
    self.selection
        .selected_key()
        .and_then(|key| self.store.read().lookup_record(&key).cloned())
}

let Some(record) = self.get_selected_record() else {
    return false;
}
```

to avoid duplicating this effort in every such component add new helper
methods to the `Store`. they each take a `Selection` and either return
an optional reference or an optional clone of the selected record.
turning the above into:

```rust
let Some(record) = self.store.selected_record(&self.selection) else {
    return false;
}
```

the second commit in this series is mostly for demonstrative purposes.
sending this as an rfc as i am not sure if the naming of these functions
is ideal or whether we want to add both helpers (instead of just one of
them).

proxmox-yew-widget-toolkit:

Shannon Sterz (1):
  store: add helper methods to extract a record via a selection

 src/state/store.rs | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)


proxmox-yew-comp:

Shannon Sterz (1):
  token panel: use new `selected_record` helper

 src/token_panel.rs | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)


Summary over all repositories:
  2 files changed, 19 insertions(+), 10 deletions(-)

--
Generated by git-murpp 0.8.1


_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [yew-devel] [RFC PATCH yew-widget-toolkit 1/1] store: add helper methods to extract a record via a selection
  2025-10-29 13:30 [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
@ 2025-10-29 13:30 ` Shannon Sterz
  2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-comp 1/1] token panel: use new `selected_record` helper Shannon Sterz
  2025-10-29 13:50 ` [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
  2 siblings, 0 replies; 4+ messages in thread
From: Shannon Sterz @ 2025-10-29 13:30 UTC (permalink / raw)
  To: yew-devel

this adds two helpers to the `Store` (and its `StoreState`) that have
similar objectives:

- `selected_record(Selection) -> Option<T>`: returns a clone of the
record that has the same `Key` as the currently selected item in the
`Selection`. this requires the type `T` to implement `Clone`.
- `lookup_with_selection(Selection) -> Option<&T>`: requires the user
to acquire a read guard on the store first and will then return a
reference to the record of the store that matches the currently
selected item in the `Selection`.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/state/store.rs | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/state/store.rs b/src/state/store.rs
index 42cb53b3..c075edd1 100644
--- a/src/state/store.rs
+++ b/src/state/store.rs
@@ -14,7 +14,7 @@ use yew::virtual_dom::Key;
 use crate::props::{
     ExtractKeyFn, ExtractPrimaryKey, FilterFn, IntoFilterFn, IntoSorterFn, SorterFn,
 };
-use crate::state::{optional_rc_ptr_eq, DataNode, DataNodeDerefGuard, DataStore};
+use crate::state::{optional_rc_ptr_eq, DataNode, DataNodeDerefGuard, DataStore, Selection};

 /// Hook to use a [Store] with functional components.
 ///
@@ -102,6 +102,13 @@ impl<T: ExtractPrimaryKey + 'static> FromIterator<T> for Store<T> {
     }
 }

+impl<T: Clone> Store<T> {
+    /// Returns a clone of the record that is currently selected by `selection`.
+    pub fn selected_record(&self, selection: &Selection) -> Option<T> {
+        self.read().lookup_with_selection(selection).cloned()
+    }
+}
+
 impl<T: 'static> Store<T> {
     /// Creates a new instance with the specifies extract key function.
     pub fn with_extract_key(extract_key: impl Into<ExtractKeyFn<T>>) -> Self {
@@ -558,6 +565,15 @@ impl<T: 'static> StoreState<T> {
     pub fn lookup_record_mut(&mut self, key: &Key) -> Option<&mut T> {
         self.record_pos(key).map(|n| &mut self.data[n])
     }
+
+    /// Find the record that has the same key as is currently selected by `selection`.
+    pub fn lookup_with_selection(&self, selection: &Selection) -> Option<&T> {
+        if let Some(ref key) = selection.selected_key() {
+            return self.lookup_record(key);
+        }
+
+        None
+    }
 }

 #[doc(hidden)]
--
2.47.3



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [yew-devel] [RFC PATCH yew-comp 1/1] token panel: use new `selected_record` helper
  2025-10-29 13:30 [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
  2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-widget-toolkit 1/1] store: add helper methods to extract a record via a selection Shannon Sterz
@ 2025-10-29 13:30 ` Shannon Sterz
  2025-10-29 13:50 ` [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
  2 siblings, 0 replies; 4+ messages in thread
From: Shannon Sterz @ 2025-10-29 13:30 UTC (permalink / raw)
  To: yew-devel

instead of re-implementing it here

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/token_panel.rs | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/src/token_panel.rs b/src/token_panel.rs
index 55795a6..ebdccdd 100644
--- a/src/token_panel.rs
+++ b/src/token_panel.rs
@@ -218,7 +218,7 @@ impl LoadableComponent for ProxmoxTokenView {
         match msg {
             Msg::Refresh => true,
             Msg::Remove => {
-                let Some(record) = self.get_selected_record() else {
+                let Some(record) = self.store.selected_record(&self.selection) else {
                     return false;
                 };

@@ -243,7 +243,7 @@ impl LoadableComponent for ProxmoxTokenView {
                 false
             }
             Msg::Regenerate => {
-                let Some(record) = self.get_selected_record() else {
+                let Some(record) = self.store.selected_record(&self.selection) else {
                     return false;
                 };
                 let user = record.tokenid.user().to_string();
@@ -302,13 +302,6 @@ impl LoadableComponent for ProxmoxTokenView {
 }

 impl ProxmoxTokenView {
-    fn get_selected_record(&self) -> Option<ApiToken> {
-        self.selection
-            .selected_key()
-            .map(|key| self.store.read().lookup_record(&key).cloned())
-            .flatten()
-    }
-
     fn create_show_permissions_dialog(
         &self,
         ctx: &LoadableComponentContext<Self>,
--
2.47.3



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store
  2025-10-29 13:30 [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
  2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-widget-toolkit 1/1] store: add helper methods to extract a record via a selection Shannon Sterz
  2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-comp 1/1] token panel: use new `selected_record` helper Shannon Sterz
@ 2025-10-29 13:50 ` Shannon Sterz
  2 siblings, 0 replies; 4+ messages in thread
From: Shannon Sterz @ 2025-10-29 13:50 UTC (permalink / raw)
  To: Shannon Sterz; +Cc: yew-devel

discussed this off-list and was encouraged to also add versions of these
helpers for selections in multi-select mode. will include that in a v1.

On Wed Oct 29, 2025 at 2:30 PM CET, Shannon Sterz wrote:
> a very common pattern is to use a `Store` combined with a `Selection`.
> however, to get the record from a `Store` that has the same `Key` as is
> selected by the `Selection` is a little cumbersome as it requires
> dealing with several optional values. so many components implement a
> helper for that. it usually looks like this:
>
> ```rust
> fn get_selected_record(&self) -> Option<ApiToken> {
>     self.selection
>         .selected_key()
>         .and_then(|key| self.store.read().lookup_record(&key).cloned())
> }
>
> let Some(record) = self.get_selected_record() else {
>     return false;
> }
> ```
>
> to avoid duplicating this effort in every such component add new helper
> methods to the `Store`. they each take a `Selection` and either return
> an optional reference or an optional clone of the selected record.
> turning the above into:
>
> ```rust
> let Some(record) = self.store.selected_record(&self.selection) else {
>     return false;
> }
> ```
>
> the second commit in this series is mostly for demonstrative purposes.
> sending this as an rfc as i am not sure if the naming of these functions
> is ideal or whether we want to add both helpers (instead of just one of
> them).
>
> proxmox-yew-widget-toolkit:
>
> Shannon Sterz (1):
>   store: add helper methods to extract a record via a selection
>
>  src/state/store.rs | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
>
> proxmox-yew-comp:
>
> Shannon Sterz (1):
>   token panel: use new `selected_record` helper
>
>  src/token_panel.rs | 11 ++---------
>  1 file changed, 2 insertions(+), 9 deletions(-)
>
>
> Summary over all repositories:
>   2 files changed, 19 insertions(+), 10 deletions(-)
>
> --
> Generated by git-murpp 0.8.1



_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-10-29 13:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-29 13:30 [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz
2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-widget-toolkit 1/1] store: add helper methods to extract a record via a selection Shannon Sterz
2025-10-29 13:30 ` [yew-devel] [RFC PATCH yew-comp 1/1] token panel: use new `selected_record` helper Shannon Sterz
2025-10-29 13:50 ` [yew-devel] [RFC yew-comp/yew-widget-toolkit 0/2] add helpers to get a record via a Selection from a Store Shannon Sterz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal