edc_web_ui/components/
list_contract_definitions.rs1use crate::models::ContractDefinitionItem;
2use patternfly_yew::prelude::*;
3use std::rc::Rc;
4use yew::prelude::*;
5
6#[derive(Clone, Debug, PartialEq, Properties)]
7pub struct ListContractDefinitionsProps {
8 pub contract_definition_items: Vec<ContractDefinitionItem>,
9 pub offset: usize,
10 pub limit: usize,
11 pub onoffset: Callback<usize>,
12 pub onlimit: Callback<usize>,
13 pub ondelete: Callback<String>,
14}
15
16#[component]
17pub fn ListContractDefinitions(props: &ListContractDefinitionsProps) -> Html {
18 let header = html_nested! {
19 <TableHeader<Columns>>
20 <TableColumn<Columns> label="ID" index={Columns::Id} />
21 <TableColumn<Columns> label="Access Policy ID" index={Columns::AccessPolicyId} />
22 <TableColumn<Columns> label="Contract Policy ID" index={Columns::ContractPolicyId} />
23 <TableColumn<Columns> label="" index={Columns::Actions} />
24 </TableHeader<Columns>>
25 };
26
27 let total_entries: Option<usize> = None;
28
29 let nav_callback = use_callback(
30 (
31 props.offset,
32 props.limit,
33 total_entries,
34 props.onoffset.clone(),
35 ),
36 |page: Navigation, (offset, limit, total_entries, onoffset)| {
37 let offset = match page {
38 Navigation::First => 0,
39 Navigation::Last => (total_entries.unwrap_or_default().saturating_sub(1) / limit) * limit,
40 Navigation::Previous => *offset - limit,
41 Navigation::Next => *offset + limit,
42 Navigation::Page(n) => n * limit,
43 };
44 onoffset.emit(offset);
45 },
46 );
47
48 let rows = props
49 .contract_definition_items
50 .iter()
51 .map(|contract_definition_item| ContractDefinitionItemRenderer {
52 contract_definition_item: contract_definition_item.clone(),
53 ondelete: props.ondelete.clone(),
54 })
55 .collect();
56
57 let (entries, _) = use_table_data(MemoizedTableModel::new(Rc::new(rows)));
58
59 html!(
60 <>
61 <Toolbar>
62 <ToolbarContent>
63 <ToolbarItem r#type={ToolbarItemType::Pagination}>
64 <Pagination
65 offset={props.offset}
66 entries_per_page_choices={vec![5, 10, 25, 50, 100]}
67 selected_choice={props.limit}
68 onlimit={&props.onlimit}
69 onnavigation={&nav_callback}
70 />
71 </ToolbarItem>
72 </ToolbarContent>
73 </Toolbar>
74 <Table<Columns, UseTableData<Columns, MemoizedTableModel<ContractDefinitionItemRenderer>>>
75 mode={TableMode::Compact}
76 {header}
77 {entries}
78 />
79 </>
80 )
81}
82
83#[derive(Clone, Debug, Eq, PartialEq)]
84enum Columns {
85 Id,
86 AccessPolicyId,
87 ContractPolicyId,
88 Actions,
89}
90
91#[derive(Clone, Debug)]
92struct ContractDefinitionItemRenderer {
93 contract_definition_item: ContractDefinitionItem,
94 ondelete: Callback<String>,
95}
96
97impl ContractDefinitionItemRenderer {}
98
99impl TableEntryRenderer<Columns> for ContractDefinitionItemRenderer {
100 fn render_cell(&self, context: CellContext<'_, Columns>) -> Cell {
101 match context.column {
102 Columns::Id => html! { self.contract_definition_item.id.to_string() },
103 Columns::AccessPolicyId => html!(self.contract_definition_item.access_policy_id.to_string()),
104 Columns::ContractPolicyId => html!(
105 self.contract_definition_item.contract_policy_id.to_string()
106 ),
107 Columns::Actions => {
108 let contract_definition_id = self.contract_definition_item.id.to_string();
109
110 html!(<DeleteContractDefinition {contract_definition_id} ondelete={self.ondelete.clone()} />)
111 }
112 }
113 .into()
114 }
115}
116
117#[derive(Clone, PartialEq, Properties)]
118pub struct Props {
119 pub contract_definition_id: String,
120 pub ondelete: Callback<String>,
121}
122
123#[function_component]
124pub fn DeleteContractDefinition(props: &Props) -> Html {
125 let onclick = use_callback(
126 (props.ondelete.clone(), props.contract_definition_id.clone()),
127 move |_, (ondelete, contract_definition_id)| {
128 ondelete.emit(contract_definition_id.to_string());
129 },
130 );
131
132 html!(<Button variant={ButtonVariant::Danger} icon={Icon::Trash} {onclick}>{ "Delete" }</Button>)
133}