edc_web_components/pages/
my_published_offers.rs1use 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}