edc_web_components/components/
create_common_expression_language.rs1use crate::components::StringListEdit;
2use crate::contexts::use_edc_connector_context;
3use edc_connector_client::EdcConnectorApiVersion;
4use edc_connector_client::types::common_expression_language::NewCommonExpressionLanguage;
5use patternfly_yew::prelude::*;
6use yew::platform::spawn_local;
7use yew::prelude::*;
8
9#[derive(Clone, Debug, PartialEq, Properties)]
10pub struct CreateCommonExpressionLanguageProps {
11 #[prop_or_default]
12 pub on_create: Callback<()>,
13}
14
15#[component]
16pub fn CreateCommonExpressionLanguage(props: &CreateCommonExpressionLanguageProps) -> Html {
17 let edc_connector_context = use_edc_connector_context();
18
19 let identifier = use_state(|| "".to_string());
20 let left_operand = use_state(|| "".to_string());
21 let catalog_scope = use_state(|| false);
22 let contract_negotiation_scope = use_state(|| false);
23 let transfer_process_scope = use_state(|| false);
24 let scopes = use_state(Vec::new);
25 let expression = use_state(|| "".to_string());
26 let description = use_state(|| "".to_string());
27
28 let onchange_identifier = use_callback(identifier.setter(), |value, identifier_setter| {
29 identifier_setter.set(value);
30 });
31
32 let onchange_left_operand = use_callback(left_operand.setter(), |value, left_operand_setter| {
33 left_operand_setter.set(value);
34 });
35
36 let onchange_scopes = use_callback(scopes.setter(), |value: Vec<String>, scopes_setter| {
37 scopes_setter.set(value);
38 });
39
40 let onchange_expression =
41 use_callback(expression.setter(), |value: String, expression_setter| {
42 expression_setter.set(value);
43 });
44
45 let onchange_description = use_callback(description.setter(), |value, description_setter| {
46 description_setter.set(value);
47 });
48
49 let onsubmit = use_callback(
50 (
51 edc_connector_context.clone(),
52 identifier.clone(),
53 left_operand.clone(),
54 catalog_scope.clone(),
55 contract_negotiation_scope.clone(),
56 transfer_process_scope.clone(),
57 scopes.clone(),
58 expression.clone(),
59 description.clone(),
60 props.on_create.clone(),
61 ),
62 |event: SubmitEvent,
63 (
64 edc_connector_context,
65 identifier,
66 left_operand,
67 catalog_scope,
68 contract_negotiation_scope,
69 transfer_process_scope,
70 scopes,
71 expression,
72 description,
73 on_create,
74 )| {
75 event.prevent_default();
76
77 let edc_connector_context = edc_connector_context.clone();
78 let identifier = (**identifier).clone();
79 let left_operand = (**left_operand).clone();
80 let catalog_scope = **catalog_scope;
81 let contract_negotiation_scope = **contract_negotiation_scope;
82 let transfer_process_scope = **transfer_process_scope;
83 let mut scopes = (**scopes).clone();
84 let expression = (**expression).clone();
85 let description = (**description).clone();
86 let on_create = on_create.clone();
87
88 if catalog_scope {
89 scopes.push("catalog".to_string());
90 }
91 if contract_negotiation_scope {
92 scopes.push("contract.negotiation".to_string());
93 }
94 if transfer_process_scope {
95 scopes.push("transfer.process".to_string());
96 }
97
98 spawn_local(async move {
99 let new_common_expression_language_builder = NewCommonExpressionLanguage::builder();
100
101 let new_common_expression_language_builder = new_common_expression_language_builder
102 .expression(expression)
103 .left_operand(left_operand)
104 .description(description)
105 .scopes(scopes);
106
107 let new_common_expression_language = if identifier.is_empty() {
108 new_common_expression_language_builder.build()
109 } else {
110 new_common_expression_language_builder
111 .id(identifier)
112 .build()
113 };
114
115 if let Some(client) = edc_connector_context.get_client() {
116 if let Err(error) = client
117 .common_expression_language(EdcConnectorApiVersion::V5Beta)
118 .create(&new_common_expression_language)
119 .await
120 {
121 log::error!("Error creating asset: {}", error);
122 } else {
123 on_create.emit(());
124 }
125 }
126 })
127 },
128 );
129
130 let disabled = false;
131
132 let onchange_catalog_scope = use_callback(
133 catalog_scope.setter(),
134 |checkbox_state, catalog_scope_setter| {
135 catalog_scope_setter.set(checkbox_state == CheckboxState::Checked);
136 },
137 );
138 let onchange_contract_negotiation_scope = use_callback(
139 contract_negotiation_scope.setter(),
140 |checkbox_state, contract_negotiation_setter| {
141 contract_negotiation_setter.set(checkbox_state == CheckboxState::Checked)
142 },
143 );
144 let onchange_transfer_process_scope = use_callback(
145 transfer_process_scope.setter(),
146 |checkbox_state, transfer_process_setter| {
147 transfer_process_setter.set(checkbox_state == CheckboxState::Checked)
148 },
149 );
150
151 html!(
152 <Form {onsubmit}>
153 <FormGroup label="Identifier" required=true>
154 <TextInput required=true value={(*identifier).to_string()} onchange={onchange_identifier} />
155 </FormGroup>
156 <FormGroup label="Left Operand" required=true>
157 <TextInput
158 required=true
159 value={(*left_operand).to_string()}
160 onchange={onchange_left_operand}
161 />
162 </FormGroup>
163 <FormGroup label="Scopes">
164 <Stack gutter=true>
165 <StackItem>
166 <Checkbox label="Catalog" onchange={onchange_catalog_scope} checked={*catalog_scope} />
167 </StackItem>
168 <StackItem>
169 <Checkbox
170 label="Contract Negotiation"
171 onchange={onchange_contract_negotiation_scope}
172 checked={*contract_negotiation_scope}
173 />
174 </StackItem>
175 <StackItem>
176 <Checkbox
177 label="Transfer Process"
178 onchange={onchange_transfer_process_scope}
179 checked={*transfer_process_scope}
180 />
181 </StackItem>
182 <StackItem>
183 <StringListEdit
184 values={(*scopes).clone()}
185 onchange={onchange_scopes}
186 add_button_label="Add Extra Scope"
187 />
188 </StackItem>
189 </Stack>
190 </FormGroup>
191 <FormGroupValidated<TextArea>
192 label="Expression"
193 required=true
194 validator={Validator::from(|ctx: ValidationContext<String>| {
195 if ctx.initial {
196 ValidationResult::default()
197 } else if ctx.value.is_empty() {
198 ValidationResult::error("Must not be empty")
199 } else {
200 match cel::Program::compile(&ctx.value) {
201 Ok(_) => ValidationResult::new(InputState::Success, ""),
202 Err(errors) => ValidationResult::error(errors.to_string())
203 }
204 }
205 })}
206 >
207 <TextArea required=true value={(*expression).to_string()} onchange={onchange_expression} />
208 </FormGroupValidated<TextArea>>
209 <FormGroup label="Description">
210 <TextArea value={(*description).to_string()} onchange={onchange_description} />
211 </FormGroup>
212 <ActionGroup>
213 <Button
214 variant={ButtonVariant::Primary}
215 label="Submit"
216 r#type={ButtonType::Submit}
217 {disabled}
218 />
219 <Button variant={ButtonVariant::Secondary} label="Reset" r#type={ButtonType::Reset} />
220 </ActionGroup>
221 </Form>
222 )
223}