edc_web_components/pages/
show_contract_negotiation.rs1use crate::components::ContractNegotiationStatus;
2use crate::contexts::use_edc_connector_context;
3#[cfg(feature = "contract-negotiation-review")]
4use edc_connector_client::types::contract_negotiation::{
5 ContractNegotiationKind, ContractNegotiationState,
6};
7use patternfly_yew::prelude::*;
8use yew::prelude::*;
9use yew::suspense::use_future_with;
10
11#[derive(Clone, Debug, PartialEq, Properties)]
12pub struct ShowContractNegotiationPageProps {
13 pub contract_negotiation_id: String,
14 #[prop_or_default]
15 pub on_contract_agreement_click: Callback<String>,
16}
17
18#[component]
19pub fn ShowContractNegotiationPage(props: &ShowContractNegotiationPageProps) -> Html {
20 html!(
21 <>
22 <Title level={Level::H2} size={Size::XXXLarge}>{ "Contract Negotiation" }</Title>
23 <Suspense fallback="Loading ...">
24 <ShowContractNegotiationPageInner
25 contract_negotiation_id={props.contract_negotiation_id.clone()}
26 on_contract_agreement_click={props.on_contract_agreement_click.clone()}
27 />
28 </Suspense>
29 </>
30 )
31}
32
33#[component]
34pub fn ShowContractNegotiationPageInner(props: &ShowContractNegotiationPageProps) -> HtmlResult {
35 let edc_connector_client = use_edc_connector_context();
36
37 let refresh = use_state(|| 0usize);
38
39 let contract_negotiation = use_future_with(
40 (
41 props.contract_negotiation_id.clone(),
42 edc_connector_client.clone(),
43 refresh.clone(),
44 ),
45 |properties| async move {
46 let (contract_negotiation_id, edc_connector_client, _) = (*properties).clone();
47
48 if let Some(client) = edc_connector_client.get_client() {
49 client
50 .contract_negotiations(edc_connector_client::EdcConnectorApiVersion::V4)
51 .get(&contract_negotiation_id)
52 .await
53 .ok()
54 } else {
55 None
56 }
57 },
58 )?;
59
60 let on_finalized = use_callback(refresh.setter(), |_, refresh_setter| {
61 refresh_setter.set(1);
62 });
63
64 #[cfg(feature = "contract-negotiation-review")]
65 let on_reviewed = use_callback(refresh.setter(), |_, refresh_setter| {
66 refresh_setter.set(1);
67 });
68
69 let contract_negotiation = (*contract_negotiation).clone();
70
71 if let Some(contract_negotiation) = contract_negotiation {
72 let contract_agreement =
73 if let Some(contract_agreement_id) = contract_negotiation.contract_agreement_id() {
74 let onclick = {
75 let contract_agreement_id = contract_agreement_id.clone();
76
77 props
78 .on_contract_agreement_click
79 .reform(move |_| contract_agreement_id.clone())
80 };
81
82 html!(
83 <DescriptionGroup term="Contract Agreement Id">
84 <Button variant={ButtonVariant::InlineLink} {onclick}>{ contract_agreement_id }</Button>
85 </DescriptionGroup>
86 )
87 } else {
88 html!()
89 };
90
91 let state =
92 Some(crate::models::ContractNegotiationState::from(contract_negotiation.state()).to_string())
93 .map(|value| {
94 let color = match value.as_str() {
95 "Finalized" => Color::Green,
96 "Terminated" => Color::Red,
97 _ => Color::Blue,
98 };
99
100 html!(
101 <DescriptionGroup term="State">
102 <Label label={value} {color} />
103 </DescriptionGroup>
104 )
105 });
106
107 let kind =
108 crate::models::ContractNegotiationKind::from(contract_negotiation.kind()).to_string();
109
110 #[cfg(feature = "contract-negotiation-review")]
111 let review = if contract_negotiation.state() == &ContractNegotiationState::Requested
112 && contract_negotiation.kind() == &ContractNegotiationKind::Provider
113 {
114 let contract_negotiation_id = contract_negotiation.id().to_string();
115
116 html!(
117 <Alert title="Review the Contract Negotiation">
118 <Suspense fallback={html!(<Bullseye><Spinner /></Bullseye>)}>
119 <crate::components::ReviewContractNegotiation {contract_negotiation_id} {on_reviewed} />
120 </Suspense>
121 </Alert>
122 )
123 } else {
124 html!()
125 };
126
127 #[cfg(not(feature = "contract-negotiation-review"))]
128 let review = html!();
129
130 Ok(html!(
131 <Stack gutter=true>
132 <StackItem>
133 <DescriptionList mode={[DescriptionListMode::Horizontal]}>
134 <DescriptionGroup term="Id">{ contract_negotiation.id() }</DescriptionGroup>
135 { state }
136 <DescriptionGroup term="Kind">{ kind }</DescriptionGroup>
137 { contract_agreement }
138 <DescriptionGroup term="Counter Party ID">
139 { contract_negotiation.counter_party_id().clone().unwrap_or_default() }
140 </DescriptionGroup>
141 </DescriptionList>
142 </StackItem>
143 <StackItem>
144 <ContractNegotiationStatus
145 contract_negotiation_id={props.contract_negotiation_id.clone()}
146 {on_finalized}
147 />
148 </StackItem>
149 <StackItem>{ review }</StackItem>
150 </Stack>
151 ))
152 } else {
153 Ok(html!(
154 format!(
155 "Contract Negotiation with id {} not found.",
156 props.contract_negotiation_id
157 )
158 ))
159 }
160}