edc_web_ui/pages/
policy_page.rs1use 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}