edc_web_ui/components/
list_transfer_processes.rs

1use crate::contexts::use_edc_connector_context;
2use edc_connector_client::types::query::Query;
3use edc_connector_client::types::transfer_process::{
4  TransferProcess, TransferProcessKind, TransferProcessState,
5};
6use patternfly_yew::prelude::*;
7use std::rc::Rc;
8use yew::prelude::*;
9use yew::suspense::use_future_with;
10
11#[function_component]
12pub fn ListTransferProcesses() -> Html {
13  let fallback = html!("Loading ...");
14
15  html!(
16    <Suspense {fallback}>
17      <ListTransferProcessesInner />
18    </Suspense>
19  )
20}
21
22#[function_component]
23pub fn ListTransferProcessesInner() -> HtmlResult {
24  let edc_connector_context = use_edc_connector_context();
25
26  let offset = use_state(|| 0usize);
27  let limit = use_state(|| 10usize);
28
29  let transfer_process_list = use_future_with(
30    (edc_connector_context, *limit, *offset),
31    |parameters| async move {
32      let (edc_connector_context, limit, offset) = &*parameters;
33
34      let query = Query::builder()
35        .limit(*limit as u32)
36        .offset(*offset as u32)
37        .build();
38
39      if let Some(client) = edc_connector_context.get_client() {
40        client.transfer_processes().query(query).await
41      } else {
42        Ok(vec![])
43      }
44    },
45  )?;
46
47  let transfer_process_list = &(*transfer_process_list);
48
49  let header = html_nested! {
50    <TableHeader<Columns>>
51      <TableColumn<Columns> label="ID" index={Columns::Id} />
52      <TableColumn<Columns> label="State" index={Columns::State} />
53      <TableColumn<Columns> label="Asset ID" index={Columns::AssetId} />
54      <TableColumn<Columns> label="Contract ID" index={Columns::ContractId} />
55      <TableColumn<Columns> label="Transfer Type" index={Columns::TransferType} />
56      <TableColumn<Columns> label="Kind" index={Columns::Kind} />
57    </TableHeader<Columns>>
58  };
59
60  let limit_callback = use_callback(limit.clone(), |number, limit| limit.set(number));
61
62  let total_entries: Option<usize> = None;
63
64  let nav_callback = use_callback(
65    (offset.clone(), *limit, total_entries),
66    |page: Navigation, (offset, limit, total_entries)| {
67      let o = match page {
68        Navigation::First => 0,
69        Navigation::Last => (total_entries.unwrap_or_default().saturating_sub(1) / limit) * limit,
70        Navigation::Previous => **offset - limit,
71        Navigation::Next => **offset + limit,
72        Navigation::Page(n) => n * limit,
73      };
74      offset.set(o);
75    },
76  );
77
78  let rows = transfer_process_list
79    .as_ref()
80    .unwrap()
81    .iter()
82    .map(|transfer_process| ListTransferProcessRenderer(transfer_process.clone()))
83    .collect();
84
85  let (entries, _) = use_table_data(MemoizedTableModel::new(Rc::new(rows)));
86
87  let table = html!(
88    <>
89      <Toolbar>
90        <ToolbarContent>
91          <ToolbarItem r#type={ToolbarItemType::Pagination}>
92            <Pagination
93              offset={*offset}
94              entries_per_page_choices={vec![5, 10, 25, 50, 100]}
95              selected_choice={*limit}
96              onlimit={&limit_callback}
97              onnavigation={&nav_callback}
98            />
99          </ToolbarItem>
100        </ToolbarContent>
101      </Toolbar>
102      <Table<Columns, UseTableData<Columns, MemoizedTableModel<ListTransferProcessRenderer>>>
103        mode={TableMode::Compact}
104        {header}
105        {entries}
106        />
107    </>
108  );
109
110  Ok(table)
111}
112
113#[derive(Clone, Debug, Eq, PartialEq)]
114enum Columns {
115  Id,
116  State,
117  AssetId,
118  ContractId,
119  TransferType,
120  Kind,
121}
122
123#[derive(Clone, Debug)]
124struct ListTransferProcessRenderer(TransferProcess);
125
126impl ListTransferProcessRenderer {}
127
128impl TableEntryRenderer<Columns> for ListTransferProcessRenderer {
129  fn render_cell(&self, context: CellContext<'_, Columns>) -> Cell {
130    let state = match self.0.state() {
131      TransferProcessState::Initial => "Initial".to_string(),
132      TransferProcessState::Provisioning => "Provisioning".to_string(),
133      TransferProcessState::ProvisioningRequested => "ProvisioningRequested".to_string(),
134      TransferProcessState::Provisioned => "Provisioned".to_string(),
135      TransferProcessState::Requesting => "Requesting".to_string(),
136      TransferProcessState::Requested => "Requested".to_string(),
137      TransferProcessState::Starting => "Starting".to_string(),
138      TransferProcessState::Started => "Started".to_string(),
139      TransferProcessState::Suspending => "Suspending".to_string(),
140      TransferProcessState::Suspended => "Suspended".to_string(),
141      TransferProcessState::Resuming => "Resuming".to_string(),
142      TransferProcessState::Resumed => "Resumed".to_string(),
143      TransferProcessState::Completing => "Completing".to_string(),
144      TransferProcessState::Completed => "Completed".to_string(),
145      TransferProcessState::Terminating => "Terminating".to_string(),
146      TransferProcessState::Terminated => "Terminated".to_string(),
147      TransferProcessState::Deprovisioning => "Deprovisioning".to_string(),
148      TransferProcessState::DeprovisioningRequested => "DeprovisioningRequested".to_string(),
149      TransferProcessState::Deprovisioned => "Deprovisioned".to_string(),
150      TransferProcessState::Other(other) => other.to_string(),
151    };
152
153    let kind = match self.0.kind() {
154      TransferProcessKind::Consumer => "Consumer",
155      TransferProcessKind::Provider => "Provider",
156    };
157
158    match context.column {
159      Columns::Id => html! {self.0.id().to_string()},
160      Columns::State => html!(state),
161      Columns::AssetId => html!(self.0.asset_id().to_string()),
162      Columns::ContractId => html! {self.0.contract_id().to_string()},
163      Columns::TransferType => html!(self.0.transfer_type().to_string()),
164      Columns::Kind => html!(kind),
165    }
166    .into()
167  }
168}