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