edc_web_components/components/
create_contract_definition.rs1use 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 if !asset_items.is_empty() {
70 new_contract_definition = new_contract_definition.asset_selector(Criterion::new(
71 "https://w3id.org/edc/v0.0.1/ns/id",
72 "IN",
73 asset_items
74 .iter()
75 .map(|asset_item| asset_item.id.clone())
76 .collect::<Vec<_>>(),
77 ));
78 }
79
80 let new_contract_definition = new_contract_definition.build();
81
82 if let Some(client) = edc_connector_context.get_client() {
83 let _ = client
84 .contract_definitions(EdcConnectorApiVersion::V4)
85 .create(&new_contract_definition)
86 .await;
87
88 on_create.emit(());
89 }
90 })
91 },
92 );
93
94 let onchange_name = use_callback(name.setter(), move |name, name_setter| {
95 name_setter.set(name);
96 });
97
98 let onselect_access_policy = use_callback(
99 access_policy_definition_item.setter(),
100 move |access_policy_definition_item, access_policy_definition_item_setter| {
101 access_policy_definition_item_setter.set(Some(access_policy_definition_item));
102 },
103 );
104
105 let onselect_contract_policy = use_callback(
106 contract_policy_definition_item.setter(),
107 move |contract_policy, contract_policy_setter| {
108 contract_policy_setter.set(Some(contract_policy));
109 },
110 );
111
112 let disabled = (*name).is_empty()
113 || (*access_policy_definition_item).is_none()
114 || (*contract_policy_definition_item).is_none();
115
116 let onselect_assets = use_callback(asset_items.setter(), |asset_items, asset_items_setter| {
117 asset_items_setter.set(asset_items);
118 });
119
120 html!(
121 <Form {onsubmit}>
122 <FormGroup label="Name" required=true>
123 <TextInput required=true value={(*name).to_string()} onchange={onchange_name} />
124 </FormGroup>
125 <FormGroup label="Asset Selector">
126 <HelperText>
127 <HelperTextItem>{ "Which asset is covered by this offer ?" }</HelperTextItem>
128 </HelperText>
129 <AssetSelector onselect={onselect_assets} selected_assets={(*asset_items).clone()} />
130 </FormGroup>
131 <FormGroup label="Access Policy" required=true>
132 <HelperText>
133 <HelperTextItem>{ "Who is eligible to view this offer ?" }</HelperTextItem>
134 </HelperText>
135 <PolicySelector
136 onselect={onselect_access_policy}
137 selected_policy={(*access_policy_definition_item).clone()}
138 select_id="selectable-access-policy"
139 />
140 </FormGroup>
141 <FormGroup label="Contract Policy" required=true>
142 <HelperText>
143 <HelperTextItem>{ "Who is eligible to negotiate this offer ?" }</HelperTextItem>
144 </HelperText>
145 <PolicySelector
146 onselect={onselect_contract_policy}
147 selected_policy={(*contract_policy_definition_item).clone()}
148 select_id="selectable-contract-policy"
149 />
150 </FormGroup>
151 <ActionGroup>
152 <Button
153 variant={ButtonVariant::Primary}
154 label="Submit"
155 r#type={ButtonType::Submit}
156 {disabled}
157 />
158 </ActionGroup>
159 </Form>
160 )
161}