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          <TextInput
57            required=true
58            value={key.to_string()}
59            onchange={onchange_key.reform(move |key| (old_key.clone(), key))}
60          />
61        </GridItem>
62        <GridItem cols={[8]}>
63          <TextInput
64            required=true
65            value={serde_json_value}
66            onchange={onchange_value.reform(move |value| (key.clone(), value))}
67          />
68        </GridItem>
69      </>
70    )
71  });
72
73  html!(
74    <Stack gutter=true>
75      <StackItem>
76        <Button variant={ButtonVariant::Primary} icon={Icon::Plus} {onclick}>{ "Add" }</Button>
77      </StackItem>
78      <StackItem>
79        <Grid>{ for items }</Grid>
80      </StackItem>
81    </Stack>
82  )
83}