Skip to main content

edc_web_components/components/
create_common_expression_language.rs

1use 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}