Skip to main content

edc_web_components/pages/
my_published_offers.rs

1use crate::components::ListAssetsGallery;
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 std::collections::HashSet;
8use yew::prelude::*;
9use yew::suspense::use_future_with;
10
11#[derive(Clone, Debug, PartialEq, Properties)]
12pub struct MyPublishedOffersPageProps {
13  pub on_new_contract_definition: Callback<()>,
14  #[prop_or("My Published Offers".to_string())]
15  pub title: String,
16  #[prop_or(Some("Active data offerings that can be presented to consumers".to_string()))]
17  pub tag_line: Option<String>,
18  #[prop_or(AttrValue::Static("Show Offers"))]
19  pub button_label: AttrValue,
20  #[prop_or(AttrValue::Static("Publish a new Offer"))]
21  pub new_publish_offer_label: AttrValue,
22  pub onshow: Callback<String>,
23}
24
25#[component]
26pub fn MyPublishedOffersPage(props: &MyPublishedOffersPageProps) -> Html {
27  let refresh = use_state(|| 0usize);
28
29  let onclick = use_callback(
30    props.on_new_contract_definition.clone(),
31    |_, on_new_contract_definition| {
32      on_new_contract_definition.emit(());
33    },
34  );
35
36  let tag_line = props
37    .tag_line
38    .as_ref()
39    .map(|tag_line| html!(<p>{ tag_line }</p>))
40    .unwrap_or_default();
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}>{ &props.title }</Title>
48            { tag_line }
49          </SplitItem>
50          <SplitItem>
51            <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
52              { &props.new_publish_offer_label }
53            </Button>
54          </SplitItem>
55        </Split>
56      </StackItem>
57      <StackItem>
58        <Suspense>
59          <MyPublishedOffersPageInner
60            force_refresh={*refresh}
61            button_label={props.button_label.clone()}
62            onshow={props.onshow.clone()}
63          />
64        </Suspense>
65      </StackItem>
66    </Stack>
67  )
68}
69
70#[derive(Clone, Debug, PartialEq, Properties)]
71pub struct MyPublishedOffersPageInnerProps {
72  pub force_refresh: usize,
73  #[prop_or(AttrValue::Static("Show Offers"))]
74  pub button_label: AttrValue,
75  pub onshow: Callback<String>,
76}
77
78#[component]
79pub fn MyPublishedOffersPageInner(props: &MyPublishedOffersPageInnerProps) -> HtmlResult {
80  let edc_connector_context = use_edc_connector_context();
81
82  let asset_items = use_future_with(
83    (edc_connector_context, props.force_refresh),
84    |parameters| async move {
85      let (edc_connector_context, _) = (*parameters).clone();
86
87      let query = Query::builder().limit(1000).build();
88
89      if let Some(client) = edc_connector_context.get_client() {
90        let asset_ids: HashSet<String> = HashSet::from_iter(
91          client
92            .contract_definitions(EdcConnectorApiVersion::V4)
93            .query(query)
94            .await
95            .unwrap_or_default()
96            .into_iter()
97            .flat_map(|contract_definition| {
98              contract_definition
99                .assets_selector()
100                .iter()
101                .flat_map(|criterion| match &criterion.operand_right().0 {
102                  serde_json::Value::String(identifier) => vec![identifier.to_string()],
103                  serde_json::Value::Array(identifiers) => identifiers
104                    .iter()
105                    .map(|identifier| identifier.as_str().unwrap_or_default().to_string())
106                    .collect(),
107                  _ => vec![],
108                })
109                .collect::<Vec<_>>()
110            }),
111        );
112
113        let mut asset_items = vec![];
114
115        for asset_id in asset_ids {
116          if let Ok(asset_item) = client
117            .assets(EdcConnectorApiVersion::V4)
118            .get(&asset_id)
119            .await
120            .map(AssetItem::from)
121          {
122            asset_items.push(asset_item);
123          }
124        }
125
126        asset_items
127      } else {
128        vec![]
129      }
130    },
131  )?;
132
133  let asset_items: Vec<_> = (*asset_items).clone();
134
135  Ok(html!(
136    <ListAssetsGallery
137      {asset_items}
138      onshow={props.onshow.clone()}
139      button_label={props.button_label.clone()}
140    />
141  ))
142}