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  #[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}