Skip to main content

edc_web_components/components/
extensible_properties_edit.rs

1use patternfly_yew::prelude::*;
2use serde_json::Value;
3use std::collections::HashMap;
4use yew::prelude::*;
5
6#[derive(Clone, Debug, PartialEq, Properties)]
7pub struct ExtensiblePropertiesEditProps {
8  pub values: HashMap<String, Value>,
9  pub onchange: Callback<HashMap<String, Value>>,
10}
11
12#[component]
13pub fn ExtensiblePropertiesEdit(props: &ExtensiblePropertiesEditProps) -> Html {
14  let onclick = use_callback(
15    (props.values.clone(), props.onchange.clone()),
16    |_, (values, onchange)| {
17      let mut values = values.clone();
18      values.insert("".to_string(), Value::Null);
19      onchange.emit(values);
20    },
21  );
22
23  let onchange_key = use_callback(
24    (props.values.clone(), props.onchange.clone()),
25    |(old_key, key), (values, onchange)| {
26      let mut values = values.clone();
27
28      if let Some(value) = values.remove(&old_key) {
29        values.insert(key, value);
30        onchange.emit(values);
31      }
32    },
33  );
34
35  let onchange_value = use_callback(
36    (props.values.clone(), props.onchange.clone()),
37    |(key, value): (String, String), (values, onchange)| {
38      let mut values = values.clone();
39
40      let value = serde_json::from_str(&value).unwrap_or_default();
41
42      values.insert(key, value);
43      onchange.emit(values);
44    },
45  );
46
47  let items = props.values.iter().map(|(key, value)| {
48    let old_key = key.to_string();
49    let key = key.to_string();
50
51    let serde_json_value = serde_json::to_string_pretty(value).unwrap_or_default();
52
53    html_nested!(
54      <>
55        <GridItem cols={[4]}>
56          <FormGroup label="Key" required=true>
57            <TextInput
58              required=true
59              value={key.to_string()}
60              onchange={onchange_key.reform(move |key| (old_key.clone(), key))}
61            />
62          </FormGroup>
63        </GridItem>
64        <GridItem cols={[8]}>
65          <FormGroup
66            label="Value"
67            label_icon={LabelIcon::Help(html_nested!(<PopoverBody>{ "Enter a valid json." } </PopoverBody>))}
68          >
69            <TextInput
70              required=true
71              value={serde_json_value}
72              onchange={onchange_value.reform(move |value| (key.clone(), value))}
73            />
74          </FormGroup>
75        </GridItem>
76      </>
77    )
78  });
79
80  html!(
81    <Stack gutter=true>
82      <StackItem>
83        <Button variant={ButtonVariant::Primary} icon={Icon::Plus} {onclick}>{ "Add" }</Button>
84      </StackItem>
85      <StackItem>
86        <Grid gutter=true>{ for items }</Grid>
87      </StackItem>
88    </Stack>
89  )
90}