edc_web_components/components/
list_policies.rs1use crate::models::PolicyDefinitionItem;
2use patternfly_yew::prelude::*;
3use std::rc::Rc;
4use yew::prelude::*;
5
6#[derive(Clone, Debug, PartialEq, Properties)]
7pub struct ListPoliciesProps {
8 pub policy_definition_items: Vec<PolicyDefinitionItem>,
9 pub offset: usize,
10 pub limit: usize,
11 pub onoffset: Callback<usize>,
12 pub onlimit: Callback<usize>,
13 pub ondelete: Callback<String>,
14 pub onshow: Callback<String>,
15}
16
17#[component]
18pub fn ListPolicies(props: &ListPoliciesProps) -> Html {
19 let header = html_nested! {
20 <TableHeader<Columns>>
21 <TableColumn<Columns> label="Name" index={Columns::Name} />
22 <TableColumn<Columns> label="Kind" index={Columns::Kind} />
23 <TableColumn<Columns> label="Assignee" index={Columns::Assignee} />
24 <TableColumn<Columns> label="Assigner" index={Columns::Assigner} />
25 <TableColumn<Columns> label="" index={Columns::Actions} />
26 </TableHeader<Columns>>
27 };
28
29 let total_entries: Option<usize> = None;
30
31 let nav_callback = use_callback(
32 (
33 props.offset,
34 props.limit,
35 total_entries,
36 props.onoffset.clone(),
37 ),
38 |page: Navigation, (offset, limit, total_entries, onoffset)| {
39 let offset = match page {
40 Navigation::First => 0,
41 Navigation::Last => (total_entries.unwrap_or_default().saturating_sub(1) / limit) * limit,
42 Navigation::Previous => *offset - limit,
43 Navigation::Next => *offset + limit,
44 Navigation::Page(n) => n * limit,
45 };
46 onoffset.emit(offset);
47 },
48 );
49
50 let rows = props
51 .policy_definition_items
52 .iter()
53 .map(|policy_definition_item| PolicyDefinitionItemRenderer {
54 policy_definition_item: policy_definition_item.clone(),
55 ondelete: props.ondelete.clone(),
56 onshow: props.onshow.clone(),
57 })
58 .collect();
59
60 let (entries, _) = use_table_data(MemoizedTableModel::new(Rc::new(rows)));
61
62 html!(
63 <>
64 <Toolbar>
65 <ToolbarContent>
66 <ToolbarItem r#type={ToolbarItemType::Pagination}>
67 <Pagination
68 offset={props.offset}
69 entries_per_page_choices={vec![5, 10, 25, 50, 100]}
70 selected_choice={props.limit}
71 onlimit={&props.onlimit}
72 onnavigation={&nav_callback}
73 />
74 </ToolbarItem>
75 </ToolbarContent>
76 </Toolbar>
77 <Table<Columns, UseTableData<Columns, MemoizedTableModel<PolicyDefinitionItemRenderer>>>
78 mode={TableMode::Compact}
79 {header}
80 {entries}
81 />
82 </>
83 )
84}
85
86#[derive(Clone, Debug, Eq, PartialEq)]
87enum Columns {
88 Name,
89 Kind,
90 Assignee,
91 Assigner,
92 Actions,
93}
94
95#[derive(Clone, Debug)]
96struct PolicyDefinitionItemRenderer {
97 policy_definition_item: PolicyDefinitionItem,
98 ondelete: Callback<String>,
99 onshow: Callback<String>,
100}
101
102impl TableEntryRenderer<Columns> for PolicyDefinitionItemRenderer {
103 fn render_cell(&self, context: CellContext<'_, Columns>) -> Cell {
104 match context.column {
105 Columns::Name => html! { self.policy_definition_item.name.to_string() },
106 Columns::Kind => html! { self.policy_definition_item.kind.to_string() },
107 Columns::Assignee => html!(
108 self
109 .policy_definition_item
110 .assignee
111 .clone()
112 .unwrap_or_default()
113 ),
114 Columns::Assigner => html!(
115 self
116 .policy_definition_item
117 .assigner
118 .clone()
119 .unwrap_or_default()
120 ),
121 Columns::Actions => {
122 let policy_id = self.policy_definition_item.id.to_string();
123 let ondelete = self.ondelete.clone();
124 let onshow = self.onshow.clone();
125
126 html!(
127 <Split gutter=true>
128 <SplitItem>
129 <ShowPolicy policy_id={policy_id.clone()} {onshow} />
130 </SplitItem>
131 <SplitItem>
132 <DeletePolicy {policy_id} {ondelete} />
133 </SplitItem>
134 </Split>
135 )
136 }
137 }
138 .into()
139 }
140}
141
142#[derive(Clone, PartialEq, Properties)]
143pub struct DeletePolicyProps {
144 pub policy_id: String,
145 pub ondelete: Callback<String>,
146}
147
148#[function_component]
149pub fn DeletePolicy(props: &DeletePolicyProps) -> Html {
150 let onclick = use_callback(
151 (props.ondelete.clone(), props.policy_id.clone()),
152 move |_, (ondelete, policy_id)| {
153 ondelete.emit(policy_id.clone());
154 },
155 );
156
157 html!(<Button variant={ButtonVariant::Danger} icon={Icon::Trash} {onclick}>{ "Delete" }</Button>)
158}
159
160#[derive(Clone, PartialEq, Properties)]
161pub struct ShowPolicyProps {
162 pub policy_id: String,
163 pub onshow: Callback<String>,
164}
165
166#[function_component]
167pub fn ShowPolicy(props: &ShowPolicyProps) -> Html {
168 let onclick = use_callback(
169 (props.onshow.clone(), props.policy_id.clone()),
170 move |_, (onshow, policy_id)| {
171 onshow.emit(policy_id.clone());
172 },
173 );
174
175 html!(<Button variant={ButtonVariant::Primary} icon={Icon::Eye} {onclick}>{ "Show" }</Button>)
176}