@startinblox/components-ds4go 3.3.8 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/locales/en.xlf CHANGED
@@ -245,9 +245,6 @@
245
245
  <trans-unit id="s628bb01dd2b078ad">
246
246
  <source>No policy template provided</source>
247
247
  </trans-unit>
248
- <trans-unit id="sa37b24eee1d1bc2b">
249
- <source>Policy Composer</source>
250
- </trans-unit>
251
248
  <trans-unit id="s23cd949fc2aa86a8">
252
249
  <source>Policy Definition</source>
253
250
  </trans-unit>
@@ -278,6 +275,135 @@
278
275
  <trans-unit id="sef1b3d1d31326b46">
279
276
  <source>No category</source>
280
277
  </trans-unit>
278
+ <trans-unit id="s971c62c3e06f9d82">
279
+ <source><x id="0" equiv-text="${previewLinks.length}"/> previews</source>
280
+ </trans-unit>
281
+ <trans-unit id="sf530358a9bd19cee">
282
+ <source>Agreement ID:</source>
283
+ </trans-unit>
284
+ <trans-unit id="sb4425c5c4fac54b5">
285
+ <source>Endpoint URL:</source>
286
+ </trans-unit>
287
+ <trans-unit id="s2848302a2185c3c0">
288
+ <source>Agreed on:</source>
289
+ </trans-unit>
290
+ <trans-unit id="s00500cd82b70b565">
291
+ <source>Note:</source>
292
+ </trans-unit>
293
+ <trans-unit id="sf37d51d16fb8905b">
294
+ <source>You can now use this agreement ID to access the service through the provider's API or data gateway.</source>
295
+ </trans-unit>
296
+ <trans-unit id="s0d0e208e36652416">
297
+ <source>Renegotiate contract</source>
298
+ </trans-unit>
299
+ <trans-unit id="s49bca1b76261f3ff">
300
+ <source>Activate this service</source>
301
+ </trans-unit>
302
+ <trans-unit id="sb332ee61b882e577">
303
+ <source>Negotiate access</source>
304
+ </trans-unit>
305
+ <trans-unit id="s500790e7856278ea">
306
+ <source>Negotiating...</source>
307
+ </trans-unit>
308
+ <trans-unit id="s78636b92c1a3909c">
309
+ <source>Pending</source>
310
+ </trans-unit>
311
+ <trans-unit id="s745c3700113d0690">
312
+ <source>Access Granted</source>
313
+ </trans-unit>
314
+ <trans-unit id="sbf9c5c5a8e5efad4">
315
+ <source>Failed</source>
316
+ </trans-unit>
317
+ <trans-unit id="s5787e20cab57b383">
318
+ <source>Unknown error</source>
319
+ </trans-unit>
320
+ <trans-unit id="s95b064f1a3d622cb">
321
+ <source>Access Policies</source>
322
+ </trans-unit>
323
+ <trans-unit id="sdf84f71cdbae4127">
324
+ <source>Multiple contract policies available for this asset</source>
325
+ </trans-unit>
326
+ <trans-unit id="sb932583a436a894b">
327
+ <source>Access Policy</source>
328
+ </trans-unit>
329
+ <trans-unit id="s4a41dc01589d8c48">
330
+ <source>Select a Policy</source>
331
+ </trans-unit>
332
+ <trans-unit id="s169eedc6d5d9d506">
333
+ <source>Multiple policies are available for this dataset. Please select one to proceed with the negotiation.</source>
334
+ </trans-unit>
335
+ <trans-unit id="s2ceb11be2290bb1b">
336
+ <source>Cancel</source>
337
+ </trans-unit>
338
+ <trans-unit id="sc7331901134c794b">
339
+ <source>This will delete the current contract and start a fresh negotiation. Continue?</source>
340
+ </trans-unit>
341
+ <trans-unit id="s070a952dbfc8cc6d">
342
+ <source>Duties</source>
343
+ </trans-unit>
344
+ <trans-unit id="sdf761eb7ad16410b">
345
+ <source>Remove Duty</source>
346
+ </trans-unit>
347
+ <trans-unit id="s1718e3c349bc1d30">
348
+ <source>Add Duty</source>
349
+ </trans-unit>
350
+ <trans-unit id="s9ffd7cfd1c88fd4e">
351
+ <source>Custom <x id="0" equiv-text="${this.template.name}"/> policy</source>
352
+ </trans-unit>
353
+ <trans-unit id="s2bed402279cceb12">
354
+ <source>Cancel policy customization</source>
355
+ </trans-unit>
356
+ <trans-unit id="sb59dc090f2be3796">
357
+ <source>Reset to <x id="0" equiv-text="${this.template.name}"/> default</source>
358
+ </trans-unit>
359
+ <trans-unit id="sddd8862fc1bdf610">
360
+ <source>Customize access policy</source>
361
+ </trans-unit>
362
+ <trans-unit id="s9e1971000a6a2270">
363
+ <source>Customize contract policy</source>
364
+ </trans-unit>
365
+ <trans-unit id="s0865e5a38e856821">
366
+ <source>No policy details available</source>
367
+ </trans-unit>
368
+ <trans-unit id="s70a26f677dc46e06">
369
+ <source>Policy ID:</source>
370
+ </trans-unit>
371
+ <trans-unit id="s7b3a70561cec8d75">
372
+ <source>Type:</source>
373
+ </trans-unit>
374
+ <trans-unit id="s15923994727a0adb">
375
+ <source>Permissions:</source>
376
+ </trans-unit>
377
+ <trans-unit id="s0772542b009a8be9">
378
+ <source>Action: <x id="0" equiv-text="${perm[&quot;odrl:action&quot;]?.[&quot;@id&quot;] || perm[&quot;odrl:action&quot;] || msg(&quot;use&quot;)}"/></source>
379
+ </trans-unit>
380
+ <trans-unit id="s4c52b0193dcce634">
381
+ <source>use</source>
382
+ </trans-unit>
383
+ <trans-unit id="s723a09cb247483aa">
384
+ <source>Constraint: <x id="0" equiv-text="${c[&quot;odrl:leftOperand&quot;]} ${c[&quot;odrl:operator&quot;]} ${c[&quot;odrl:rightOperand&quot;]}"/></source>
385
+ </trans-unit>
386
+ <trans-unit id="s0885bc9622c48b61">
387
+ <source>Prohibitions:</source>
388
+ </trans-unit>
389
+ <trans-unit id="s498865c7bd1f3959">
390
+ <source>unknown</source>
391
+ </trans-unit>
392
+ <trans-unit id="sbde02617664d091c">
393
+ <source>Obligations:</source>
394
+ </trans-unit>
395
+ <trans-unit id="s5ea7f731936859c6">
396
+ <source>Target Asset:</source>
397
+ </trans-unit>
398
+ <trans-unit id="s3fca726cbe9998b3">
399
+ <source>Assigner:</source>
400
+ </trans-unit>
401
+ <trans-unit id="se6f9192c93e67e2f">
402
+ <source>No redistribution, no commercial use</source>
403
+ </trans-unit>
404
+ <trans-unit id="sc01b3f089359860d">
405
+ <source>Premium tier (40 calls/month)</source>
406
+ </trans-unit>
281
407
  </body>
282
408
  </file>
283
409
  </xliff>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startinblox/components-ds4go",
3
- "version": "3.3.8",
3
+ "version": "4.0.0",
4
4
  "description": "Startin'blox DS4GO",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -69,7 +69,7 @@
69
69
  "@inquirer/prompts": "^8.3.0",
70
70
  "@lit/localize": "^0.12.2",
71
71
  "@lit/task": "^1.0.3",
72
- "@startinblox/solid-tems-shared": "^2.1.0",
72
+ "@startinblox/solid-tems-shared": "^2.1.1",
73
73
  "autoprefixer": "^10.4.27",
74
74
  "cssnano": "^7.1.3",
75
75
  "lit": "^3.3.2",
@@ -1,25 +1,8 @@
1
1
  import Ds4goCardCatalogStyle from "@styles/cards/ds4go-card-dataspace-catalog.scss?inline";
2
+ import type { DSPOffer } from "@src/ds4go";
2
3
  import { css, html, LitElement, nothing, unsafeCSS } from "lit";
3
4
  import { customElement, property } from "lit/decorators.js";
4
- import { classMap } from "lit/directives/class-map.js";
5
- import { ifDefined } from "lit/directives/if-defined.js";
6
-
7
- export type Ds4goCardCatalogProps = {
8
- cardType?: string;
9
- isFullSize: boolean;
10
- logoOnTop: boolean;
11
-
12
- backgroundImg?: string;
13
- orgLogo?: string;
14
- address?: string;
15
- language?: string;
16
- date?: string;
17
- source?: string;
18
- header?: string;
19
- content?: string;
20
- badge?: string;
21
- tags: string[] | { name: string; type?: string }[];
22
- };
5
+ import { msg, str } from "@lit/localize";
23
6
 
24
7
  @customElement("ds4go-card-dataspace-catalog")
25
8
  export class Ds4goCardCatalog extends LitElement {
@@ -27,230 +10,102 @@ export class Ds4goCardCatalog extends LitElement {
27
10
  ${unsafeCSS(Ds4goCardCatalogStyle)};
28
11
  `;
29
12
 
30
- @property({ attribute: "type", type: String, reflect: true })
31
- cardType: Ds4goCardCatalogProps["cardType"] = "vertical";
32
-
33
- @property({ attribute: "address", type: String })
34
- address: Ds4goCardCatalogProps["address"];
35
-
36
- @property({ attribute: "language", type: String })
37
- language: Ds4goCardCatalogProps["language"];
38
-
39
- @property({ attribute: "date", type: String })
40
- date: Ds4goCardCatalogProps["date"];
41
-
42
- @property({ attribute: "source", type: String })
43
- source: Ds4goCardCatalogProps["source"];
44
-
45
- @property({ attribute: "background-img", type: String })
46
- backgroundImg: Ds4goCardCatalogProps["backgroundImg"];
47
-
48
- @property({ attribute: "org-logo", type: String })
49
- orgLogo: Ds4goCardCatalogProps["orgLogo"];
50
-
51
- @property({ attribute: "display-logo", type: Boolean })
52
- logoOnTop: Ds4goCardCatalogProps["logoOnTop"] = false;
53
-
54
- @property({ attribute: "full-size", type: Boolean })
55
- isFullSize: Ds4goCardCatalogProps["isFullSize"] = false;
56
-
57
- @property({ attribute: "header", type: String })
58
- header: Ds4goCardCatalogProps["header"];
59
-
60
- @property({ attribute: "content", type: String })
61
- content: Ds4goCardCatalogProps["content"];
62
-
63
- @property({ attribute: "badge", type: String })
64
- badge: Ds4goCardCatalogProps["badge"];
65
-
66
13
  @property({ attribute: false })
67
- tags: Ds4goCardCatalogProps["tags"] = [];
14
+ object?: DSPOffer;
68
15
 
69
- private _getType() {
70
- const allowedTypes = ["vertical", "horizontal", "bill-image"];
71
- if (!allowedTypes.includes(String(this.cardType))) {
72
- this.cardType = "vertical";
73
- }
74
- return {
75
- vertical: this.cardType === "vertical",
76
- horizontal: this.cardType === "horizontal",
77
- billImage: this.cardType === "bill-image",
78
- };
16
+ private _getThumbnail(): string {
17
+ // Missing foaf:thumbnail outside of DSIF
18
+ return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='354' height='167' viewBox='0 0 354 167'%3E%3Crect width='354' height='167' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='sans-serif' font-size='14' fill='%23999'%3ENo Thumbnail%3C/text%3E%3C/svg%3E";
79
19
  }
80
20
 
81
- private renderImageHeader() {
82
- if (this.isFullSize && (this.backgroundImg || this.badge)) {
83
- if (this.backgroundImg) {
84
- return html`<header
85
- class="image"
86
- style="background-image: url(${this.backgroundImg})"
87
- >
88
- ${
89
- this.badge
90
- ? html`<tems-badge label=${this.badge}></tems-badge>`
91
- : nothing
92
- }
93
- </header>`;
94
- }
95
- return html`<header>
96
- ${
97
- this.badge
98
- ? html`<tems-badge label=${this.badge}></tems-badge>`
99
- : nothing
100
- }
101
- </header>`;
21
+ private _getTags() {
22
+ const tags: {
23
+ label: string;
24
+ type: string;
25
+ color?: string;
26
+ }[] = [];
27
+
28
+ if (this.object?._provider?.name) {
29
+ tags.push({
30
+ label: this.object._provider.name,
31
+ type: "information",
32
+ });
102
33
  }
103
- return nothing;
104
- }
105
34
 
106
- private renderLogo() {
107
- if (this.logoOnTop && this.orgLogo) {
108
- return html`<div
109
- class="orgLogo"
110
- style="background-image: url(${this.orgLogo})"
111
- ></div>`;
35
+ if (this.object?.category) {
36
+ tags.push({ label: this.object.category, type: "neutral" });
112
37
  }
113
- return nothing;
114
- }
115
38
 
116
- private renderTags() {
117
- if (!this.tags || this.tags.length === 0) return nothing;
118
-
119
- return html`<div class="tags">
120
- ${this.tags
121
- .filter((t) => typeof t === "string" || t.name)
122
- .map(
123
- (tag: string | { name: string; type?: string; color?: string }) =>
124
- html`<tems-badge
125
- size="sm"
126
- label=${typeof tag === "string" ? tag : tag.name}
127
- type=${typeof tag !== "string" && ifDefined(tag.type)}
128
- color=${typeof tag !== "string" && ifDefined(tag.color)}
129
- ></tems-badge>`,
130
- )}
131
- </div>`;
132
- }
133
-
134
- private renderContent() {
135
- if (this.header || this.content) {
136
- return html`<div class="content">
137
- ${
138
- this.header
139
- ? html`<div class="card-header">
140
- <tems-division label=${this.header} type="h4"></tems-division>
141
- </div>`
142
- : nothing
143
- }
144
- ${
145
- this.content
146
- ? html`<div class="card-content">
147
- <tems-division
148
- label=${this.content}
149
- type="body-m"
150
- ></tems-division>
151
- </div>`
152
- : nothing
153
- }
154
- </div>`;
39
+ const previewLinks = (this.object?.previewLinks || "").split(" ");
40
+ if (previewLinks.length > 0) {
41
+ tags.push({
42
+ label: msg(str`${previewLinks.length} previews`),
43
+ type: "information",
44
+ });
155
45
  }
156
- return nothing;
157
- }
158
46
 
159
- private renderLangDate() {
160
- if (!this.date && !this.language) return nothing;
47
+ // if (this.object?.contenttype) {
48
+ // tags.push({ label: this.object.contenttype, type: "default" });
49
+ // }
161
50
 
162
- const date = this.date ? html`<span>${this.date}</span>` : nothing;
163
- const language = this.language
164
- ? html`<span>${this.language}</span>`
165
- : nothing;
166
-
167
- return html`<div class="lang-date">
168
- ${
169
- this.cardType === "bill-image"
170
- ? html`${language}${date}`
171
- : html`${date}${language}`
172
- }
173
- </div>`;
174
- }
175
-
176
- private renderSource() {
177
- if (!this.source) return nothing;
178
-
179
- return html`<div class="source-logo">
180
- <div class="source">
181
- <icon-material-symbols-rss-feed-rounded></icon-material-symbols-rss-feed-rounded>
182
- ${this.source}
183
- </div>
184
- ${
185
- this.orgLogo && !this.logoOnTop
186
- ? html`<div
187
- class="logo"
188
- style="background-image: url(${this.orgLogo})"
189
- ></div>`
190
- : nothing
191
- }
192
- </div>`;
193
- }
194
-
195
- private renderAddressAndSource() {
196
- if (!this.address && !this.source) return nothing;
197
-
198
- if (this.cardType === "vertical" || this.cardType === "bill-image") {
199
- if (!this.address) return nothing;
200
- return html`<div class="address">
201
- <icon-ic-outline-place></icon-ic-outline-place> ${this.address}
202
- </div>`;
203
- }
204
-
205
- return html`<div class="address-line">
206
- <div>
207
- ${
208
- this.address
209
- ? html`<div class="address">
210
- <icon-ic-outline-place></icon-ic-outline-place> ${this.address}
211
- </div>`
212
- : nothing
213
- }
214
- ${this.renderSource()}
215
- </div>
216
- ${this.renderLangDate()}
217
- </div>`;
51
+ return tags;
218
52
  }
219
53
 
220
54
  render() {
221
- const classes = {
222
- ...this._getType(),
223
- };
224
-
225
- if (this.cardType === "horizontal") {
226
- return html`<article class=${classMap(classes)}>
227
- ${this.renderImageHeader()}
228
- <main>
229
- ${this.renderLogo()} ${this.renderTags()} ${this.renderContent()}
230
- ${this.renderAddressAndSource()}
231
- </main>
232
- </article>`;
233
- }
234
-
235
- if (this.cardType === "bill-image") {
236
- return html`<article class=${classMap(classes)}>
237
- ${this.renderImageHeader()}
238
- <main>
239
- ${this.renderLogo()} ${this.renderTags()} ${this.renderSource()}
240
- ${this.renderContent()} ${this.renderAddressAndSource()}
241
- ${this.renderLangDate()}
242
- </main>
243
- </article>`;
244
- }
245
-
246
- return html`<article class=${classMap(classes)}>
247
- ${this.renderImageHeader()}
55
+ if (!this.object) return nothing;
56
+ const tags = this._getTags();
57
+
58
+ return html`<article class="vertical">
59
+ <header
60
+ class="image"
61
+ style='background-image: url("${this._getThumbnail()}")'
62
+ ></header>
248
63
  <main>
249
- ${this.renderLogo()} ${this.renderLangDate()} ${this.renderContent()}
250
- ${this.renderAddressAndSource()} ${this.renderSource()}
251
- ${this.renderTags()}
64
+ <div class="tags">
65
+ <tems-badge
66
+ type="success"
67
+ size="sm"
68
+ label=${this.object.pricingTier}
69
+ ></tems-badge>
70
+ <tems-badge
71
+ type="information"
72
+ size="sm"
73
+ label=${`${this.object.bundleSize || 0}
74
+ ${(this.object.bundleSize || 0) > 1 ? msg("facts") : msg("fact")}`}
75
+ ></tems-badge>
76
+ </div>
77
+ <div class="content">
78
+ ${this.object?.name
79
+ ? html`<div class="card-header">
80
+ <tems-division
81
+ label=${this.object?.name}
82
+ type="h4"
83
+ ></tems-division>
84
+ </div>`
85
+ : nothing}
86
+ ${this.object?.description
87
+ ? html`<div class="card-content">
88
+ <tems-division
89
+ label=${this.object?.description}
90
+ type="body-m"
91
+ ></tems-division>
92
+ </div>`
93
+ : nothing}
94
+ </div>
95
+ ${tags.length > 0
96
+ ? html`<div class="tags">
97
+ ${tags.map(
98
+ (tag) =>
99
+ html`<tems-badge
100
+ size="sm"
101
+ label=${tag.label}
102
+ type=${tag.type}
103
+ color=${tag.color || nothing}
104
+ ></tems-badge>`,
105
+ )}
106
+ </div>`
107
+ : nothing}
252
108
  </main>
253
- <div class="action"><slot></slot></div>
254
109
  </article>`;
255
110
  }
256
111
  }
@@ -0,0 +1,158 @@
1
+ import type { DSPOffer } from "@src/ds4go";
2
+ import {
3
+ filterObjectByDateAfter,
4
+ filterObjectById,
5
+ filterObjectByInterval,
6
+ filterObjectByNamedValue,
7
+ filterObjectByType,
8
+ filterObjectByValue,
9
+ } from "@helpers";
10
+ import type { Resource } from "@src/component";
11
+ import {
12
+ TemsObjectsHandler,
13
+ type TemsSearchObject,
14
+ } from "@startinblox/solid-tems-shared";
15
+ import { css, html, nothing, type PropertyValues } from "lit";
16
+ import { customElement, state } from "lit/decorators.js";
17
+
18
+ @customElement("ds4go-catalog-data-holder")
19
+ export class Ds4goCatalogDataHolder extends TemsObjectsHandler {
20
+ static styles = css`
21
+ .card-grid {
22
+ display: flex;
23
+ flex-direction: row;
24
+ flex-wrap: wrap;
25
+ gap: 20px;
26
+ }
27
+ .card-grid-vertical {
28
+ justify-content: stretch;
29
+ }
30
+ .card-grid-vertical ds4go-card-dataspace-catalog {
31
+ width: 354px;
32
+ height: auto;
33
+ }
34
+ ds4go-card-dataspace-catalog {
35
+ cursor: pointer;
36
+ }
37
+ `;
38
+
39
+ @state()
40
+ view: "card" | "list" | "table" | "map" = "card";
41
+
42
+ @state()
43
+ search: TemsSearchObject[] = [];
44
+
45
+ objects: Resource[] = [];
46
+
47
+ @state()
48
+ protected _displayObjects: DSPOffer[] = [];
49
+
50
+ protected filter(objects: any[], filters: TemsSearchObject[] = []) {
51
+ if (!filters || filters.length === 0 || !objects || objects.length === 0) {
52
+ return objects;
53
+ }
54
+
55
+ const groupedFilters = new Map<string, TemsSearchObject[]>();
56
+ for (const filter of filters) {
57
+ const groupKey = filter.name;
58
+ const group = groupedFilters.get(groupKey) || [];
59
+ group.push(filter);
60
+ groupedFilters.set(groupKey, group);
61
+ }
62
+
63
+ let currentFilteredObjects = [...objects];
64
+
65
+ for (const filterGroup of groupedFilters.values()) {
66
+ if (currentFilteredObjects.length === 0) {
67
+ break;
68
+ }
69
+
70
+ const tempResults = [];
71
+ for (const filter of filterGroup) {
72
+ switch (filter.type) {
73
+ case "interval":
74
+ tempResults.push(
75
+ filterObjectByInterval(
76
+ currentFilteredObjects,
77
+ filter.name,
78
+ filter.value,
79
+ ),
80
+ );
81
+ break;
82
+ case "dateAfter":
83
+ tempResults.push(
84
+ filterObjectByDateAfter(
85
+ currentFilteredObjects,
86
+ filter.name,
87
+ filter.value,
88
+ ),
89
+ );
90
+ break;
91
+ case "matchId":
92
+ tempResults.push(
93
+ filterObjectById(
94
+ currentFilteredObjects,
95
+ filter.name,
96
+ filter.value,
97
+ ),
98
+ );
99
+ break;
100
+ case "matchType":
101
+ tempResults.push(
102
+ filterObjectByType(currentFilteredObjects, filter.value),
103
+ );
104
+ break;
105
+ case "exact":
106
+ tempResults.push(
107
+ filterObjectByNamedValue(
108
+ currentFilteredObjects,
109
+ filter.name,
110
+ filter.value,
111
+ ),
112
+ );
113
+ break;
114
+ default:
115
+ tempResults.push(
116
+ filterObjectByValue(currentFilteredObjects, filter.value),
117
+ );
118
+ }
119
+ }
120
+ currentFilteredObjects = [...tempResults.flat()];
121
+ }
122
+
123
+ return currentFilteredObjects;
124
+ }
125
+
126
+ protected _handleClickEvent(originalObj: Resource) {
127
+ this.dispatchEvent(new CustomEvent("clicked", { detail: originalObj }));
128
+ }
129
+
130
+ willUpdate(changedProperties: PropertyValues) {
131
+ if (changedProperties.has("objects") || changedProperties.has("search")) {
132
+ const filteredObjects = this.filter(this.objects, this.search);
133
+ this.dispatchEvent(
134
+ new CustomEvent("result-count", { detail: filteredObjects.length }),
135
+ );
136
+
137
+ this._displayObjects = filteredObjects as DSPOffer[];
138
+ }
139
+ }
140
+
141
+ render() {
142
+ if (!this._displayObjects || this._displayObjects.length === 0) {
143
+ return nothing;
144
+ }
145
+
146
+ return html`<div
147
+ class="card-grid${this.view === "card" ? " card-grid-vertical" : ""}"
148
+ >
149
+ ${this._displayObjects.map((dspOffer) => {
150
+ return html`<ds4go-card-dataspace-catalog
151
+ .object=${dspOffer}
152
+ type=${this.view === "card" ? "card" : "horizontal"}
153
+ @click=${() => this._handleClickEvent(dspOffer as Resource)}
154
+ ></ds4go-card-dataspace-catalog>`;
155
+ })}
156
+ </div>`;
157
+ }
158
+ }