Skip to main content

edc_web_components/components/
create_contract_definition.rs

1use crate::components::{AssetSelector, PolicySelector};
2use crate::contexts::use_edc_connector_context;
3use crate::models::{AssetItem, PolicyDefinitionItem};
4use edc_connector_client::EdcConnectorApiVersion;
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(String::new);
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_items = use_state(Vec::<AssetItem>::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_items.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_items,
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_items = (**asset_items).clone();
51      let on_create = on_create.clone();
52
53      spawn_local(async move {
54        let mut 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        for asset_item in &asset_items {
68          new_contract_definition = new_contract_definition.asset_selector(Criterion::new(
69            "https://w3id.org/edc/v0.0.1/ns/id",
70            "=",
71            asset_item.id.clone(),
72          ));
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(EdcConnectorApiVersion::V4)
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 onselect_assets = use_callback(asset_items.setter(), |asset_items, asset_items_setter| {
113    asset_items_setter.set(asset_items);
114  });
115
116  html!(
117    <Form {onsubmit}>
118      <FormGroup label="Identifier" required=true>
119        <TextInput required=true value={(*identifier).to_string()} onchange={onchange_identifier} />
120      </FormGroup>
121      <FormGroup label="Access Policy" required=true>
122        <PolicySelector
123          onselect={onselect_access_policy}
124          selected_policy={(*access_policy_definition_item).clone()}
125          select_id="selectable-access-policy"
126        />
127      </FormGroup>
128      <FormGroup label="Contract Policy" required=true>
129        <PolicySelector
130          onselect={onselect_contract_policy}
131          selected_policy={(*contract_policy_definition_item).clone()}
132          select_id="selectable-contract-policy"
133        />
134      </FormGroup>
135      <FormGroup label="Asset Selector">
136        <AssetSelector onselect={onselect_assets} selected_assets={(*asset_items).clone()} />
137      </FormGroup>
138      <ActionGroup>
139        <Button
140          variant={ButtonVariant::Primary}
141          label="Submit"
142          r#type={ButtonType::Submit}
143          {disabled}
144        />
145      </ActionGroup>
146    </Form>
147  )
148}