edc_web_components/pages/
contract_definition_page.rs1use crate::components::ListContractDefinitions;
2use crate::contexts::use_edc_connector_context;
3use crate::models::ContractDefinitionItem;
4use edc_connector_client::EdcConnectorApiVersion;
5use edc_connector_client::types::query::Query;
6use patternfly_yew::prelude::*;
7use yew::platform::spawn_local;
8use yew::prelude::*;
9use yew::suspense::use_future_with;
10
11#[derive(Clone, Debug, PartialEq, Properties)]
12pub struct ContractDefinitionPageProps {
13 pub on_new_contract_definition: Callback<()>,
14 #[prop_or_default]
15 pub on_policy_click: Callback<String>,
16 #[prop_or_default]
17 pub on_asset_click: Callback<String>,
18}
19
20#[component]
21pub fn ContractDefinitionPage(props: &ContractDefinitionPageProps) -> Html {
22 let refresh = use_state(|| 0usize);
23 let offset = use_state(|| 0usize);
24 let limit = use_state(|| 10usize);
25
26 let onoffset = use_callback(
27 (refresh.clone(), offset.setter()),
28 |offset, (refresh, offset_setter)| {
29 offset_setter.set(offset);
30 refresh.set(**refresh + 1);
31 },
32 );
33
34 let onlimit = use_callback(
35 (refresh.clone(), limit.setter()),
36 |limit, (refresh, limit_setter)| {
37 limit_setter.set(limit);
38 refresh.set(**refresh + 1);
39 },
40 );
41
42 let edc_connector_context = use_edc_connector_context();
43
44 let ondelete = use_callback(
45 (refresh.clone(), edc_connector_context),
46 |contract_definition_id: String, (refresh, edc_connector_context)| {
47 let refresh = refresh.clone();
48 let edc_connector_context = edc_connector_context.clone();
49 let contract_definition_id = contract_definition_id.clone();
50
51 spawn_local(async move {
52 if let Some(client) = edc_connector_context.get_client() {
53 let _ = client
54 .contract_definitions(EdcConnectorApiVersion::V4)
55 .delete(&contract_definition_id)
56 .await;
57 }
58 refresh.set(*refresh + 1);
59 });
60 },
61 );
62
63 let onclick = use_callback(
64 props.on_new_contract_definition.clone(),
65 |_, on_new_contract_definition| {
66 on_new_contract_definition.emit(());
67 },
68 );
69
70 html!(
71 <Stack gutter=true>
72 <StackItem>
73 <Split gutter=true>
74 <SplitItem fill=true>
75 <Title level={Level::H3} size={Size::XXLarge}>{ "List Contract Definitions" }</Title>
76 <p>
77 { "A contract definition links an asset to an access policy and a contract policy. The contract definition constitutes an offer to the other participants." }
78 </p>
79 </SplitItem>
80 <SplitItem>
81 <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
82 { "Create a Contract Definition" }
83 </Button>
84 </SplitItem>
85 </Split>
86 </StackItem>
87 <StackItem>
88 <Suspense>
89 <ContractDefinitionPageInner
90 offset={*offset}
91 limit={*limit}
92 {onoffset}
93 {onlimit}
94 {ondelete}
95 on_policy_click={props.on_policy_click.clone()}
96 on_asset_click={props.on_asset_click.clone()}
97 force_refresh={*refresh}
98 />
99 </Suspense>
100 </StackItem>
101 </Stack>
102 )
103}
104
105#[derive(Clone, Debug, PartialEq, Properties)]
106pub struct ContractDefinitionPageInnerProps {
107 pub offset: usize,
108 pub limit: usize,
109 pub onoffset: Callback<usize>,
110 pub onlimit: Callback<usize>,
111 pub ondelete: Callback<String>,
112 #[prop_or_default]
113 pub on_policy_click: Callback<String>,
114 #[prop_or_default]
115 pub on_asset_click: Callback<String>,
116 pub force_refresh: usize,
117}
118
119#[component]
120pub fn ContractDefinitionPageInner(props: &ContractDefinitionPageInnerProps) -> HtmlResult {
121 let edc_connector_context = use_edc_connector_context();
122
123 let contract_definition_items = use_future_with(
124 (
125 edc_connector_context,
126 props.limit,
127 props.offset,
128 props.force_refresh,
129 ),
130 |parameters| async move {
131 let (edc_connector_context, limit, offset, _) = (*parameters).clone();
132
133 let query = Query::builder()
134 .limit(limit as u32)
135 .offset(offset as u32)
136 .build();
137
138 if let Some(client) = edc_connector_context.get_client() {
139 client
140 .contract_definitions(EdcConnectorApiVersion::V4)
141 .query(query)
142 .await
143 .unwrap_or_default()
144 .into_iter()
145 .map(ContractDefinitionItem::from)
146 .collect()
147 } else {
148 vec![]
149 }
150 },
151 )?;
152
153 let contract_definition_items = (*contract_definition_items).clone();
154
155 Ok(html!(
156 <ListContractDefinitions
157 contract_definition_items={contract_definition_items}
158 offset={props.offset}
159 limit={props.limit}
160 onoffset={props.onoffset.clone()}
161 onlimit={props.onlimit.clone()}
162 ondelete={props.ondelete.clone()}
163 on_policy_click={props.on_policy_click.clone()}
164 on_asset_click={props.on_asset_click.clone()}
165 />
166 ))
167}