Skip to main content

edc_web_components/pages/
show_asset_page.rs

1use crate::contexts::use_edc_connector_context;
2use crate::models::AssetItem;
3use edc_connector_client::EdcConnectorApiVersion;
4use patternfly_yew::prelude::*;
5use yew::platform::spawn_local;
6use yew::prelude::*;
7use yew::suspense::use_future_with;
8
9#[derive(Clone, Debug, PartialEq, Properties)]
10pub struct ShowAssetPageProps {
11  #[prop_or("Show Asset".to_string())]
12  pub title: String,
13  #[prop_or(None)]
14  pub tag_line: Option<String>,
15  pub asset_id: String,
16  pub on_deleted: Callback<()>,
17  pub dcterm_types: Vec<(String, String)>,
18}
19
20#[component]
21pub fn ShowAssetPage(props: &ShowAssetPageProps) -> Html {
22  let tag_line = props
23    .tag_line
24    .as_ref()
25    .map(|tag_line| html!(<p>{ tag_line }</p>))
26    .unwrap_or_default();
27
28  html!(
29    <>
30      <Title level={Level::H2} size={Size::XXXLarge}>{ &props.title }</Title>
31      { tag_line }
32      <Suspense fallback={html! {<Bullseye><Spinner /></Bullseye>}}>
33        <ShowAssetPageInner
34          asset_id={props.asset_id.clone()}
35          on_deleted={props.on_deleted.clone()}
36          dcterm_types={props.dcterm_types.clone()}
37        />
38      </Suspense>
39    </>
40  )
41}
42
43#[component]
44pub fn ShowAssetPageInner(props: &ShowAssetPageProps) -> HtmlResult {
45  let edc_connector_client = use_edc_connector_context();
46
47  let asset = use_future_with(
48    (props.asset_id.clone(), edc_connector_client.clone()),
49    |properties| async move {
50      let (asset_id, edc_connector_client) = (*properties).clone();
51
52      if let Some(client) = edc_connector_client.get_client() {
53        client
54          .assets(EdcConnectorApiVersion::V4)
55          .get(&asset_id)
56          .await
57          .ok()
58          .map(AssetItem::from)
59      } else {
60        None
61      }
62    },
63  )?;
64
65  let asset = (*asset).clone();
66
67  let edc_connector_context = use_edc_connector_context();
68
69  let ondelete = use_callback(
70    (
71      props.asset_id.clone(),
72      edc_connector_context,
73      props.on_deleted.clone(),
74    ),
75    |_, (asset_id, edc_connector_context, on_deleted)| {
76      let edc_connector_context = edc_connector_context.clone();
77      let asset_id = asset_id.clone();
78      let on_deleted = on_deleted.clone();
79
80      spawn_local(async move {
81        if let Some(client) = edc_connector_context.get_client()
82          && client
83            .assets(EdcConnectorApiVersion::V4)
84            .delete(&asset_id)
85            .await
86            .is_ok()
87        {
88          on_deleted.emit(());
89        }
90      });
91    },
92  );
93
94  if let Some(asset_item) = asset {
95    let keywords = asset_item
96      .keywords
97      .iter()
98      .map(|keyword| html! { <Label label={keyword.to_string()} color={Color::Blue} /> });
99
100    let dcterm_types = if !asset_item.dcterm_types.is_empty() {
101      let labels = asset_item
102        .dcterm_types
103        .iter()
104        .map(|dcterm_type| {
105          props
106            .dcterm_types
107            .iter()
108            .find(|(dcterm_type_name, _)| dcterm_type_name == dcterm_type)
109            .map(|(_, dcterm_type_label)| dcterm_type_label.to_string())
110            .unwrap_or(dcterm_type.to_string())
111        })
112        .map(|dcterm_type| {
113          html_nested!(
114            <FlexItem>
115              <Label label={dcterm_type} />
116            </FlexItem>
117          )
118        });
119
120      html!(
121        <DescriptionGroup term="Dataset Type(s)">
122          <Flex>{ for labels }</Flex>
123        </DescriptionGroup>
124      )
125    } else {
126      html!()
127    };
128
129    Ok(html!(
130      <>
131        <Card>
132          <CardBody>
133            <DescriptionList>
134              <DescriptionGroup term="ID">{ asset_item.id }</DescriptionGroup>
135            </DescriptionList>
136          </CardBody>
137        </Card>
138        <Card>
139          <CardHeader>
140            <Title level={Level::H2} size={Size::XXXLarge}>{ "Provider Information" }</Title>
141          </CardHeader>
142          <CardBody>
143            <DescriptionList>
144              <DescriptionGroup term="Company Name">
145                { asset_item.creator.clone().and_then(|creator| creator.name).unwrap_or_default() }
146              </DescriptionGroup>
147              <DescriptionGroup term="Company Logo URL">
148                { asset_item.creator.and_then(|creator| creator.thumbnail).and_then(|thumbnail| thumbnail.resource).unwrap_or_default() }
149              </DescriptionGroup>
150            </DescriptionList>
151          </CardBody>
152        </Card>
153        <Card>
154          <CardHeader>
155            <Title level={Level::H2} size={Size::XXXLarge}>{ "Dataset Description" }</Title>
156          </CardHeader>
157          <CardBody>
158            <DescriptionList>
159              <DescriptionGroup term="Title">{ asset_item.name }</DescriptionGroup>
160              <DescriptionGroup term="Version">
161                { asset_item.version.map(|version| version.to_string()).unwrap_or_default() }
162              </DescriptionGroup>
163              <DescriptionGroup term="Description">
164                { asset_item.description.unwrap_or_default() }
165              </DescriptionGroup>
166              <DescriptionGroup term="Keywords">{ for keywords }</DescriptionGroup>
167              <DescriptionGroup term="Landing Page">
168                { asset_item.landing_page.unwrap_or_default() }
169              </DescriptionGroup>
170              { dcterm_types }
171            </DescriptionList>
172          </CardBody>
173        </Card>
174        <Card>
175          <CardHeader>
176            <Title level={Level::H2} size={Size::XXXLarge}>{ "Dataset Source" }</Title>
177          </CardHeader>
178          <CardBody>
179            <Split gutter=true>
180              <SplitItem fill=true>
181                <DescriptionList>
182                  <DescriptionGroup term="Base URL">{ asset_item.base_url }</DescriptionGroup>
183                  <DescriptionGroup term="DataSource Type">
184                    { asset_item.datasource_type }
185                  </DescriptionGroup>
186                  <DescriptionGroup term="Proxy Path">
187                    <Switch disabled=true checked={asset_item.proxy_path} />
188                  </DescriptionGroup>
189                  <DescriptionGroup term="Proxy Query Parameters">
190                    <Switch disabled=true checked={asset_item.proxy_query_params} />
191                  </DescriptionGroup>
192                  <DescriptionGroup term="Proxy Method">
193                    <Switch disabled=true checked={asset_item.proxy_method} />
194                  </DescriptionGroup>
195                  <DescriptionGroup term="Proxy Body">
196                    <Switch disabled=true checked={asset_item.proxy_body} />
197                  </DescriptionGroup>
198                </DescriptionList>
199              </SplitItem>
200              <SplitItem fill=true>
201                <DescriptionList>
202                  <DescriptionGroup term="OpenID Client ID">
203                    { asset_item.oauth2_client_id }
204                  </DescriptionGroup>
205                  <DescriptionGroup term="OpenID Client Secret Key">
206                    { asset_item.oauth2_client_secret_key }
207                  </DescriptionGroup>
208                  <DescriptionGroup term="OpenID Token URL">
209                    { asset_item.oauth2_token_url }
210                  </DescriptionGroup>
211                  <DescriptionGroup term="OpenID Scopes">
212                    { asset_item.oauth2_scope }
213                  </DescriptionGroup>
214                </DescriptionList>
215              </SplitItem>
216            </Split>
217          </CardBody>
218        </Card>
219        <Flex>
220          <FlexItem modifiers={[FlexModifier::Grow.all()]} />
221          <FlexItem>
222            <Button variant={ButtonVariant::Danger} onclick={ondelete.clone()}>
223              { "Delete Asset" }
224            </Button>
225          </FlexItem>
226        </Flex>
227      </>
228    ))
229  } else {
230    Ok(html!(
231      format!(
232      "Asset with id {} not found.",
233      props.asset_id
234    )
235    ))
236  }
237}