Skip to main content

edc_web_components/components/
asset_reference.rs

1use crate::components::DatasetCard;
2use crate::contexts::{
3  RedirectionAction, use_edc_connector_context, use_edc_federated_catalog_assets_context,
4  use_redirection_context,
5};
6use crate::models::{AssetItem, DataspaceDataset};
7use edc_connector_client::EdcConnectorApiVersion;
8use patternfly_yew::prelude::*;
9use yew::prelude::*;
10use yew::suspense::use_future_with;
11
12#[derive(Clone, Debug, PartialEq, Properties)]
13pub struct AssetReferenceProps {
14  pub asset_id: String,
15}
16
17#[component]
18pub fn AssetReference(props: &AssetReferenceProps) -> Html {
19  html! {
20    <Suspense fallback={html! {<Bullseye><Spinner size={SpinnerSize::Sm} /></Bullseye>}}>
21      <AssetReferenceInner asset_id={props.asset_id.clone()} />
22    </Suspense>
23  }
24}
25
26#[component]
27pub fn AssetReferenceInner(props: &AssetReferenceProps) -> HtmlResult {
28  let edc_connector_context = use_edc_connector_context();
29  let backdropper = use_backdrop();
30  let edc_federated_catalog_assets_context = use_edc_federated_catalog_assets_context();
31  let redirection_context = use_redirection_context();
32
33  let asset = use_future_with(
34    (
35      props.asset_id.clone(),
36      edc_federated_catalog_assets_context.clone(),
37      edc_connector_context.clone(),
38    ),
39    async move |parameters| {
40      let (asset_id, edc_federated_catalog_assets_context, edc_connector_context) =
41        (*parameters).clone();
42
43      if let Some(edc_federated_catalog_assets_context) = edc_federated_catalog_assets_context
44        && let Some(asset_item) = edc_federated_catalog_assets_context.asset(&asset_id)
45      {
46        Some(asset_item.clone())
47      } else {
48        if let Some(edc_connector_client) = edc_connector_context.get_client() {
49          edc_connector_client
50            .assets(EdcConnectorApiVersion::V4)
51            .get(&asset_id)
52            .await
53            .ok()
54            .map(AssetItem::from)
55        } else {
56          None
57        }
58      }
59    },
60  )?;
61
62  let asset = (*asset).clone();
63
64  let label = if let Some(asset) = &asset {
65    asset.name.clone()
66  } else {
67    props.asset_id.clone()
68  };
69
70  let onclick = use_callback(
71    (
72      backdropper.clone(),
73      redirection_context.clone(),
74      asset.clone(),
75      props.asset_id.clone(),
76    ),
77    |_, (backdropper, redirection_context, asset, asset_id)| {
78      let asset_id = asset_id.clone();
79
80      if let Some(backdropper) = backdropper
81        && let Some(asset) = asset
82      {
83        let dataspace_dataset = DataspaceDataset::from(asset.clone());
84
85        let button = if let Some(redirection_context) = redirection_context {
86          let backdropper = backdropper.clone();
87
88          html!(
89            <Button
90              variant={ButtonVariant::Primary}
91              icon={Icon::Eye}
92              onclick={redirection_context.redirect_to().reform(move |_| {
93            backdropper.close();
94            RedirectionAction::Asset(asset_id.clone())
95          })}
96            >
97              { "Show" }
98            </Button>
99          )
100        } else {
101          html!()
102        };
103
104        backdropper.open(Backdrop::new(html!(
105          <Bullseye>
106            <Modal title="Asset" variant={ModalVariant::Small}>
107              <Bullseye>
108                <Stack gutter=true>
109                  <StackItem>
110                    <DatasetCard dataset={dataspace_dataset} />
111                  </StackItem>
112                  <StackItem>{ button }</StackItem>
113                </Stack>
114              </Bullseye>
115            </Modal>
116          </Bullseye>
117        )));
118      } else {
119        if let Some(redirection_context) = redirection_context {
120          redirection_context
121            .redirect_to()
122            .emit(RedirectionAction::Asset(asset_id));
123        }
124      }
125    },
126  );
127
128  let variant = if backdropper.is_some() || redirection_context.is_some() {
129    ButtonVariant::InlineLink
130  } else {
131    ButtonVariant::Plain
132  };
133
134  Ok(html!(<Button {variant} {onclick}>{ label }</Button>))
135}