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}
15
16#[component]
17pub fn ContractDefinitionPage(props: &ContractDefinitionPageProps) -> 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 edc_connector_context = use_edc_connector_context();
39
40 let ondelete = use_callback(
41 (refresh.clone(), edc_connector_context),
42 |contract_definition_id: String, (refresh, edc_connector_context)| {
43 let refresh = refresh.clone();
44 let edc_connector_context = edc_connector_context.clone();
45 let contract_definition_id = contract_definition_id.clone();
46
47 spawn_local(async move {
48 if let Some(client) = edc_connector_context.get_client() {
49 let _ = client
50 .contract_definitions(EdcConnectorApiVersion::V4)
51 .delete(&contract_definition_id)
52 .await;
53 }
54 refresh.set(*refresh + 1);
55 });
56 },
57 );
58
59 let onclick = use_callback(
60 props.on_new_contract_definition.clone(),
61 |_, on_new_contract_definition| {
62 on_new_contract_definition.emit(());
63 },
64 );
65
66 html!(
67 <Stack gutter=true>
68 <StackItem>
69 <Split gutter=true>
70 <SplitItem fill=true>
71 <Title level={Level::H3} size={Size::XXLarge}>{ "List Contract Definitions" }</Title>
72 <p>
73 { "A contract definition links an asset to an access policy and a contract policy. The contract definition constitutes an offer to the other participants." }
74 </p>
75 </SplitItem>
76 <SplitItem>
77 <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
78 { "Create a Contract Definition" }
79 </Button>
80 </SplitItem>
81 </Split>
82 </StackItem>
83 <StackItem>
84 <Suspense>
85 <ContractDefinitionPageInner
86 offset={*offset}
87 limit={*limit}
88 {onoffset}
89 {onlimit}
90 {ondelete}
91 force_refresh={*refresh}
92 />
93 </Suspense>
94 </StackItem>
95 </Stack>
96 )
97}
98
99#[derive(Clone, Debug, PartialEq, Properties)]
100pub struct ContractDefinitionPageInnerProps {
101 pub offset: usize,
102 pub limit: usize,
103 pub onoffset: Callback<usize>,
104 pub onlimit: Callback<usize>,
105 pub ondelete: Callback<String>,
106 pub force_refresh: usize,
107}
108
109#[component]
110pub fn ContractDefinitionPageInner(props: &ContractDefinitionPageInnerProps) -> HtmlResult {
111 let edc_connector_context = use_edc_connector_context();
112
113 let contract_definition_items = use_future_with(
114 (
115 edc_connector_context,
116 props.limit,
117 props.offset,
118 props.force_refresh,
119 ),
120 |parameters| async move {
121 let (edc_connector_context, limit, offset, _) = (*parameters).clone();
122
123 let query = Query::builder()
124 .limit(limit as u32)
125 .offset(offset as u32)
126 .build();
127
128 if let Some(client) = edc_connector_context.get_client() {
129 client
130 .contract_definitions(EdcConnectorApiVersion::V4)
131 .query(query)
132 .await
133 .unwrap_or_default()
134 .into_iter()
135 .map(ContractDefinitionItem::from)
136 .collect()
137 } else {
138 vec![]
139 }
140 },
141 )?;
142
143 let contract_definition_items = (*contract_definition_items).clone();
144
145 Ok(html!(
146 <ListContractDefinitions
147 contract_definition_items={contract_definition_items}
148 offset={props.offset}
149 limit={props.limit}
150 onoffset={props.onoffset.clone()}
151 onlimit={props.onlimit.clone()}
152 ondelete={props.ondelete.clone()}
153 />
154 ))
155}