Skip to main content

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