Skip to main content

edc_web_ui/pages/
policy_page.rs

1use crate::components::{CreatePolicy, ListPolicies};
2use crate::contexts::use_edc_connector_context;
3use crate::models::PolicyDefinitionItem;
4use edc_connector_client::types::query::Query;
5use patternfly_yew::prelude::*;
6use yew::platform::spawn_local;
7use yew::prelude::*;
8use yew::suspense::use_future_with;
9
10#[component]
11pub fn PolicyPage() -> Html {
12  let refresh = use_state(|| 0usize);
13  let backdropper = use_backdrop();
14  let offset = use_state(|| 0usize);
15  let limit = use_state(|| 10usize);
16
17  let onoffset = use_callback(
18    (refresh.clone(), offset.setter()),
19    |offset, (refresh, offset_setter)| {
20      offset_setter.set(offset);
21      refresh.set(**refresh + 1);
22    },
23  );
24
25  let onlimit = use_callback(
26    (refresh.clone(), limit.setter()),
27    |limit, (refresh, limit_setter)| {
28      limit_setter.set(limit);
29      refresh.set(**refresh + 1);
30    },
31  );
32
33  let edc_connector_context = use_edc_connector_context();
34
35  let ondelete = use_callback(
36    (refresh.clone(), edc_connector_context),
37    |policy_id: String, (refresh, edc_connector_context)| {
38      let refresh = refresh.clone();
39      let edc_connector_context = edc_connector_context.clone();
40      let policy_id = policy_id.clone();
41
42      spawn_local(async move {
43        if let Some(client) = edc_connector_context.get_client() {
44          let _ = client.policies().delete(&policy_id).await;
45          log::warn!("Deleted policy {} - {}", policy_id, *refresh + 1);
46          refresh.set(*refresh + 1);
47        }
48      });
49    },
50  );
51
52  let on_create = use_callback(
53    (backdropper.clone(), refresh.clone()),
54    |_, (backdropper, refresh)| {
55      if let Some(backdropper) = backdropper {
56        backdropper.close();
57      }
58
59      refresh.set(**refresh + 1);
60    },
61  );
62
63  let onclick = use_callback((backdropper, on_create), |_, (backdropper, on_create)| {
64    if let Some(backdropper) = backdropper {
65      backdropper.open(html!(
66        <Bullseye>
67          <Modal variant={ModalVariant::Medium} title="Create an Policy">
68            <CreatePolicy {on_create} />
69          </Modal>
70        </Bullseye>
71      ))
72    }
73  });
74
75  html!(
76    <Stack gutter=true>
77      <StackItem>
78        <Split gutter=true>
79          <SplitItem fill=true>
80            <Title level={Level::H3} size={Size::XXLarge}>{ "List Policies" }</Title>
81          </SplitItem>
82          <SplitItem>
83            <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>{ "Add" }</Button>
84          </SplitItem>
85        </Split>
86      </StackItem>
87      <StackItem>
88        <Card>
89          <CardBody>
90            <Suspense>
91              <PolicyPageInner
92                offset={*offset}
93                limit={*limit}
94                {onoffset}
95                {onlimit}
96                {ondelete}
97                force_refresh={*refresh}
98              />
99            </Suspense>
100          </CardBody>
101        </Card>
102      </StackItem>
103    </Stack>
104  )
105}
106
107#[derive(Clone, Debug, PartialEq, Properties)]
108pub struct PolicyPageInnerProps {
109  pub offset: usize,
110  pub limit: usize,
111  pub onoffset: Callback<usize>,
112  pub onlimit: Callback<usize>,
113  pub ondelete: Callback<String>,
114  pub force_refresh: usize,
115}
116
117#[component]
118pub fn PolicyPageInner(props: &PolicyPageInnerProps) -> HtmlResult {
119  let edc_connector_context = use_edc_connector_context();
120
121  let policy_definition_items = use_future_with(
122    (
123      edc_connector_context,
124      props.limit,
125      props.offset,
126      props.force_refresh,
127    ),
128    |parameters| async move {
129      let (edc_connector_context, limit, offset, _) = (*parameters).clone();
130
131      let query = Query::builder()
132        .limit(limit as u32)
133        .offset(offset as u32)
134        .build();
135
136      if let Some(client) = edc_connector_context.get_client() {
137        client
138          .policies()
139          .query(query)
140          .await
141          .unwrap_or_default()
142          .into_iter()
143          .map(PolicyDefinitionItem::from)
144          .collect::<Vec<_>>()
145      } else {
146        vec![]
147      }
148    },
149  )?;
150
151  let policy_definition_items = (*policy_definition_items).clone();
152
153  Ok(html!(
154    <ListPolicies
155      policy_definition_items={policy_definition_items}
156      offset={props.offset}
157      limit={props.limit}
158      onoffset={props.onoffset.clone()}
159      onlimit={props.onlimit.clone()}
160      ondelete={props.ondelete.clone()}
161    />
162  ))
163}