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