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