Skip to content

Commit 8966847

Browse files
committed
Bump version 0.8.2 to 0.8.3
2 parents 72782f7 + fb59be3 commit 8966847

29 files changed

+8096
-9327
lines changed

package-lock.json

Lines changed: 7587 additions & 8884 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "inesdata-connector-interface",
3-
"version": "0.8.2",
3+
"version": "0.8.3",
44
"project": "com.gmv.inesdata",
55
"scripts": {
66
"ng": "ng",
@@ -27,11 +27,11 @@
2727
"@angular/router": "^17.1.2",
2828
"@auth0/angular-jwt": "^5.2.0",
2929
"@ckeditor/ckeditor5-angular": "^7.0.1",
30-
"@ckeditor/ckeditor5-build-classic": "^41.4.2",
31-
"@ckeditor/ckeditor5-core": "^41.4.2",
32-
"@ckeditor/ckeditor5-engine": "^41.4.2",
33-
"@ckeditor/ckeditor5-utils": "^41.4.2",
34-
"@ckeditor/ckeditor5-watchdog": "^41.4.2",
30+
"@ckeditor/ckeditor5-build-classic": "^43.1.0",
31+
"@ckeditor/ckeditor5-core": "^43.1.0",
32+
"@ckeditor/ckeditor5-engine": "^43.1.0",
33+
"@ckeditor/ckeditor5-utils": "^43.1.0",
34+
"@ckeditor/ckeditor5-watchdog": "^43.1.0",
3535
"@jsonforms/angular": "^3.2.1",
3636
"@jsonforms/angular-material": "^3.2.1",
3737
"@jsonforms/core": "^3.2.1",

src/app/pages/assets/asset-create/asset-create.component.html

Lines changed: 219 additions & 215 deletions
Large diffs are not rendered by default.

src/app/pages/assets/asset-create/asset-create.component.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,16 @@ mat-card-actions {
5959
:host ::ng-deep .mat-expansion-indicator {
6060
display: none;
6161
}
62+
63+
.toggle {
64+
margin-bottom: 22px;
65+
--mat-mdc-form-field-floating-label-scale: 0.75;
66+
display: inline-flex;
67+
flex-direction: column;
68+
min-width: 0;
69+
text-align: left;
70+
}
71+
72+
:host ::ng-deep .toggle .mdc-form-field{
73+
font-size: 16px;
74+
}

src/app/pages/assets/asset-create/asset-create.component.ts

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Component, Inject, OnInit } from '@angular/core';
2-
import { HttpDataAddress, DataAddress, AssetInput } from '@think-it-labs/edc-connector-client';
3-
import { MatDialogRef } from "@angular/material/dialog";
2+
import { HttpDataAddress, DataAddress } from '@think-it-labs/edc-connector-client';
43
import { JsonDoc } from "../../../shared/models/json-doc";
54
import { StorageType } from "../../../shared/models/storage-type";
65
import { AmazonS3DataAddress } from "../../../shared/models/amazon-s3-data-address";
@@ -19,6 +18,7 @@ import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
1918
import { AssetService } from 'src/app/shared/services/asset.service';
2019
import { BehaviorSubject } from 'rxjs';
2120
import { Router } from '@angular/router';
21+
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
2222

2323

2424
@Component({
@@ -89,7 +89,7 @@ export class AssetCreateComponent implements OnInit {
8989
type: 'InesDataStore'
9090
};
9191

92-
assetType:any;
92+
assetType: any;
9393
assetTypes = Object.entries(ASSET_TYPES);
9494
defaultForms: JsonFormData[]
9595
selectedForms: JsonFormData[]
@@ -101,7 +101,7 @@ export class AssetCreateComponent implements OnInit {
101101
config = CKEDITOR_CONFIG
102102
selectedAssetTypeVocabularies: Vocabulary[]
103103

104-
urlPattern: RegExp = /^(file|ftp|http|https|imap|irc|nntp|acap|icap|mtqp|wss):\/\/(localhost|([a-z\d]([a-z\d-]*[a-z\d])*)|(([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i;
104+
urlPattern: RegExp = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/;
105105

106106
private fetch$ = new BehaviorSubject(null);
107107

@@ -122,7 +122,7 @@ export class AssetCreateComponent implements OnInit {
122122
}
123123
if (this.selectedVocabularies?.length > 0) {
124124
this.selectedVocabularies.forEach(s => {
125-
if(this.selectedAssetTypeVocabularies.find(satv=> satv['@id'] === s['@id'])){
125+
if (this.selectedAssetTypeVocabularies.find(satv => satv['@id'] === s['@id'])) {
126126
this.initVocabularyForm(s, false)
127127
}
128128
})
@@ -168,7 +168,7 @@ export class AssetCreateComponent implements OnInit {
168168
const forms: JsonFormData[] = [...this.defaultForms, ...this.selectedForms]
169169

170170
let assetDataProperty: any = {}
171-
forms.forEach(async f=>{
171+
forms.forEach(async f => {
172172
if (f.schema && f.schema.hasOwnProperty("@context")) {
173173
// Add context if it is provided in the Json Schema
174174
const jsonSchema: JsonDoc = f.schema as JsonDoc;
@@ -197,7 +197,7 @@ export class AssetCreateComponent implements OnInit {
197197
dataAddress = this.amazonS3DataAddress;
198198
} else if (this.storageTypeId === DATA_ADDRESS_TYPES.httpData) {
199199
dataAddress = this.httpDataAddress;
200-
} else if (this.storageTypeId === DATA_ADDRESS_TYPES.inesDataStore) {
200+
} else if (this.storageTypeId === DATA_ADDRESS_TYPES.inesDataStore) {
201201
dataAddress = this.inesDataStoreAddress;
202202
} else {
203203
this.notificationService.showError("Incorrect destination value");
@@ -213,6 +213,7 @@ export class AssetCreateComponent implements OnInit {
213213
};
214214

215215
if (this.storageTypeId === DATA_ADDRESS_TYPES.inesDataStore && this.inesDataStoreAddress?.file) {
216+
this.loadingService.showLoading('Processing the file...');
216217
const file = this.inesDataStoreAddress?.file;
217218

218219
const chunkSize = 1024 * 1024;
@@ -229,7 +230,7 @@ export class AssetCreateComponent implements OnInit {
229230
assetInput.blob = new Blob(chunks);
230231
}
231232

232-
this.createAsset(assetInput)
233+
await this.createAsset(assetInput)
233234
}
234235
addInfoProperties(properties: JsonDoc) {
235236
// Add default information
@@ -245,7 +246,7 @@ export class AssetCreateComponent implements OnInit {
245246
this.addKeywords(properties);
246247
}
247248

248-
addKeywords(properties: JsonDoc){
249+
addKeywords(properties: JsonDoc) {
249250
const parsedKeywords: string[] = [];
250251
this.keywords.split(",").forEach(keyword => parsedKeywords.push(keyword.trim()));
251252
properties["dcat:keyword"] = parsedKeywords;
@@ -286,7 +287,7 @@ export class AssetCreateComponent implements OnInit {
286287
if (!this.id || !this.storageTypeId || !this.name || !this.version || !this.description || !this.keywords || !this.shortDescription || !this.assetType) {
287288
return false;
288289
} else {
289-
if (this.storageTypeId === DATA_ADDRESS_TYPES.httpData && (!this.httpDataAddress.name || !this.httpDataAddress.baseUrl || !this.validateUrl())) {
290+
if (this.storageTypeId === DATA_ADDRESS_TYPES.httpData && (!this.httpDataAddress.name || !this.httpDataAddress.baseUrl || !this.validateUrl())) {
290291
return false;
291292
}
292293
if (this.storageTypeId === DATA_ADDRESS_TYPES.amazonS3 && !this.amazonS3DataAddress.region) {
@@ -328,7 +329,7 @@ export class AssetCreateComponent implements OnInit {
328329

329330
if (this.selectedVocabularies.length > 0) {
330331
this.selectedVocabularies.forEach(s => {
331-
if(this.selectedAssetTypeVocabularies.find(satv=> satv['@id'] === s['@id'])){
332+
if (this.selectedAssetTypeVocabularies.find(satv => satv['@id'] === s['@id'])) {
332333
this.initVocabularyForm(s, false)
333334
}
334335
})
@@ -339,24 +340,24 @@ export class AssetCreateComponent implements OnInit {
339340
* Transform to text asset type value
340341
* @returns asset type text
341342
*/
342-
getAssetTypeText(){
343-
return this.assetType?ASSET_TYPES[this.assetType as keyof typeof ASSET_TYPES]:'';
343+
getAssetTypeText() {
344+
return this.assetType ? ASSET_TYPES[this.assetType as keyof typeof ASSET_TYPES] : '';
344345
}
345346

346-
setFiles(event:File[]){
347-
if(event?.length>0){
347+
setFiles(event: File[]) {
348+
if (event?.length > 0) {
348349
this.inesDataStoreAddress.file = event[0]
349-
}else{
350+
} else {
350351
delete this.inesDataStoreAddress.file
351352
}
352353
}
353354

354-
onSelectionChangeVocabulary(){
355+
onSelectionChangeVocabulary() {
355356
this.selectedForms = []
356357

357358
if (this.selectedVocabularies.length > 0) {
358359
this.selectedVocabularies.forEach(s => {
359-
if(this.selectedAssetTypeVocabularies.find(satv=> satv['@id'] === s['@id'])){
360+
if (this.selectedAssetTypeVocabularies.find(satv => satv['@id'] === s['@id'])) {
360361
this.initVocabularyForm(s, false)
361362
}
362363
})
@@ -366,46 +367,80 @@ export class AssetCreateComponent implements OnInit {
366367
validateUrl(): boolean {
367368
const regex = new RegExp(this.urlPattern);
368369
return regex.test(this.httpDataAddress.baseUrl);
369-
}
370+
}
370371

371372

372-
private createAsset(asset: AssetInput){
373-
const newAsset = asset;
374-
if (newAsset) {
375-
if (newAsset.dataAddress.type !== DATA_ADDRESS_TYPES.inesDataStore) {
376-
this.assetService.createAsset(newAsset).subscribe({
377-
next: () => this.fetch$.next(null),
378-
error: err => this.showError(err, "This asset cannot be created"),
379-
complete: () => {
380-
this.navigateToAsset()
381-
this.notificationService.showInfo("Successfully created");
382-
this.loadingService.hideLoading();
383-
}
384-
})
385-
} else {
386-
this.assetService.createStorageAsset(newAsset).subscribe({
387-
next: () => this.fetch$.next(null),
388-
error: err => this.showError(err, "This asset cannot be created"),
389-
complete: () => {
390-
this.navigateToAsset()
391-
this.notificationService.showInfo("Successfully created");
392-
this.loadingService.hideLoading();
373+
async createAsset(assetInput: any) {
374+
if (this.storageTypeId === DATA_ADDRESS_TYPES.inesDataStore && this.inesDataStoreAddress.file) {
375+
const file = this.inesDataStoreAddress.file;
376+
const chunkSize = 50 * 1024 * 1024; // 50 MB
377+
const totalChunks = Math.ceil(file.size / chunkSize);
378+
const fileName = file.name;
379+
const maxRetries = 3;
380+
381+
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
382+
const start = chunkIndex * chunkSize;
383+
const chunk = file.slice(start, start + chunkSize);
384+
385+
let attempt = 0;
386+
let success = false;
387+
388+
const progressPercentage = Math.floor(((chunkIndex + 1) / totalChunks) * 100);
389+
390+
while (attempt < maxRetries && !success) {
391+
try {
392+
this.loadingService.updateMessage(`Uploading file: ${progressPercentage}% completed`);
393+
394+
await this.assetService.uploadChunk(assetInput, chunk, fileName, chunkIndex, totalChunks);
395+
success = true;
396+
} catch (error) {
397+
attempt++;
398+
if (attempt >= maxRetries) {
399+
this.loadingService.hideLoading();
400+
this.notificationService.showError(`Error uploading chunk ${chunkIndex + 1}. Maximum retries reached.`);
401+
return;
402+
}
393403
}
394-
})
404+
}
395405
}
396406

407+
try {
408+
await this.assetService.finalizeUpload(assetInput, fileName);
409+
this.loadingService.hideLoading();
410+
this.notificationService.showInfo('Asset created successfully');
411+
this.navigateToAsset();
412+
} catch (error: any) {
413+
this.loadingService.hideLoading();
414+
this.notificationService.showError('Error finalizing the asset creation: ' + error.error[0].message);
415+
}
416+
} else {
417+
this.assetService.createAsset(assetInput).subscribe({
418+
next: () => this.fetch$.next(null),
419+
error: (err) => {
420+
this.loadingService.hideLoading();
421+
this.showError(err, "Error creating the asset: " + err.error[0].message);
422+
},
423+
complete: () => {
424+
this.loadingService.hideLoading();
425+
this.notificationService.showInfo('Asset created successfully');
426+
this.navigateToAsset();
427+
},
428+
});
397429
}
398430
}
399431

400432

401-
402433
private showError(error: string, errorMessage: string) {
403434
this.notificationService.showError(errorMessage);
404435
console.error(error);
405436
this.loadingService.hideLoading();
406437
}
407438

408-
navigateToAsset(){
439+
navigateToAsset() {
409440
this.router.navigate(['assets'])
410441
}
442+
443+
onToggleChange(propertyName: string, event: MatSlideToggleChange): void {
444+
this.httpDataAddress[propertyName] = event ? 'true' : 'false';
445+
}
411446
}

src/app/pages/assets/asset-viewer/asset-viewer.component.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { Component, OnInit } from '@angular/core';
22
import { BehaviorSubject } from 'rxjs';
3-
import { first } from 'rxjs/operators';
43
import { MatDialog } from '@angular/material/dialog';
5-
import { AssetInput, Asset } from "../../../shared/models/edc-connector-entities";
4+
import { Asset } from "../../../shared/models/edc-connector-entities";
65
import { AssetService } from "../../../shared/services/asset.service";
76
import { ConfirmationDialogComponent, ConfirmDialogModel } from "../../../shared/components/confirmation-dialog/confirmation-dialog.component";
87
import { NotificationService } from "../../../shared/services/notification.service";
9-
import { CONTEXTS, DATA_ADDRESS_TYPES } from 'src/app/shared/utils/app.constants';
108
import { PageEvent } from '@angular/material/paginator';
11-
import { EDC_CONTEXT, QuerySpec, DataAddress } from '@think-it-labs/edc-connector-client';
12-
import { ContractOffersViewerComponent } from '../../catalog/contract-offers-viewer/contract-offers-viewer.component';
9+
import { EDC_CONTEXT, QuerySpec } from '@think-it-labs/edc-connector-client';
1310
import { compact } from 'jsonld';
1411
import { Router } from '@angular/router';
1512

@@ -67,7 +64,7 @@ export class AssetViewerComponent implements OnInit {
6764
if (res) {
6865
this.assetService.removeAsset(asset.id).subscribe({
6966
next: () => this.fetch$.next(null),
70-
error: err => this.showError(err, "This asset cannot be deleted"),
67+
error: err => this.showError(err, "This asset cannot be deleted: " + err.error[0].message),
7168
complete: () => {
7269
this.countAssets();
7370
this.loadAssets(this.currentPage);

src/app/pages/catalog/catalog-browser/catalog-browser.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import { Component, Inject, OnInit } from '@angular/core';
1+
import { Component, OnInit } from '@angular/core';
22
import { MatDialog } from '@angular/material/dialog';
33
import { CatalogBrowserService } from "../../../shared/services/catalog-browser.service";
44
import { DataOffer } from 'src/app/shared/models/data-offer';
5-
import { ContractOffersViewerComponent } from '../contract-offers-viewer/contract-offers-viewer.component';
6-
import { Policy } from 'src/app/shared/models/edc-connector-entities';
75
import { PageEvent } from '@angular/material/paginator';
86
import { QuerySpec } from '@think-it-labs/edc-connector-client';
9-
import { ContractOffer } from 'src/app/shared/models/contract-offer';
107
import { Router } from '@angular/router';
118

129

src/app/pages/catalog/contract-offers-viewer/contract-offers-viewer.component.scss

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ mat-list-item:hover .property-title,
2121
.property-value {
2222
font-size: 14px;
2323
color: #d7d7d7;
24+
overflow-wrap: anywhere;
25+
white-space: pre-wrap;
2426
}
2527

2628
.property-icon {
@@ -102,11 +104,6 @@ ul {
102104
padding: 20px;
103105
}
104106

105-
.property-value {
106-
overflow-wrap: anywhere;
107-
white-space: pre-wrap;
108-
}
109-
110107
.grey {
111108
margin-bottom: 15px;
112109
}

src/app/pages/catalog/contract-offers-viewer/contract-offers-viewer.component.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, Inject } from '@angular/core';
2-
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
2+
import { MatDialog } from '@angular/material/dialog';
33
import { TransferProcessStates } from "../../../shared/models/transfer-process-states";
44
import { NegotiationResult } from "../../../shared/models/negotiation-result";
55
import { ContractNegotiation, ContractNegotiationRequest, Policy } from "../../../shared/models/edc-connector-entities";
@@ -8,7 +8,6 @@ import { NotificationService } from 'src/app/shared/services/notification.servic
88
import { StorageType } from 'src/app/shared/models/storage-type';
99
import { PolicyCard } from '../../../shared/models/policy/policy-card';
1010
import { DATA_ADDRESS_TYPES } from '../../../shared/utils/app.constants';
11-
import { ContractOffer } from 'src/app/shared/models/contract-offer';
1211
import { PolicyCardBuilder } from 'src/app/shared/models/policy/policy-card-builder';
1312
import { JsonDialogData } from '../../json-dialog/json-dialog/json-dialog.data';
1413
import { JsonDialogComponent } from '../../json-dialog/json-dialog/json-dialog.component'
@@ -218,9 +217,13 @@ export class ContractOffersViewerComponent {
218217
if (finishedNegotiationStates.includes(updatedNegotiation.state)) {
219218
let offerId = negotiation.offerId;
220219
this.runningNegotiations.delete(offerId);
220+
const errorDetail = updatedNegotiation.optionalValue("edc", "errorDetail");
221221
if (updatedNegotiation["state"] === "VERIFIED" || updatedNegotiation["state"] === "FINALIZED") {
222222
this.finishedNegotiations.set(offerId, updatedNegotiation);
223223
this.notificationService.showInfo("Contract Negotiation complete!");
224+
} else if (updatedNegotiation["state"] === "TERMINATED" && typeof errorDetail === 'string' && errorDetail.includes("Contract offer is not valid")) {
225+
this.finishedNegotiations.set(offerId, updatedNegotiation);
226+
this.notificationService.showError("Contract offer is not valid.");
224227
}
225228
}
226229

src/app/pages/contract-definitions/contract-definition-new/contract-definition-new.component.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Component, Inject, OnInit } from '@angular/core';
2-
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
1+
import { Component, OnInit } from '@angular/core';
32
import { AssetService } from "../../../shared/services/asset.service";
43
import { PolicyService } from "../../../shared/services/policy.service";
54
import { Asset, PolicyDefinition, ContractDefinitionInput } from "../../../shared/models/edc-connector-entities";

0 commit comments

Comments
 (0)