Skip to main content

edc_web_components/components/
list_contract_negotiations.rs

1use crate::models::ContractNegotiationItem;
2use patternfly_yew::prelude::*;
3use std::rc::Rc;
4use yew::prelude::*;
5
6#[derive(Clone, Debug, PartialEq, Properties)]
7pub struct ListContractNegotiationsProps {
8  pub contract_negotiation_items: Vec<ContractNegotiationItem>,
9  pub offset: usize,
10  pub limit: usize,
11  pub onoffset: Callback<usize>,
12  pub onlimit: Callback<usize>,
13  pub on_show_contract_negotiation: Callback<String>,
14}
15
16#[component]
17pub fn ListContractNegotiations(props: &ListContractNegotiationsProps) -> Html {
18  let header = html_nested! {
19    <TableHeader<Columns>>
20      <TableColumn<Columns> label="State" index={Columns::State} />
21      <TableColumn<Columns> label="Contract Agreement ID" index={Columns::ContractAgreementId} />
22      <TableColumn<Columns> label="Counter Party ID" index={Columns::CounterPartyId} />
23      <TableColumn<Columns> label="Protocol" index={Columns::Protocol} />
24      <TableColumn<Columns> label="Kind" index={Columns::Kind} />
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    .contract_negotiation_items
52    .iter()
53    .map(
54      |contract_negotiation_item| ContractNegotiationItemRenderer {
55        item: contract_negotiation_item.clone(),
56        on_show_contract_negotiation: props.on_show_contract_negotiation.clone(),
57      },
58    )
59    .collect();
60
61  let (entries, _) = use_table_data(MemoizedTableModel::new(Rc::new(rows)));
62
63  html!(
64    <>
65      <Toolbar>
66        <ToolbarContent>
67          <ToolbarItem r#type={ToolbarItemType::Pagination}>
68            <Pagination
69              offset={props.offset}
70              entries_per_page_choices={vec![5, 10, 25, 50, 100]}
71              selected_choice={props.limit}
72              onlimit={&props.onlimit}
73              onnavigation={&nav_callback}
74            />
75          </ToolbarItem>
76        </ToolbarContent>
77      </Toolbar>
78      <Table<Columns, UseTableData<Columns, MemoizedTableModel<ContractNegotiationItemRenderer>>>
79        mode={TableMode::Compact}
80        {header}
81        {entries}
82      />
83    </>
84  )
85}
86
87#[derive(Clone, Debug, Eq, PartialEq)]
88enum Columns {
89  State,
90  ContractAgreementId,
91  CounterPartyId,
92  Protocol,
93  Kind,
94  Actions,
95}
96
97#[derive(Clone, Debug)]
98struct ContractNegotiationItemRenderer {
99  item: ContractNegotiationItem,
100  on_show_contract_negotiation: Callback<String>,
101}
102
103impl TableEntryRenderer<Columns> for ContractNegotiationItemRenderer {
104  fn render_cell(&self, context: CellContext<'_, Columns>) -> Cell {
105    match context.column {
106      Columns::State => html! { <Label label={self.item.state.to_string()} color={Color::Blue} /> },
107      Columns::ContractAgreementId => html! { self.item.contract_agreement_id.to_string() },
108      Columns::CounterPartyId => html! { self.item.counter_party_id.to_string() },
109      Columns::Protocol => html! { self.item.protocol.to_string() },
110      Columns::Kind => html! { self.item.kind.to_string() },
111      Columns::Actions => {
112        let contract_negotiation_id = self.item.id.clone();
113        html! {
114          <Button
115            variant={ButtonVariant::Primary}
116            onclick={self.on_show_contract_negotiation.clone().reform(move |_| contract_negotiation_id.clone())}
117            icon={Icon::Eye}
118          >
119            { "Show" }
120          </Button>
121        }
122      },
123    }
124    .into()
125  }
126}