Skip to main content

edc_web_components/pages/
contract_definition_page.rs

1use 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}