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