edc_web_components/pages/
show_policy_page.rs1use crate::components::ConstraintRenderer;
2use crate::contexts::use_edc_connector_context;
3use edc_connector_client::types::policy::PolicyKind;
4use patternfly_yew::prelude::*;
5use yew::prelude::*;
6use yew::suspense::use_future_with;
7
8#[derive(Clone, Debug, PartialEq, Properties)]
9pub struct ShowPolicyPageProps {
10 pub policy_id: String,
11}
12
13#[component]
14pub fn ShowPolicyPage(props: &ShowPolicyPageProps) -> Html {
15 html!(
16 <>
17 <Title level={Level::H2} size={Size::XXXLarge}>{ "Policy" }</Title>
18 <Suspense fallback="Loading ...">
19 <ShowPolicyPageInner policy_id={props.policy_id.clone()} />
20 </Suspense>
21 </>
22 )
23}
24
25#[component]
26pub fn ShowPolicyPageInner(props: &ShowPolicyPageProps) -> HtmlResult {
27 let edc_connector_client = use_edc_connector_context();
28
29 let policy = use_future_with(
30 (props.policy_id.clone(), edc_connector_client.clone()),
31 |properties| async move {
32 let (policy_id, edc_connector_client) = (*properties).clone();
33
34 if let Some(client) = edc_connector_client.get_client() {
35 client
36 .policies(edc_connector_client::EdcConnectorApiVersion::V4)
37 .get(&policy_id)
38 .await
39 .ok()
40 } else {
41 None
42 }
43 },
44 )?;
45
46 let policy = (*policy).clone();
47
48 if let Some(policy) = policy {
49 let kind = match policy.policy().kind() {
50 PolicyKind::Set => "Set",
51 PolicyKind::Offer => "Offer",
52 PolicyKind::Agreement => "Agreement",
53 };
54
55 let permissions = policy.policy().permissions().iter().map(|permission| {
56 html! {
57 <ConstraintRenderer
58 action={permission.action().clone()}
59 constraints={permission.constraints().to_vec()}
60 />
61 }
62 });
63
64 let obligations = policy.policy().obligations().iter().map(|obligation| {
65 html! {
66 <ConstraintRenderer
67 action={obligation.action().clone()}
68 constraints={obligation.constraints().to_vec()}
69 />
70 }
71 });
72
73 let prohibitions = policy.policy().prohibitions().iter().map(|prohibition| {
74 html! {
75 <ConstraintRenderer
76 action={prohibition.action().clone()}
77 constraints={prohibition.constraints().to_vec()}
78 />
79 }
80 });
81
82 let profiles = policy.policy().profiles().iter().map(|profile| {
83 html_nested! {
84 <FlexItem>
85 <Label color={Color::Blue} label={profile.to_string()} />
86 </FlexItem>
87 }
88 });
89
90 let extensible_properties =
91 policy
92 .policy()
93 .extensible_properties()
94 .iter()
95 .map(|(key, value)| {
96 html_nested! {
97 <StackItem>
98 <DescriptionGroup term={key.to_string()}>
99 <CodeBlock>
100 <CodeBlockCode>
101 { serde_json::to_string_pretty(value).unwrap_or_default() }
102 </CodeBlockCode>
103 </CodeBlock>
104 </DescriptionGroup>
105 </StackItem>
106 }
107 });
108
109 Ok(html!(
110 <DescriptionList mode={[DescriptionListMode::Horizontal]}>
111 <DescriptionGroup term="Id">{ policy.id() }</DescriptionGroup>
112 <DescriptionGroup term="Kind">{ kind }</DescriptionGroup>
113 <DescriptionGroup term="Assigner">
114 { policy.policy().assigner().cloned().unwrap_or_default() }
115 </DescriptionGroup>
116 <DescriptionGroup term="Assignee">
117 { policy.policy().assignee().cloned().unwrap_or_default() }
118 </DescriptionGroup>
119 <DescriptionGroup term="Permissions">{ for permissions }</DescriptionGroup>
120 <DescriptionGroup term="Obligations">{ for obligations }</DescriptionGroup>
121 <DescriptionGroup term="Prohibitions">{ for prohibitions }</DescriptionGroup>
122 <DescriptionGroup term="Profiles">
123 <Flex>{ for profiles }</Flex>
124 </DescriptionGroup>
125 <DescriptionGroup term="Extensible Properties">
126 <DescriptionList mode={[DescriptionListMode::Horizontal]}>
127 { for extensible_properties }
128 </DescriptionList>
129 </DescriptionGroup>
130 </DescriptionList>
131 ))
132 } else {
133 Ok(html!(
134 format!(
135 "Policy with id {} not found.",
136 props.policy_id
137 )
138 ))
139 }
140}