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("List Contract Definitions".to_string())]
15 pub title: String,
16 #[prop_or(Some("A contract definition links an asset to an access policy and a contract policy. The contract definition constitutes an offer to the other participants".to_string()))]
17 pub tag_line: Option<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 let tag_line = props
71 .tag_line
72 .as_ref()
73 .map(|tag_line| html!(<p>{ tag_line }</p>))
74 .unwrap_or_default();
75
76 html!(
77 <Stack gutter=true>
78 <StackItem>
79 <Split gutter=true>
80 <SplitItem fill=true>
81 <Title level={Level::H3} size={Size::XXLarge}>{ &props.title }</Title>
82 { tag_line }
83 </SplitItem>
84 <SplitItem>
85 <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
86 { "Create a Contract Definition" }
87 </Button>
88 </SplitItem>
89 </Split>
90 </StackItem>
91 <StackItem>
92 <Suspense>
93 <ContractDefinitionPageInner
94 offset={*offset}
95 limit={*limit}
96 {onoffset}
97 {onlimit}
98 {ondelete}
99 force_refresh={*refresh}
100 />
101 </Suspense>
102 </StackItem>
103 </Stack>
104 )
105}
106
107#[derive(Clone, Debug, PartialEq, Properties)]
108pub struct ContractDefinitionPageInnerProps {
109 pub offset: usize,
110 pub limit: usize,
111 pub onoffset: Callback<usize>,
112 pub onlimit: Callback<usize>,
113 pub ondelete: Callback<String>,
114 pub force_refresh: usize,
115}
116
117#[component]
118pub fn ContractDefinitionPageInner(props: &ContractDefinitionPageInnerProps) -> HtmlResult {
119 let edc_connector_context = use_edc_connector_context();
120
121 let contract_definition_items = use_future_with(
122 (
123 edc_connector_context,
124 props.limit,
125 props.offset,
126 props.force_refresh,
127 ),
128 |parameters| async move {
129 let (edc_connector_context, limit, offset, _) = (*parameters).clone();
130
131 let query = Query::builder()
132 .limit(limit as u32)
133 .offset(offset as u32)
134 .build();
135
136 if let Some(client) = edc_connector_context.get_client() {
137 client
138 .contract_definitions(EdcConnectorApiVersion::V4)
139 .query(query)
140 .await
141 .unwrap_or_default()
142 .into_iter()
143 .map(ContractDefinitionItem::from)
144 .collect()
145 } else {
146 vec![]
147 }
148 },
149 )?;
150
151 let contract_definition_items = (*contract_definition_items).clone();
152
153 Ok(html!(
154 <ListContractDefinitions
155 contract_definition_items={contract_definition_items}
156 offset={props.offset}
157 limit={props.limit}
158 onoffset={props.onoffset.clone()}
159 onlimit={props.onlimit.clone()}
160 ondelete={props.ondelete.clone()}
161 />
162 ))
163}