Skip to main content

edc_web_components/pages/
policy_page.rs

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