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}
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 onclick = use_callback(props.on_new_asset.clone(), |_, on_new_asset| {
39    on_new_asset.emit(());
40  });
41
42  html!(
43    <Stack gutter=true>
44      <StackItem>
45        <Split gutter=true>
46          <SplitItem fill=true>
47            <Title level={Level::H3} size={Size::XXLarge}>{ "List Assets" }</Title>
48            <p>{ "The data you hold, before any of it is offered." }</p>
49          </SplitItem>
50          <SplitItem>
51            <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
52              { "Create an Asset" }
53            </Button>
54          </SplitItem>
55        </Split>
56      </StackItem>
57      <StackItem>
58        <Suspense>
59          <AssetPageInner
60            offset={*offset}
61            limit={*limit}
62            {onoffset}
63            {onlimit}
64            onshow={props.onshow.clone()}
65            force_refresh={*refresh}
66          />
67        </Suspense>
68      </StackItem>
69    </Stack>
70  )
71}
72
73#[derive(Clone, Debug, PartialEq, Properties)]
74pub struct AssetPageInnerProps {
75  pub offset: usize,
76  pub limit: usize,
77  pub onoffset: Callback<usize>,
78  pub onlimit: Callback<usize>,
79  pub onshow: Callback<String>,
80  pub force_refresh: usize,
81}
82
83#[component]
84pub fn AssetPageInner(props: &AssetPageInnerProps) -> HtmlResult {
85  let edc_connector_context = use_edc_connector_context();
86
87  let asset_items = use_future_with(
88    (
89      edc_connector_context,
90      props.limit,
91      props.offset,
92      props.force_refresh,
93    ),
94    |parameters| async move {
95      let (edc_connector_context, limit, offset, _) = (*parameters).clone();
96
97      let query = Query::builder()
98        .limit(limit as u32)
99        .offset(offset as u32)
100        .build();
101
102      if let Some(client) = edc_connector_context.get_client() {
103        let items = client
104          .assets(EdcConnectorApiVersion::V4)
105          .query(query)
106          .await
107          .map_err(|error| {
108            log::error!("Error: {}", error);
109            error
110          })
111          .unwrap_or_default();
112
113        items.into_iter().map(AssetItem::from).collect::<Vec<_>>()
114      } else {
115        vec![]
116      }
117    },
118  )?;
119
120  let asset_items = (*asset_items).clone();
121
122  Ok(html!(
123    <ListAssets
124      asset_items={asset_items}
125      offset={props.offset}
126      limit={props.limit}
127      onoffset={props.onoffset.clone()}
128      onlimit={props.onlimit.clone()}
129      onshow={props.onshow.clone()}
130      button_label="Show"
131    />
132  ))
133}