Skip to main content

edc_web_components/pages/
show_contract_negotiation.rs

1use 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}