Skip to main content

edc_web_ui/components/
list_contract_definitions.rs

1use 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}