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 uuid::Uuid;
9use yew::platform::spawn_local;
10use yew::prelude::*;
11
12#[derive(Clone, Debug, PartialEq, Properties)]
13pub struct CreateContractDefinitionProps {
14  #[prop_or_default]
15  pub on_create: Callback<()>,
16}
17
18#[component]
19pub fn CreateContractDefinition(props: &CreateContractDefinitionProps) -> Html {
20  let edc_connector_context = use_edc_connector_context();
21
22  let name = use_state(String::new);
23  let access_policy_definition_item = use_state(|| Option::<PolicyDefinitionItem>::None);
24  let contract_policy_definition_item = use_state(|| Option::<PolicyDefinitionItem>::None);
25  let asset_items = use_state(Vec::<AssetItem>::new);
26
27  let onsubmit = use_callback(
28    (
29      edc_connector_context.clone(),
30      name.clone(),
31      access_policy_definition_item.clone(),
32      contract_policy_definition_item.clone(),
33      asset_items.clone(),
34      props.on_create.clone(),
35    ),
36    |event: SubmitEvent,
37     (
38      edc_connector_context,
39      name,
40      access_policy_definition_item,
41      contract_policy_definition_item,
42      asset_items,
43      on_create,
44    )| {
45      event.prevent_default();
46
47      let edc_connector_context = edc_connector_context.clone();
48      let name = (**name).clone();
49      let access_policy_definition_item = (**access_policy_definition_item).clone();
50      let contract_policy_definition_item = (**contract_policy_definition_item).clone();
51      let asset_items = (**asset_items).clone();
52      let on_create = on_create.clone();
53
54      spawn_local(async move {
55        let mut new_contract_definition = NewContractDefinition::builder()
56          .id(Uuid::new_v4().to_string())
57          .private_property("name", name.clone())
58          .access_policy_id(
59            access_policy_definition_item
60              .map(|policy_definition_item| policy_definition_item.id)
61              .unwrap_or_default(),
62          )
63          .contract_policy_id(
64            contract_policy_definition_item
65              .map(|policy_definition_item| policy_definition_item.id.to_string())
66              .unwrap_or_default(),
67          );
68
69        for asset_item in &asset_items {
70          new_contract_definition = new_contract_definition.asset_selector(Criterion::new(
71            "https://w3id.org/edc/v0.0.1/ns/id",
72            "=",
73            asset_item.id.clone(),
74          ));
75        }
76
77        let new_contract_definition = new_contract_definition.build();
78
79        if let Some(client) = edc_connector_context.get_client() {
80          let _ = client
81            .contract_definitions(EdcConnectorApiVersion::V4)
82            .create(&new_contract_definition)
83            .await;
84
85          on_create.emit(());
86        }
87      })
88    },
89  );
90
91  let onchange_name = use_callback(name.setter(), move |name, name_setter| {
92    name_setter.set(name);
93  });
94
95  let onselect_access_policy = use_callback(
96    access_policy_definition_item.setter(),
97    move |access_policy_definition_item, access_policy_definition_item_setter| {
98      access_policy_definition_item_setter.set(Some(access_policy_definition_item));
99    },
100  );
101
102  let onselect_contract_policy = use_callback(
103    contract_policy_definition_item.setter(),
104    move |contract_policy, contract_policy_setter| {
105      contract_policy_setter.set(Some(contract_policy));
106    },
107  );
108
109  let disabled = (*name).is_empty()
110    || (*access_policy_definition_item).is_none()
111    || (*contract_policy_definition_item).is_none();
112
113  let onselect_assets = use_callback(asset_items.setter(), |asset_items, asset_items_setter| {
114    asset_items_setter.set(asset_items);
115  });
116
117  html!(
118    <Form {onsubmit}>
119      <FormGroup label="Name" required=true>
120        <TextInput required=true value={(*name).to_string()} onchange={onchange_name} />
121      </FormGroup>
122      <FormGroup label="Access Policy" required=true>
123        <HelperText>
124          <HelperTextItem>{ "Who is eligible to view this offer ?" }</HelperTextItem>
125        </HelperText>
126        <PolicySelector
127          onselect={onselect_access_policy}
128          selected_policy={(*access_policy_definition_item).clone()}
129          select_id="selectable-access-policy"
130        />
131      </FormGroup>
132      <FormGroup label="Contract Policy" required=true>
133        <HelperText>
134          <HelperTextItem>{ "Who is eligible to negotiate this offer ?" }</HelperTextItem>
135        </HelperText>
136        <PolicySelector
137          onselect={onselect_contract_policy}
138          selected_policy={(*contract_policy_definition_item).clone()}
139          select_id="selectable-contract-policy"
140        />
141      </FormGroup>
142      <FormGroup label="Asset Selector">
143        <HelperText>
144          <HelperTextItem>{ "Which asset is covered by this offer ?" }</HelperTextItem>
145        </HelperText>
146        <AssetSelector onselect={onselect_assets} selected_assets={(*asset_items).clone()} />
147      </FormGroup>
148      <ActionGroup>
149        <Button
150          variant={ButtonVariant::Primary}
151          label="Submit"
152          r#type={ButtonType::Submit}
153          {disabled}
154        />
155      </ActionGroup>
156    </Form>
157  )
158}