Skip to main content

edc_web_components/pages/
asset_page.rs

1use 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 Asset".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}