edc_web_components/components/
transfer_process_status.rs1use crate::contexts::use_edc_connector_context;
2use edc_connector_client::types::transfer_process::{TransferProcess, TransferProcessState};
3use patternfly_yew::prelude::*;
4use std::time::Duration;
5use yew::platform::spawn_local;
6use yew::platform::time::sleep;
7use yew::prelude::*;
8
9const HAPPY_PATH_STATES: [(&str, TransferProcessState); 5] = [
10 ("Initial", TransferProcessState::Initial),
11 ("Provisioned", TransferProcessState::Provisioned),
12 ("Requested", TransferProcessState::Requested),
13 ("Started", TransferProcessState::Started),
14 ("Completed", TransferProcessState::Completed),
15];
16
17#[derive(Clone, Debug, PartialEq, Properties)]
18pub struct TransferProcessStatusProps {
19 pub transfer_process_id: String,
20 #[prop_or_default]
21 pub on_started: Callback<()>,
22 #[prop_or_default]
23 pub on_finalized: Callback<()>,
24}
25
26#[component]
27pub fn TransferProcessStatus(props: &TransferProcessStatusProps) -> Html {
28 let edc_connector_client = use_edc_connector_context();
29
30 let transfer_process_state = use_state(|| None);
31 let transfer_process_error = use_state(|| Option::<String>::None);
32
33 use_effect_with(
34 (
35 props.transfer_process_id.clone(),
36 edc_connector_client.clone(),
37 transfer_process_state.setter(),
38 transfer_process_error.setter(),
39 props.on_finalized.clone(),
40 props.on_started.clone(),
41 ),
42 |(
43 transfer_process_id,
44 edc_connector_client,
45 transfer_process_state_setter,
46 transfer_process_error_setter,
47 on_finalized,
48 on_started,
49 )| {
50 let transfer_process_id = transfer_process_id.clone();
51 let edc_connector_client = edc_connector_client.clone();
52 let transfer_process_state_setter = transfer_process_state_setter.clone();
53 let transfer_process_error_setter = transfer_process_error_setter.clone();
54 let on_finalized = on_finalized.clone();
55 let on_started = on_started.clone();
56
57 spawn_local(async move {
58 loop {
59 let transfer_process = if let Some(client) = edc_connector_client.get_client() {
60 client
61 .transfer_processes(edc_connector_client::EdcConnectorApiVersion::V4)
62 .get(&transfer_process_id)
63 .await
64 .ok()
65 } else {
66 None
67 };
68
69 let state = transfer_process
70 .as_ref()
71 .map(|transfer_process| transfer_process.state().clone());
72
73 let error_message = transfer_process.as_ref().and_then(|transfer_process| {
74 transfer_process
75 .error_detail()
76 .map(|error_detail| error_detail.to_string())
77 });
78
79 transfer_process_error_setter.set(error_message);
80
81 transfer_process_state_setter.set(transfer_process);
82
83 if state == Some(TransferProcessState::Started) {
84 on_started.emit(());
85 break;
86 }
87
88 if state == Some(TransferProcessState::Completed)
89 || state == Some(TransferProcessState::Terminated)
90 {
91 on_finalized.emit(());
92 break;
93 }
94
95 sleep(Duration::from_secs(1)).await;
96 }
97 });
98 },
99 );
100
101 match (
102 (*transfer_process_error).clone(),
103 (*transfer_process_state).clone(),
104 ) {
105 (Some(error_message), _) => html!(
106 <Alert title="Transfer Process failed" r#type={AlertType::Danger}>
107 <div>{ error_message }</div>
108 </Alert>
109 ),
110 (None, Some(transfer_process)) => {
111 let transfer_process: TransferProcess = transfer_process;
112
113 let current_state_index = HAPPY_PATH_STATES
114 .iter()
115 .position(|(_, state)| state == transfer_process.state())
116 .unwrap_or_default();
117
118 let steps = HAPPY_PATH_STATES
119 .iter()
120 .enumerate()
121 .map(|(index, (state_label, _))| {
122 let status = if index < current_state_index {
123 ProgressStepperStepStatus::Success
124 } else if index == current_state_index {
125 if index == HAPPY_PATH_STATES.len() - 1 {
126 ProgressStepperStepStatus::Success
127 } else {
128 ProgressStepperStepStatus::Default
129 }
130 } else {
131 ProgressStepperStepStatus::Pending
132 };
133
134 html_nested!(
135 <ProgressStepperStep {status}>
136 <div>{ state_label.to_string() }</div>
137 </ProgressStepperStep>
138 )
139 });
140
141 html!(<ProgressStepper>{ for steps }</ProgressStepper>)
142 }
143 _ => html!(),
144 }
145}