edc_web_components/pages/
show_asset_page.rs1use 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}