edc_web_ui/components/
create_policy.rs1use crate::components::list_of_rules::ListOfRules;
2use crate::components::simple_or_id_field::SimpleOrIdField;
3use crate::contexts::use_edc_connector_context;
4use edc_connector_client::types::policy::{
5 Action, Constraint, NewPolicyDefinition, Obligation, Permission, Policy, PolicyKind, Prohibition,
6 Target,
7};
8use patternfly_yew::prelude::*;
9use yew::platform::spawn_local;
10use yew::prelude::*;
11
12#[derive(Copy, Clone, PartialEq, Eq, strum::Display)]
13enum Options {
14 Agreement,
15 Offer,
16 Set,
17}
18
19#[function_component]
20pub fn CreatePolicy() -> Html {
21 let edc_connector_context = use_edc_connector_context();
22
23 let identifier = use_state(String::new);
24 let kind = use_state(|| Options::Set);
25 let assignee = use_state(String::default);
26 let assigner = use_state(String::default);
27 let target = use_state(|| (true, String::default()));
28 let permissions = use_state(Vec::new);
29 let prohibitions = use_state(Vec::new);
30 let obligations = use_state(Vec::new);
31
32 let onsubmit = use_callback(
33 (
34 edc_connector_context,
35 identifier.clone(),
36 kind.clone(),
37 assignee.clone(),
38 assigner.clone(),
39 target.clone(),
40 permissions.clone(),
41 prohibitions.clone(),
42 obligations.clone(),
43 ),
44 |event: SubmitEvent,
45 (
46 edc_connector_context,
47 identifier,
48 kind,
49 assignee,
50 assigner,
51 target,
52 permissions,
53 prohibitions,
54 obligations,
55 )| {
56 event.prevent_default();
57
58 let edc_connector_context = edc_connector_context.clone();
59 let identifier = (**identifier).clone();
60 let kind = **kind;
61 let assignee = (**assignee).clone();
62 let assigner = (**assigner).clone();
63 let (is_simple_target, target) = (**target).clone();
64
65 let permissions = (**permissions)
66 .iter()
67 .map(|(action, constraints): &(Action, Vec<Constraint>)| {
68 Permission::builder()
69 .action(action.clone())
70 .constraints(constraints.clone())
71 .build()
72 })
73 .collect();
74
75 let prohibitions = (**prohibitions)
76 .iter()
77 .map(|(action, constraints): &(Action, Vec<Constraint>)| {
78 Prohibition::builder()
79 .action(action.clone())
80 .constraints(constraints.clone())
81 .build()
82 })
83 .collect();
84
85 let obligations = (**obligations)
86 .iter()
87 .map(|(action, constraints): &(Action, Vec<Constraint>)| {
88 Obligation::builder()
89 .action(action.clone())
90 .constraints(constraints.clone())
91 .build()
92 })
93 .collect();
94
95 spawn_local(async move {
96 let kind = match kind {
97 Options::Agreement => PolicyKind::Agreement,
98 Options::Offer => PolicyKind::Offer,
99 Options::Set => PolicyKind::Set,
100 };
101
102 let policy_builder = Policy::builder()
103 .kind(kind)
104 .permissions(permissions)
105 .prohibitions(prohibitions)
106 .obligations(obligations);
107
108 let policy_builder = if !assignee.is_empty() {
109 policy_builder.maybe_assignee(Some(assignee))
110 } else {
111 policy_builder.maybe_assignee(None::<String>)
112 };
113
114 let policy_builder = if !assigner.is_empty() {
115 policy_builder.maybe_assigner(Some(assigner))
116 } else {
117 policy_builder.maybe_assigner(None::<String>)
118 };
119
120 let policy_builder = if !target.is_empty() {
121 if is_simple_target {
122 policy_builder.target(Target::Simple(target))
123 } else {
124 policy_builder.target(Target::Id { id: target })
125 }
126 } else {
127 policy_builder.maybe_target(None::<Target>)
128 };
129
130 let policy = policy_builder.build();
131
132 let new_policy = NewPolicyDefinition::builder()
133 .id(&identifier)
134 .policy(policy)
135 .build();
136
137 if let Some(client) = edc_connector_context.get_client() {
138 let _ = client.policies().create(&new_policy).await;
139 }
140 })
141 },
142 );
143
144 let onchange_identifier = {
145 let identifier = identifier.clone();
146
147 use_callback((), move |value, _| {
148 identifier.set(value);
149 })
150 };
151
152 let onselect_kind = {
153 let kind = kind.clone();
154
155 use_callback((), move |value, _| {
156 kind.set(value);
157 })
158 };
159
160 let onchange_assignee = {
161 let assignee = assignee.clone();
162
163 use_callback((), move |value: String, _| {
164 assignee.set(value);
165 })
166 };
167
168 let onchange_assigner = {
169 let assigner = assigner.clone();
170
171 use_callback((), move |value: String, _| {
172 assigner.set(value);
173 })
174 };
175
176 let onchange_target = {
177 let target = target.clone();
178
179 use_callback((), move |value: (bool, String), _| {
180 target.set(value);
181 })
182 };
183
184 let onchange_permissions = {
185 let permissions = permissions.clone();
186 use_callback((), move |list, _| {
187 permissions.set(list);
188 })
189 };
190
191 let onchange_prohibitions = {
192 let prohibitions = prohibitions.clone();
193 use_callback((), move |list, _| {
194 prohibitions.set(list);
195 })
196 };
197
198 let onchange_obligations = {
199 let obligations = obligations.clone();
200 use_callback((), move |list, _| {
201 obligations.set(list);
202 })
203 };
204
205 let (target_is_simple, target_value) = (*target).clone();
206
207 let disabled = false;
208
209 html!(
210 <Form {onsubmit}>
211 <FormGroup
212 label={"Identifier"}
213 required={true}
214 >
215 <TextInput
216 required={true}
217 value={(*identifier).to_string()}
218 onchange={onchange_identifier}
219 />
220 </FormGroup>
221
222 <FormGroup
223 label={"Kind"}
224 required={true}
225 >
226 <SimpleSelect<Options>
227 selected={*kind}
228 onselect={onselect_kind}
229 entries={vec![Options::Agreement, Options::Offer, Options::Set]}
230 />
231 </FormGroup>
232
233 <FormGroup
234 label={"Permissions"}
235 >
236 <ListOfRules
237 list={(*permissions).clone()}
238 onchange={onchange_permissions}
239 />
240 </FormGroup>
241
242 <FormGroup
243 label={"Prohibitions"}
244 >
245 <ListOfRules
246 list={(*prohibitions).clone()}
247 onchange={onchange_prohibitions}
248 />
249 </FormGroup>
250
251 <FormGroup
252 label={"Obligations"}
253 >
254 <ListOfRules
255 list={(*obligations).clone()}
256 onchange={onchange_obligations}
257 />
258 </FormGroup>
259
260 <FormGroup
261 label={"Assignee"}
262 >
263 <TextInput
264 value={(*assignee).clone()}
265 onchange={onchange_assignee}
266 />
267 </FormGroup>
268
269 <FormGroup
270 label={"Assigner"}
271 >
272 <TextInput
273 value={(*assigner).clone()}
274 onchange={onchange_assigner}
275 />
276 </FormGroup>
277
278 <FormGroup
279 label={"Target"}
280 >
281 <SimpleOrIdField onchange={onchange_target} is_simple={target_is_simple} value={target_value} />
282 </FormGroup>
283
284 <ActionGroup>
285 <Button
286 variant={ButtonVariant::Primary}
287 label="Submit"
288 r#type={ButtonType::Submit}
289 {disabled}
290 />
291 <Button variant={ButtonVariant::Secondary} label="Reset" r#type={ButtonType::Reset}/>
292 </ActionGroup>
293 </Form>
294 )
295}