@startinblox/components-ds4go 3.1.2 → 3.1.3

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/dist/index.js CHANGED
@@ -1 +1 @@
1
- import "./index-juyC2UdH.js";
1
+ import "./index-aCtNDRnY.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startinblox/components-ds4go",
3
- "version": "3.1.2",
3
+ "version": "3.1.3",
4
4
  "description": "Startin'blox DS4GO",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -87,14 +87,20 @@ export interface LiveOrbit extends Orbit {
87
87
  getRoute: (
88
88
  type: string,
89
89
  returnFirst?: boolean,
90
- ignoreError?: boolean
90
+ ignoreError?: boolean,
91
91
  ) => string | false;
92
92
  Swal: any;
93
93
  defaultRoute: string;
94
94
  }
95
95
 
96
96
  export type Context = Record<string, string | { "@id": string }>;
97
- export type Permission = "add" | "delete" | "change" | "control" | "view" | string;
97
+ export type Permission =
98
+ | "add"
99
+ | "delete"
100
+ | "change"
101
+ | "control"
102
+ | "view"
103
+ | string;
98
104
  export type DateTime = string;
99
105
 
100
106
  export interface LimitedResource {
@@ -231,38 +237,81 @@ export interface PolicyDefinitionInput {
231
237
  "@type"?: string;
232
238
  "@id": string;
233
239
  policy: OdrlPolicy;
234
- }interface AssetSelector {
235
- "@type": "CriterionDto";
236
- operandLeft: string;
237
- operator: string;
238
- operandRight: any;
240
+ }
241
+
242
+ interface AssetSelector {
243
+ "@type": "CriterionDto";
244
+ operandLeft: string;
245
+ operator: string;
246
+ operandRight: any;
247
+ }
248
+
249
+ export type NegotiationState =
250
+ | "REQUESTING"
251
+ | "REQUESTED"
252
+ | "OFFERING"
253
+ | "OFFERED"
254
+ | "ACCEPTING"
255
+ | "ACCEPTED"
256
+ | "AGREEING"
257
+ | "AGREED"
258
+ | "VERIFYING"
259
+ | "VERIFIED"
260
+ | "FINALIZING"
261
+ | "FINALIZED"
262
+ | "TERMINATING"
263
+ | "TERMINATED";
264
+
265
+ export type NegotiationType = "CONSUMER" | "PROVIDER";
266
+
267
+ export interface ContractNegotiation {
268
+ "@id": string;
269
+ "@type"?: string;
270
+ state: NegotiationState;
271
+ counterPartyId?: string;
272
+ counterPartyAddress?: string;
273
+ contractAgreementId?: string;
274
+ assetId?: string;
275
+ errorDetail?: string;
276
+ createdAt?: number;
277
+ type?: NegotiationType;
278
+ }
279
+
280
+ export interface ContractAgreement {
281
+ "@type": "ContractAgreement";
282
+ "@id": string;
283
+ assetId: string;
284
+ policy?: any;
285
+ contractSigningDate?: number;
286
+ consumerId?: string;
287
+ providerId?: string;
239
288
  }
240
289
 
241
290
  export interface ContractDefinition {
242
- "@type": "ContractDefinition";
243
- "@id": string;
244
- "@context"?: any;
245
- accessPolicyId: string;
246
- contractPolicyId: string;
247
- assetsSelector?: AssetSelector[] | AssetSelector;
248
- createdAt?: number;
291
+ "@type": "ContractDefinition";
292
+ "@id": string;
293
+ "@context"?: any;
294
+ accessPolicyId: string;
295
+ contractPolicyId: string;
296
+ assetsSelector?: AssetSelector[] | AssetSelector;
297
+ createdAt?: number;
249
298
  }
250
299
 
251
300
  export interface ContractDefinitionInput {
252
- "@id": string;
253
- accessPolicyId: string;
254
- contractPolicyId: string;
255
- assetsSelector?: AssetSelector[];
301
+ "@id": string;
302
+ accessPolicyId: string;
303
+ contractPolicyId: string;
304
+ assetsSelector?: AssetSelector[];
256
305
  }
257
306
 
258
307
  export interface PolicyDefinition {
259
- "@id": string;
260
- policy?: OdrlPolicy;
308
+ "@id": string;
309
+ policy?: OdrlPolicy;
261
310
  }
262
311
 
263
312
  export interface Asset {
264
- "@id": string;
265
- properties?: Record<string, any>;
313
+ "@id": string;
314
+ properties?: Record<string, any>;
266
315
  }
267
316
 
268
317
  export declare global {
@@ -1,82 +1,221 @@
1
- import { ComponentObjectHandler } from "@helpers";
1
+ import { OrbitComponent } from "@helpers";
2
2
  import { localized, msg } from "@lit/localize";
3
- import type { Resource } from "@src/component";
3
+ import { Task } from "@lit/task";
4
+ import type {
5
+ Asset,
6
+ ContractAgreement,
7
+ ContractDefinition,
8
+ ContractNegotiation,
9
+ OrbitComponent as OrbitComponentConfig,
10
+ PolicyDefinition,
11
+ Resource,
12
+ } from "@src/component";
4
13
 
5
14
  import ModalStyle from "@styles/modal/ds4go-fact-bundle-modal.scss?inline";
6
15
  import { css, html, nothing, unsafeCSS } from "lit";
7
- import { customElement, property } from "lit/decorators.js";
16
+ import { customElement, state } from "lit/decorators.js";
17
+
18
+ type ExtendedContractNegotiation = ContractNegotiation & {
19
+ agreement?: ContractAgreement;
20
+ };
8
21
 
9
22
  @customElement("ds4go-fact-bundle-modal")
10
23
  @localized()
11
- export class Ds4goFactBundleModal extends ComponentObjectHandler {
24
+ export class Ds4goFactBundleModal extends OrbitComponent {
25
+ constructor() {
26
+ super({ setupSubscriptions: false, ignoreRouter: true });
27
+ }
28
+
12
29
  static styles = css`
13
30
  ${unsafeCSS(ModalStyle)}
14
31
  `;
15
32
 
16
- @property({ attribute: false, type: Object })
17
- object: Resource = { "@id": "" };
33
+ @state()
34
+ dspConnector: OrbitComponentConfig | undefined;
35
+
36
+ async _afterAttach() {
37
+ // use this.dspConnector.instance to reach the connector
38
+ this.dspConnector = this.orbit?.components.find(
39
+ (c) => c.type === "dsp-connector",
40
+ );
41
+
42
+ return Promise.resolve();
43
+ }
18
44
 
19
45
  _closeModal() {
20
46
  this.dispatchEvent(new CustomEvent("close"));
21
47
  }
22
48
 
49
+ @state()
50
+ assets: Asset[] = [];
51
+
52
+ @state()
53
+ policies: PolicyDefinition[] = [];
54
+
55
+ @state()
56
+ contracts: ContractDefinition[] = [];
57
+
58
+ @state()
59
+ negotiations: ExtendedContractNegotiation[] = [];
60
+
61
+ _getResource = new Task(this, {
62
+ task: async () => {
63
+ if (!this.object) return;
64
+
65
+ if (this.dspConnector?.instance) {
66
+ this.assets = this.dspConnector.instance.assets.filter(
67
+ (a: Asset) =>
68
+ a.dataAddress?.baseUrl ===
69
+ "https://api.stg.ds4go.startinblox.com/factbundles/21/",
70
+ );
71
+
72
+ this.contracts = this.dspConnector.instance.contracts.filter(
73
+ (c: ContractDefinition) =>
74
+ (this.assets || []).find((a: Asset) => {
75
+ if (!c.assetsSelector) {
76
+ return false;
77
+ }
78
+ if (Array.isArray(c.assetsSelector)) {
79
+ return c.assetsSelector.find(
80
+ (s) => s.operandRight === a["@id"],
81
+ );
82
+ }
83
+ return c.assetsSelector.operandRight === a["@id"];
84
+ }),
85
+ );
86
+
87
+ this.policies = [
88
+ ...(this.contracts || []).flatMap((c: ContractDefinition) => {
89
+ if (!c.accessPolicyId && !c.contractPolicyId) return [];
90
+ return this.dspConnector?.instance?.policies.filter(
91
+ (p: PolicyDefinition) =>
92
+ p["@id"] === c.accessPolicyId ||
93
+ p["@id"] === c.contractPolicyId,
94
+ );
95
+ }),
96
+ ];
97
+
98
+ this.negotiations = this.dspConnector.instance.negotiations.filter(
99
+ (c: ContractNegotiation) => {
100
+ if (!c.assetId) return false;
101
+ return this.assets.find((a: Asset) => a["@id"] === c.assetId);
102
+ },
103
+ );
104
+
105
+ this.negotiations.forEach((n: ExtendedContractNegotiation) => {
106
+ if (n.contractAgreementId) {
107
+ n.agreement = this.dspConnector?.instance?.loadAgreement(n["@id"]);
108
+ }
109
+ });
110
+ } else {
111
+ console.warn(
112
+ "DSP Connector not found. Please ensure the DSP Connector is properly initialized.",
113
+ );
114
+ }
115
+
116
+ return this.object;
117
+ },
118
+ args: () => [this.caching, this.currentRoute],
119
+ });
120
+
23
121
  render() {
24
- return html`<div class="modal">
25
- <div class="topbar">
26
- <tems-button
27
- @click=${this._closeModal}
28
- type="outline-gray"
29
- .iconLeft=${html`<icon-material-symbols-close-rounded></icon-material-symbols-close-rounded>`}
30
- ></tems-button>
31
- </div>
32
- <div class="modal-content-wrapper">
33
- <div class="modal-box">
34
- <div class="modal-content">
35
- <tems-division type="h3"
36
- ><div>${String(this.object.name || "")}</div></tems-division
37
- >
38
- <tems-division type="body-m"
39
- ><div>${String(this.object.description || "")}</div></tems-division
40
- >
41
- <tems-division type="h4"
42
- ><div>${msg("All facts in this bundle")}</div></tems-division
43
- >
44
- <div class="card-grid card-grid-vertical">
45
- ${this.object.facts.map((fact: Resource) => {
46
- const tags = fact.categories.map((c: Resource) => ({
47
- name: c.name,
48
- type: "information",
49
- }));
50
- if (tags.length > 3) {
51
- const overflowTags = tags.length - 3;
52
- tags.splice(3, overflowTags);
53
- tags.push({
54
- name: `+${overflowTags} ${msg("more")}`,
55
- type: "information",
56
- });
57
- }
58
- return html`<ds4go-card-catalog
59
- .object=${import.meta.env.DEV ? fact : nothing}
60
- .tags=${tags}
61
- .header=${fact.name || nothing}
62
- .content=${fact.description || nothing}
63
- date=${fact.updated_at || nothing}
64
- ></ds4go-card-catalog>`;
65
- })}
66
- </div>
67
- <tems-division type="body-sm"
68
- ><div>
69
- <div>
70
- ${msg("Bundle created on")} ${String(this.object.created_at)}
71
- </div>
72
- <div>
73
- ${msg("Bundle updated on")} ${String(this.object.updated_at)}
122
+ return this._getResource.render({
123
+ pending: () => html`<solid-loader></solid-loader>`,
124
+ complete: (obj?: Resource) => {
125
+ if (!obj) {
126
+ this._closeModal();
127
+ return nothing;
128
+ }
129
+
130
+ return html`<div class="modal">
131
+ <div class="topbar">
132
+ <tems-button
133
+ @click=${this._closeModal}
134
+ type="outline-gray"
135
+ .iconLeft=${html`<icon-material-symbols-close-rounded></icon-material-symbols-close-rounded>`}
136
+ ></tems-button>
137
+ </div>
138
+ <div class="modal-content-wrapper">
139
+ <div class="modal-box">
140
+ <div class="modal-content">
141
+ <tems-division type="h3"
142
+ ><div>${String(obj.name || "")}</div></tems-division
143
+ >
144
+ <tems-division type="body-m"
145
+ ><div>${String(obj.description || "")}</div></tems-division
146
+ >
147
+ <tems-division type="h4"
148
+ ><div>${msg("All facts in this bundle")}</div></tems-division
149
+ >
150
+ <div class="card-grid card-grid-vertical">
151
+ ${obj.facts.map((fact: Resource) => {
152
+ const tags = fact.categories.map((c: Resource) => ({
153
+ name: c.name,
154
+ type: "information",
155
+ }));
156
+ if (tags.length > 3) {
157
+ const overflowTags = tags.length - 3;
158
+ tags.splice(3, overflowTags);
159
+ tags.push({
160
+ name: `+${overflowTags} ${msg("more")}`,
161
+ type: "information",
162
+ });
163
+ }
164
+ return html`<ds4go-card-catalog
165
+ .object=${import.meta.env.DEV ? fact : nothing}
166
+ .tags=${tags}
167
+ .header=${fact.name || nothing}
168
+ .content=${fact.description || nothing}
169
+ date=${fact.updated_at || nothing}
170
+ ></ds4go-card-catalog>`;
171
+ })}
74
172
  </div>
75
- </div></tems-division
76
- >
173
+ <tems-division type="body-sm"
174
+ ><div>
175
+ <div>
176
+ ${msg("Bundle created on")} ${String(obj.created_at)}
177
+ </div>
178
+ <div>
179
+ ${msg("Bundle updated on")} ${String(obj.updated_at)}
180
+ </div>
181
+ </div></tems-division
182
+ >
183
+ <tems-division type="h4"
184
+ ><div>${msg("Technical informations")}</div></tems-division
185
+ >
186
+ ${this.contracts && this.contracts.length > 0
187
+ ? html`${this.contracts.map(
188
+ (contract: ContractDefinition) =>
189
+ html`<ds4go-contract-modal-part
190
+ .contract=${contract}
191
+ .assets=${this.assets}
192
+ .policies=${this.policies}
193
+ ></ds4go-contract-modal-part>`,
194
+ )}`
195
+ : nothing}
196
+ ${this.negotiations && this.negotiations.length > 0
197
+ ? html`<ds4go-negotiations-modal-part
198
+ .negotiations=${this.negotiations}
199
+ .assets=${this.assets}
200
+ .type=${"PROVIDER"}
201
+ ></ds4go-negotiations-modal-part>
202
+ <ds4go-negotiations-modal-part
203
+ .negotiations=${this.negotiations}
204
+ .assets=${this.assets}
205
+ .type=${"CONSUMER"}
206
+ ></ds4go-negotiations-modal-part>`
207
+ : nothing}
208
+ </div>
209
+ </div>
77
210
  </div>
78
- </div>
79
- </div>
80
- </div>`;
211
+ </div>`;
212
+ },
213
+ error: (e) => {
214
+ if (import.meta.env.DEV) {
215
+ console.error(e, this);
216
+ }
217
+ return nothing;
218
+ },
219
+ });
81
220
  }
82
221
  }
@@ -0,0 +1,145 @@
1
+ import { localized, msg } from "@lit/localize";
2
+ import type {
3
+ Asset,
4
+ ContractDefinition,
5
+ PolicyDefinition,
6
+ } from "@src/component";
7
+ import ComponentStyle from "@styles/modal/fact-bundle-modal/ds4go-contract-modal-part.scss?inline";
8
+ import { css, html, LitElement, nothing, unsafeCSS } from "lit";
9
+ import { customElement, state } from "lit/decorators.js";
10
+
11
+ @customElement("ds4go-contract-modal-part")
12
+ @localized()
13
+ export class DS4GOContractModalPart extends LitElement {
14
+ static styles = css`
15
+ ${unsafeCSS(ComponentStyle)}
16
+ `;
17
+
18
+ @state()
19
+ contract?: ContractDefinition;
20
+
21
+ @state()
22
+ assets?: Asset[] = [];
23
+
24
+ @state()
25
+ policies?: PolicyDefinition[] = [];
26
+
27
+ @state()
28
+ expandedAssets = false;
29
+
30
+ @state()
31
+ expandedPolicies = false;
32
+
33
+ _toggleSection(section: "assets" | "policies") {
34
+ if (section === "assets") {
35
+ this.expandedAssets = !this.expandedAssets;
36
+ } else {
37
+ this.expandedPolicies = !this.expandedPolicies;
38
+ }
39
+ }
40
+
41
+ render() {
42
+ if (!this.contract) {
43
+ return nothing;
44
+ }
45
+
46
+ const contractId = this.contract["@id"];
47
+ const relatedAssets = this.assets?.filter((a: Asset) => {
48
+ if (!this.contract?.assetsSelector) return false;
49
+ if (Array.isArray(this.contract.assetsSelector)) {
50
+ return this.contract.assetsSelector.find(
51
+ (s) => s.operandRight === a["@id"],
52
+ );
53
+ }
54
+ return this.contract.assetsSelector.operandRight === a["@id"];
55
+ });
56
+
57
+ const relatedPolicies = this.policies?.filter(
58
+ (p: PolicyDefinition) =>
59
+ p["@id"] === this.contract?.accessPolicyId ||
60
+ p["@id"] === this.contract?.contractPolicyId,
61
+ );
62
+
63
+ return html`<div class="contract-section">
64
+ <div class="contract-header">
65
+ <tems-division type="h5">${msg("Contract")}</tems-division>
66
+ <tems-division type="body-sm"
67
+ >${contractId.split("/").pop()}</tems-division
68
+ >
69
+ ${this.contract.createdAt
70
+ ? html`<tems-division type="body-sm"
71
+ >${msg("Created")}:
72
+ ${new Date(
73
+ this.contract.createdAt,
74
+ ).toLocaleString()}</tems-division
75
+ >`
76
+ : nothing}
77
+ </div>
78
+
79
+ ${relatedAssets && relatedAssets.length > 0
80
+ ? html`<div class="contract-subsection">
81
+ <div
82
+ class="collapsible-header"
83
+ @click=${() => this._toggleSection("assets")}
84
+ >
85
+ <tems-division type="body-m">${msg("Assets")}</tems-division>
86
+ <icon-material-symbols-expand-more
87
+ class="chevron ${this.expandedAssets ? "expanded" : ""}"
88
+ ></icon-material-symbols-expand-more>
89
+ </div>
90
+ <div
91
+ class="collapsible-content ${this.expandedAssets
92
+ ? "expanded"
93
+ : ""}"
94
+ >
95
+ <div class="assets-list">
96
+ ${relatedAssets.map(
97
+ (asset: Asset) =>
98
+ html`<div class="asset-item">
99
+ <tems-division type="body-sm"
100
+ >${asset["@id"].split("/").pop()}</tems-division
101
+ >
102
+ <tems-division type="body-xs"
103
+ >${asset.dataAddress?.baseUrl ||
104
+ msg("No base URL")}</tems-division
105
+ >
106
+ ${asset.dataAddress?.type
107
+ ? html`<tems-division type="body-xs"
108
+ >${msg("Type")}:
109
+ ${asset.dataAddress.type}</tems-division
110
+ >`
111
+ : nothing}
112
+ </div>`,
113
+ )}
114
+ </div>
115
+ </div>
116
+ </div>`
117
+ : nothing}
118
+ ${relatedPolicies && relatedPolicies.length > 0
119
+ ? html`<div class="contract-subsection">
120
+ <div
121
+ class="collapsible-header"
122
+ @click=${() => this._toggleSection("policies")}
123
+ >
124
+ <tems-division type="body-m">${msg("Policies")}</tems-division>
125
+ <icon-material-symbols-expand-more
126
+ class="chevron ${this.expandedPolicies ? "expanded" : ""}"
127
+ ></icon-material-symbols-expand-more>
128
+ </div>
129
+ <div
130
+ class="collapsible-content ${this.expandedPolicies
131
+ ? "expanded"
132
+ : ""}"
133
+ >
134
+ ${relatedPolicies.map(
135
+ (policy: PolicyDefinition) =>
136
+ html`<ds4go-odrl-policy-modal-part
137
+ .policy=${policy}
138
+ ></ds4go-odrl-policy-modal-part>`,
139
+ )}
140
+ </div>
141
+ </div>`
142
+ : nothing}
143
+ </div>`;
144
+ }
145
+ }