edc_web_ui/components/
create_contract_negotiation.rs

1use crate::contexts::use_edc_connector_context;
2use edc_connector_client::types::contract_negotiation::ContractRequest;
3use edc_connector_client::types::policy::Policy;
4use edc_connector_client::types::query::Query;
5use patternfly_yew::prelude::*;
6use std::fmt::{Display, Formatter};
7use yew::platform::spawn_local;
8use yew::prelude::*;
9use yew::suspense::use_future;
10
11#[function_component]
12pub fn CreateContractNegotiation() -> Html {
13  html!(
14    <Suspense>
15      <CreateContractNegotiationInner />
16    </Suspense>
17  )
18}
19
20#[function_component]
21pub fn CreateContractNegotiationInner() -> HtmlResult {
22  let edc_connector_context = use_edc_connector_context();
23
24  let counter_party_address = use_state(|| "".to_string());
25  let counter_party_id = use_state(|| "".to_string());
26  let policy = use_state(|| None);
27
28  let policies = {
29    let edc_connector_context = edc_connector_context.clone();
30
31    use_future(|| async move {
32      if let Some(client) = edc_connector_context.get_client() {
33        let query = Query::default();
34        let policies = client.policies().query(query).await.unwrap_or_default();
35
36        policies
37          .iter()
38          .map(|policy| PolicySelector(policy.id().to_string(), policy.policy().clone()))
39          .collect::<Vec<_>>()
40      } else {
41        vec![]
42      }
43    })?
44  };
45
46  let onsubmit = use_callback(
47    (
48      edc_connector_context.clone(),
49      counter_party_address.clone(),
50      counter_party_id.clone(),
51      policy.clone(),
52    ),
53    |event: SubmitEvent,
54     (edc_connector_context, counter_party_address, counter_party_id, policy)| {
55      event.prevent_default();
56
57      let edc_connector_context = edc_connector_context.clone();
58      let counter_party_address = (**counter_party_address).clone();
59      let counter_party_id = (**counter_party_id).clone();
60      let policy: Option<PolicySelector> = (**policy).clone();
61
62      spawn_local(async move {
63        if let Some(policy) = policy {
64          let contract_request = ContractRequest::builder()
65            .counter_party_address(counter_party_address)
66            .counter_party_id(counter_party_id)
67            .policy(policy.1)
68            .build();
69
70          if let Some(client) = edc_connector_context.get_client() {
71            let _ = client
72              .contract_negotiations()
73              .initiate(&contract_request)
74              .await;
75          }
76        }
77      })
78    },
79  );
80
81  let onchange_counter_party_address = {
82    let counter_party_address = counter_party_address.clone();
83
84    use_callback((), move |value, _| {
85      counter_party_address.set(value);
86    })
87  };
88
89  let onchange_counter_party_id = {
90    let counter_party_id = counter_party_id.clone();
91
92    use_callback((), move |value, _| {
93      counter_party_id.set(value);
94    })
95  };
96
97  let onselect_policy = {
98    let policy = policy.clone();
99
100    use_callback((), move |value, _| {
101      policy.set(Some(value));
102    })
103  };
104
105  let disabled = (*policy).is_none();
106
107  Ok(html!(
108    <Form {onsubmit}>
109      <FormGroup
110        label={"Counter Party Address"}
111        required={true}
112        >
113        <TextInput
114          required={true}
115          value={(*counter_party_address).to_string()}
116          onchange={onchange_counter_party_address}
117          />
118      </FormGroup>
119
120      <FormGroup
121        label={"Counter Party ID"}
122        required={true}
123        >
124        <TextInput
125          required={true}
126          value={(*counter_party_id).to_string()}
127          onchange={onchange_counter_party_id}
128          />
129      </FormGroup>
130
131      <FormGroup
132        label={"Policy"}
133        required={true}
134        >
135        <SimpleSelect<PolicySelector>
136          selected={(*policy).clone()}
137          onselect={onselect_policy}
138          entries={(*policies).clone()}
139          />
140      </FormGroup>
141
142      <ActionGroup>
143        <Button
144          variant={ButtonVariant::Primary}
145          label="Submit"
146          r#type={ButtonType::Submit}
147          {disabled}
148          />
149        <Button variant={ButtonVariant::Secondary} label="Reset" r#type={ButtonType::Reset}/>
150      </ActionGroup>
151    </Form>
152  ))
153}
154
155#[derive(Clone, PartialEq)]
156struct PolicySelector(String, Policy);
157
158impl Eq for PolicySelector {}
159
160impl Display for PolicySelector {
161  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
162    f.write_str(&self.0.clone())
163  }
164}