edc_web_components/pages/
asset_page.rs1use crate::components::ListAssets;
2use crate::contexts::use_edc_connector_context;
3use crate::models::AssetItem;
4use edc_connector_client::EdcConnectorApiVersion;
5use edc_connector_client::types::query::Query;
6use patternfly_yew::prelude::*;
7use yew::platform::spawn_local;
8use yew::prelude::*;
9use yew::suspense::use_future_with;
10
11#[derive(Clone, Debug, PartialEq, Properties)]
12pub struct AssetPageProps {
13 pub on_new_asset: Callback<()>,
14}
15
16#[component]
17pub fn AssetPage(props: &AssetPageProps) -> Html {
18 let refresh = use_state(|| 0usize);
19 let offset = use_state(|| 0usize);
20 let limit = use_state(|| 10usize);
21
22 let onoffset = use_callback(
23 (refresh.clone(), offset.setter()),
24 |offset, (refresh, offset_setter)| {
25 offset_setter.set(offset);
26 refresh.set(**refresh + 1);
27 },
28 );
29
30 let onlimit = use_callback(
31 (refresh.clone(), limit.setter()),
32 |limit, (refresh, limit_setter)| {
33 limit_setter.set(limit);
34 refresh.set(**refresh + 1);
35 },
36 );
37
38 let edc_connector_context = use_edc_connector_context();
39
40 let ondelete = use_callback(
41 (refresh.clone(), edc_connector_context),
42 |asset_id: String, (refresh, edc_connector_context)| {
43 let refresh = refresh.clone();
44 let edc_connector_context = edc_connector_context.clone();
45 let asset_id = asset_id.clone();
46
47 spawn_local(async move {
48 if let Some(client) = edc_connector_context.get_client() {
49 let _ = client
50 .assets(EdcConnectorApiVersion::V4)
51 .delete(&asset_id)
52 .await;
53 }
54 refresh.set(*refresh + 1);
55 });
56 },
57 );
58
59 let onclick = use_callback(props.on_new_asset.clone(), |_, on_new_asset| {
60 on_new_asset.emit(());
61 });
62
63 html!(
64 <Stack gutter=true>
65 <StackItem>
66 <Split gutter=true>
67 <SplitItem fill=true>
68 <Title level={Level::H3} size={Size::XXLarge}>{ "List Assets" }</Title>
69 </SplitItem>
70 <SplitItem>
71 <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
72 { "Create an Asset" }
73 </Button>
74 </SplitItem>
75 </Split>
76 </StackItem>
77 <StackItem>
78 <Suspense>
79 <AssetPageInner
80 offset={*offset}
81 limit={*limit}
82 {onoffset}
83 {onlimit}
84 {ondelete}
85 force_refresh={*refresh}
86 />
87 </Suspense>
88 </StackItem>
89 </Stack>
90 )
91}
92
93#[derive(Clone, Debug, PartialEq, Properties)]
94pub struct AssetPageInnerProps {
95 pub offset: usize,
96 pub limit: usize,
97 pub onoffset: Callback<usize>,
98 pub onlimit: Callback<usize>,
99 pub ondelete: Callback<String>,
100 pub force_refresh: usize,
101}
102
103#[component]
104pub fn AssetPageInner(props: &AssetPageInnerProps) -> HtmlResult {
105 let edc_connector_context = use_edc_connector_context();
106
107 let asset_items = use_future_with(
108 (
109 edc_connector_context,
110 props.limit,
111 props.offset,
112 props.force_refresh,
113 ),
114 |parameters| async move {
115 let (edc_connector_context, limit, offset, _) = (*parameters).clone();
116
117 let query = Query::builder()
118 .limit(limit as u32)
119 .offset(offset as u32)
120 .build();
122
123 if let Some(client) = edc_connector_context.get_client() {
124 client
125 .assets(EdcConnectorApiVersion::V4)
126 .query(query)
127 .await
128 .map_err(|error| {
129 log::error!("Error: {}", error);
130 error
131 })
132 .unwrap_or_default()
133 .into_iter()
134 .map(AssetItem::from)
135 .collect::<Vec<_>>()
136 } else {
137 vec![]
138 }
139 },
140 )?;
141
142 let asset_items = (*asset_items).clone();
143
144 Ok(html!(
145 <ListAssets
146 asset_items={asset_items}
147 offset={props.offset}
148 limit={props.limit}
149 onoffset={props.onoffset.clone()}
150 onlimit={props.onlimit.clone()}
151 ondelete={props.ondelete.clone()}
152 />
153 ))
154}