Skip to main content

edc_web_ui/components/
create_contract_definition.rs

1use crate::components::PolicySelector;
2use crate::components::criterion_edit::CriterionEdit;
3use crate::contexts::use_edc_connector_context;
4use crate::models::PolicyDefinitionItem;
5use edc_connector_client::types::contract_definition::NewContractDefinition;
6use edc_connector_client::types::query::Criterion;
7use patternfly_yew::prelude::*;
8use yew::platform::spawn_local;
9use yew::prelude::*;
10
11#[derive(Clone, Debug, PartialEq, Properties)]
12pub struct CreateContractDefinitionProps {
13  #[prop_or_default]
14  pub on_create: Callback<()>,
15}
16
17#[component]
18pub fn CreateContractDefinition(props: &CreateContractDefinitionProps) -> Html {
19  let edc_connector_context = use_edc_connector_context();
20
21  let identifier = use_state(|| "".to_string());
22  let access_policy_definition_item = use_state(|| Option::<PolicyDefinitionItem>::None);
23  let contract_policy_definition_item = use_state(|| Option::<PolicyDefinitionItem>::None);
24  let asset_selector = use_state(|| (String::new(), String::new(), String::new()));
25
26  let onsubmit = use_callback(
27    (
28      edc_connector_context.clone(),
29      identifier.clone(),
30      access_policy_definition_item.clone(),
31      contract_policy_definition_item.clone(),
32      asset_selector.clone(),
33      props.on_create.clone(),
34    ),
35    |event: SubmitEvent,
36     (
37      edc_connector_context,
38      identifier,
39      access_policy_definition_item,
40      contract_policy_definition_item,
41      asset_selector,
42      on_create,
43    )| {
44      event.prevent_default();
45
46      let edc_connector_context = edc_connector_context.clone();
47      let identifier = (**identifier).clone();
48      let access_policy_definition_item = (**access_policy_definition_item).clone();
49      let contract_policy_definition_item = (**contract_policy_definition_item).clone();
50      let asset_selector = (**asset_selector).clone();
51      let on_create = on_create.clone();
52
53      spawn_local(async move {
54        let new_contract_definition = NewContractDefinition::builder()
55          .id(&identifier)
56          .access_policy_id(
57            access_policy_definition_item
58              .map(|policy_definition_item| policy_definition_item.id)
59              .unwrap_or_default(),
60          )
61          .contract_policy_id(
62            contract_policy_definition_item
63              .map(|policy_definition_item| policy_definition_item.id.to_string())
64              .unwrap_or_default(),
65          );
66
67        let (left, operator, right) = asset_selector;
68        let new_contract_definition =
69          if !left.is_empty() && !operator.is_empty() && !right.is_empty() {
70            new_contract_definition.asset_selector(Criterion::new(&left, &operator, &right))
71          } else {
72            new_contract_definition
73          };
74
75        let new_contract_definition = new_contract_definition.build();
76
77        if let Some(client) = edc_connector_context.get_client() {
78          let _ = client
79            .contract_definitions()
80            .create(&new_contract_definition)
81            .await;
82
83          on_create.emit(());
84        }
85      })
86    },
87  );
88
89  let onchange_identifier =
90    use_callback(identifier.setter(), move |identifier, identifier_setter| {
91      identifier_setter.set(identifier);
92    });
93
94  let onselect_access_policy = use_callback(
95    access_policy_definition_item.setter(),
96    move |access_policy_definition_item, access_policy_definition_item_setter| {
97      access_policy_definition_item_setter.set(Some(access_policy_definition_item));
98    },
99  );
100
101  let onselect_contract_policy = use_callback(
102    contract_policy_definition_item.setter(),
103    move |contract_policy, contract_policy_setter| {
104      contract_policy_setter.set(Some(contract_policy));
105    },
106  );
107
108  let disabled = (*identifier).is_empty()
109    || (*access_policy_definition_item).is_none()
110    || (*contract_policy_definition_item).is_none();
111
112  let (operand_left, operator, operand_right) = (*asset_selector).clone();
113
114  let onchange_asset_selection = {
115    let asset_selector = asset_selector.clone();
116
117    use_callback((), move |value, _| {
118      asset_selector.set(value);
119    })
120  };
121
122  html!(
123    <Form {onsubmit}>
124      <FormGroup label="Identifier" required=true>
125        <TextInput required=true value={(*identifier).to_string()} onchange={onchange_identifier} />
126      </FormGroup>
127      <FormGroup label="Access Policy" required=true>
128        <PolicySelector
129          onselect={onselect_access_policy}
130          selected_policy={(*access_policy_definition_item).clone()}
131          select_id="selectable-access-policy"
132        />
133      </FormGroup>
134      <FormGroup label="Contract Policy" required=true>
135        <PolicySelector
136          onselect={onselect_contract_policy}
137          selected_policy={(*contract_policy_definition_item).clone()}
138          select_id="selectable-contract-policy"
139        />
140      </FormGroup>
141      <FormGroup label="Asset Selector">
142        <CriterionEdit
143          {operand_left}
144          {operator}
145          {operand_right}
146          onchange={onchange_asset_selection}
147        />
148      </FormGroup>
149      <ActionGroup>
150        <Button
151          variant={ButtonVariant::Primary}
152          label="Submit"
153          r#type={ButtonType::Submit}
154          {disabled}
155        />
156      </ActionGroup>
157    </Form>
158  )
159}