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