Skip to content
Snippets Groups Projects
Commit a8cc5f76 authored by Kawtar Laariche's avatar Kawtar Laariche
Browse files

#22: :recycle: upload license profile component to be reusable for uploading protobuf files

parent 5966210a
No related branches found
No related tags found
No related merge requests found
...@@ -8,97 +8,16 @@ ...@@ -8,97 +8,16 @@
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div style="display: flex; flex-direction: column; margin: 40px; width: 100%"> <div style="display: flex; flex-direction: column; margin: 40px; width: 100%">
<div></div>
<mat-divider></mat-divider>
<div style="display: flex; flex-direction: column; width: 100%"> <div style="display: flex; flex-direction: column; width: 100%">
<mat-divider></mat-divider>
<!-- on boarding--> <!-- on boarding-->
<div> <div>
<gp-headline <gp-headline
[headlineTitle]="'ON-BOARD DOCKERIZED MODEL URI'" [headlineTitle]="'ON-BOARD DOCKERIZED MODEL URI'"
></gp-headline> ></gp-headline>
</div> </div>
<!--process model-->
<div>
@if (solutionTrackId) {
<mat-list role="list" style="display: flex">
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span
class="image-content micro-service-process-completed"
alt=""
title=""
></span>
<span>Create solution</span>
</div></mat-list-item
>
<mat-list-item
><span class="progress-status progress-status-completed"></span
></mat-list-item>
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span
class="image-content add-repository-completed"
alt="Add Artifacts"
title="Add Artifacts"
></span>
<span>Add Artifacts </span>
</div></mat-list-item
>
<mat-list-item
><span class="progress-status progress-status-completed"></span
></mat-list-item>
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span
class="image-content onboarded-completed"
alt="Onboarding status"
title="Onboarding status"
></span>
<button>View model</button>
<span>Model is on-boarded and available in Private catalog </span>
</div></mat-list-item
>
</mat-list>
} @else {
<mat-list role="list" style="display: flex">
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span class="image-content micro-service" alt="" title=""></span>
<span>Create solution</span>
</div></mat-list-item
>
<mat-list-item
><span class="progress-status process-status-not-yet-started"></span
></mat-list-item>
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span
class="image-content add-repository"
alt="Add Artifacts"
title="Add Artifacts"
></span>
<span>Add Artifacts </span>
</div></mat-list-item
>
<mat-list-item
><span class="progress-status process-status-not-yet-started"></span
></mat-list-item>
<mat-list-item role="listitem"
><div style="display: flex; flex-direction: column">
<span
class="image-content not-yet-onboarded"
alt="Not yet on-boarded"
title="Not yet on-boarded"
></span>
<span>Not yet on-boarded </span>
</div></mat-list-item
>
</mat-list>
}
</div>
<div style="display: flex"> <div style="display: flex">
<div style="display: flex; flex-direction: column; width: 100%"> <div style="display: flex; flex-direction: column; width: 100%">
<!-- onboarding model form--> <!-- onboarding model form-->
...@@ -154,6 +73,7 @@ ...@@ -154,6 +73,7 @@
<div style="display: flex; flex-direction: column; width: 100%"> <div style="display: flex; flex-direction: column; width: 100%">
<mat-label>Upload Protobuf File </mat-label> <mat-label>Upload Protobuf File </mat-label>
<div style="display: flex; width: 100%; gap: 10px"> <div style="display: flex; width: 100%; gap: 10px">
<mat-form-field style="height: 70px"> <mat-form-field style="height: 70px">
<input matInput [value]="fileName" /> <input matInput [value]="fileName" />
<mat-hint class="modal-note full-width no-padding"> <mat-hint class="modal-note full-width no-padding">
...@@ -175,7 +95,7 @@ ...@@ -175,7 +95,7 @@
style="height: 48px" style="height: 48px"
color="primary" color="primary"
mat-raised-button mat-raised-button
(click)="uploadFile()" (click)="onClickUploadProtoBufFile()"
> >
Upload file Upload file
</button> </button>
...@@ -183,13 +103,7 @@ ...@@ -183,13 +103,7 @@
@if (message !== "") { @if (message !== "") {
<span class="modal-error">.proto file is required.</span> <span class="modal-error">.proto file is required.</span>
} }
<!-- @if (
onboardingModelForm.controls["protobufFile"].errors?.[
"required"
] && onboardingModelForm.controls["protobufFile"].touched
) {
<span class="modal-error">.proto file is required.</span>
} -->
</div> </div>
<!--license profile--> <!--license profile-->
<div style="display: flex; flex-direction: column"> <div style="display: flex; flex-direction: column">
...@@ -200,21 +114,13 @@ ...@@ -200,21 +114,13 @@
>Add License Profile</mat-checkbox >Add License Profile</mat-checkbox
> >
<!-- <mat-radio-group color="primary">
<mat-radio-button value="auto" (click)="onCreateLicenseProfile()"
>Create license profile</mat-radio-button
>
<mat-radio-button
value="always"
(click)="onClickUploadLicenseProfile()"
>Upload license profile</mat-radio-button
>
</mat-radio-group> -->
</div> </div>
@if ( @if (
onboardingModelForm.controls["addLicenseProfile"].value === true onboardingModelForm.controls["addLicenseProfile"].value === true
) { ) {
<gp-model-details-license-profile></gp-model-details-license-profile>
<gp-model-details-license-profile [isExistingLicenseProfile]="false" ></gp-model-details-license-profile>
} }
<div style="display: flex"> <div style="display: flex">
...@@ -223,6 +129,7 @@ ...@@ -223,6 +129,7 @@
mat-raised-button mat-raised-button
color="primary" color="primary"
[disabled]="!enableSubmit" [disabled]="!enableSubmit"
(click)="onClickBoardModel()"
> >
On-board model On-board model
</button> </button>
......
...@@ -29,6 +29,9 @@ import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.s ...@@ -29,6 +29,9 @@ import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.s
import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service'; import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service';
import { Observable, Subject, Subscription, map, takeUntil } from 'rxjs'; import { Observable, Subject, Subscription, map, takeUntil } from 'rxjs';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
import { Router } from '@angular/router';
import { ConfirmActionComponent } from 'src/app/shared/components/confirm-action/confirm-action.component';
import { MessageStatusModel } from 'src/app/shared/models/message-status.model';
@Component({ @Component({
selector: 'gp-on-boarding-model', selector: 'gp-on-boarding-model',
...@@ -66,6 +69,8 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -66,6 +69,8 @@ export class OnBoardingModelComponent implements OnInit {
private onDestroy = new Subject<void>(); private onDestroy = new Subject<void>();
private subscription: Subscription = new Subscription(); private subscription: Subscription = new Subscription();
modelLicense: LicenseProfileModel | null = null; modelLicense: LicenseProfileModel | null = null;
userId!: string;
messageStatuses!: MessageStatusModel[];
constructor( constructor(
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
...@@ -74,16 +79,15 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -74,16 +79,15 @@ export class OnBoardingModelComponent implements OnInit {
private alertService: AlertService, private alertService: AlertService,
private privateCatalogsService: PrivateCatalogsService, private privateCatalogsService: PrivateCatalogsService,
private browserStorageService: BrowserStorageService, private browserStorageService: BrowserStorageService,
private router: Router,
) { ) {
this.onboardingModelForm = this.formBuilder.group({ this.onboardingModelForm = this.formBuilder.group({
name: [ name: [
'', '',
[ [
Validators.required, Validators.required,
Validators.pattern('^(?=.*[a-z])[A-Za-z0-9]+[-.][A-Za-z0-9]+$'), Validators.pattern('^(?=.*[a-z])[a-z0-9]+[-.][a-z0-9]+$'),
// this.notSameAsPublisher(this.publisherName),
], ],
// [],
], ],
dockerURI: ['', [Validators.required]], dockerURI: ['', [Validators.required]],
protobufFile: [null, [Validators.required]], protobufFile: [null, [Validators.required]],
...@@ -118,6 +122,12 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -118,6 +122,12 @@ export class OnBoardingModelComponent implements OnInit {
.subscribe(() => { .subscribe(() => {
this.checkFormValidity(); this.checkFormValidity();
}); });
this.subscription.add(
this.browserStorageService.getUserDetails().subscribe((details) => {
this.userId = details?.userId ?? '';
}),
);
} }
checkFormValidity() { checkFormValidity() {
...@@ -126,7 +136,7 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -126,7 +136,7 @@ export class OnBoardingModelComponent implements OnInit {
console.log({ protobufFile }); console.log({ protobufFile });
if (!addLicenseProfile) { if (!addLicenseProfile) {
console.log('currentFile', this.currentFile); console.log('currentFile', this.currentFile);
this.enableSubmit = name && dockerURI && protobufFile; this.enableSubmit = name && dockerURI && this.currentFile;
} else { } else {
this.enableSubmit = this.enableSubmit =
name && dockerURI && this.currentFile && this.modelLicense; name && dockerURI && this.currentFile && this.modelLicense;
...@@ -231,6 +241,8 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -231,6 +241,8 @@ export class OnBoardingModelComponent implements OnInit {
resetData() { resetData() {
this.onboardingModelForm.reset(); this.onboardingModelForm.reset();
this.sharedDataService.licenseProfile = null; this.sharedDataService.licenseProfile = null;
this.currentFile = undefined;
this.fileName = 'No chosen file';
} }
processEvent(event: any): void { processEvent(event: any): void {
...@@ -247,16 +259,87 @@ export class OnBoardingModelComponent implements OnInit { ...@@ -247,16 +259,87 @@ export class OnBoardingModelComponent implements OnInit {
this.alertService.notify(alert, 5000); this.alertService.notify(alert, 5000);
} }
private handleUploadError(error: any) { async onClickUploadProtoBufFile() {
// Error handling logic here const dialogRef: MatDialogRef<UploadLicenseProfileComponent> =
this.modelUploadError = true; this.dialog.open(UploadLicenseProfileComponent, {
if (error) { data: {
this.modelUploadErrorMsg = [error]; dataKey: {
} else if (error.error) { title: 'Upload Protobuf File',
const messageError = error.error.response_detail ?? error.error; isEditMode: false,
this.modelUploadErrorMsg = [messageError]; isCheckExtension: true,
} expectedExtension: 'proto',
errorMessage: '.proto file is required.',
supportedFileText: 'Supported files type: .proto',
action: (file: File) => {
this.currentFile = file;
this.fileName = file.name;
return this.privateCatalogsService.uploadProtoBufFile(file);
},
isLicenseProfile: false,
isProcessEvent: false,
},
},
});
dialogRef.afterClosed().subscribe((result) => {
// This will be executed when the dialog is closed
// Reload data to fetch the updated license profile
this.checkFormValidity();
});
}
async vieModel() {
this.router.navigate(['/dashboard/myModels']);
}
// Additional error handling onClickBoardModel() {
if (this.enableSubmit) {
this.privateCatalogsService
.addCatalog(
this.userId,
this.onboardingModelForm.value.name,
this.onboardingModelForm.value.dockerURI,
)
.subscribe({
next: (res) => {
console.log({ res });
this.solutionTrackId = res;
const alert: Alert = {
message:
'On-boarding process has started and it will take a few seconds to reflect the change in status.',
type: AlertType.Info,
};
this.alertService.notify(alert, 5000);
this.privateCatalogsService
.getMessagingStatus(this.userId, this.solutionTrackId)
.subscribe({
next: (resp) => {
console.log({ resp });
this.messageStatuses = resp;
if (resp) {
const dialogRef: MatDialogRef<ConfirmActionComponent> =
this.dialog.open(ConfirmActionComponent, {
data: {
dataKey: {
title: 'View model',
content: 'Model successfully onboarded',
secondAction: 'View model',
action: () => this.vieModel,
},
},
autoFocus: false,
});
dialogRef.afterClosed().subscribe((result) => {
this.resetData();
});
}
},
error: (error) => {},
});
},
error: (error) => {},
});
}
} }
} }
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
[item]="item" [item]="item"
[items]="publicSolutions" [items]="publicSolutions"
[isMarketPlacePage]="true" [isMarketPlacePage]="true"
[isPublishedSolution]="true"
*ngFor="let item of publicSolutions" *ngFor="let item of publicSolutions"
></gp-list-item> ></gp-list-item>
</div> </div>
...@@ -91,6 +92,7 @@ ...@@ -91,6 +92,7 @@
<mat-grid-tile *ngFor="let item of publicSolutions"> <mat-grid-tile *ngFor="let item of publicSolutions">
<div class="cards-container"> <div class="cards-container">
<gp-card-item <gp-card-item
[isPublishedSolution]="true"
[item]="item" [item]="item"
[items]="publicSolutions" [items]="publicSolutions"
[isMarketPlacePage]="true" [isMarketPlacePage]="true"
......
...@@ -24,6 +24,8 @@ export class AlertComponent { ...@@ -24,6 +24,8 @@ export class AlertComponent {
return 'error_outline'; return 'error_outline';
case AlertType.Success: case AlertType.Success:
return 'check_circle_outline'; return 'check_circle_outline';
case AlertType.Info:
return 'info_outline';
default: default:
return null; return null;
} }
......
...@@ -6,8 +6,6 @@ import { PublicSolutionsService } from '../../../core/services/public-solutions. ...@@ -6,8 +6,6 @@ import { PublicSolutionsService } from '../../../core/services/public-solutions.
import { CardItemComponent } from '../card-item/card-item.component'; import { CardItemComponent } from '../card-item/card-item.component';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { UploadLicenseProfileComponent } from '../upload-license-profile/upload-license-profile.component';
import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service'; import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service';
import { PublicSolution } from '../../models'; import { PublicSolution } from '../../models';
import { Observable, Subscription, map, take } from 'rxjs'; import { Observable, Subscription, map, take } from 'rxjs';
......
import { ChangeDetectorRef, Component, Input } from '@angular/core'; import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service'; import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service';
import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service'; import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Observable, Subscription, map } from 'rxjs'; import { Observable, Subscription, map, throwError } from 'rxjs';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { CreateEditLicenseProfileComponent } from '../create-edit-license-profile/create-edit-license-profile.component'; import { CreateEditLicenseProfileComponent } from '../create-edit-license-profile/create-edit-license-profile.component';
import { UploadLicenseProfileComponent } from '../upload-license-profile/upload-license-profile.component'; import { UploadLicenseProfileComponent } from '../upload-license-profile/upload-license-profile.component';
import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service'; import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service';
import { LicenseProfileModel } from '../../models'; import { LicenseProfileModel } from '../../models';
import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
@Component({ @Component({
selector: 'gp-model-details-license-profile', selector: 'gp-model-details-license-profile',
...@@ -18,7 +19,8 @@ import { LicenseProfileModel } from '../../models'; ...@@ -18,7 +19,8 @@ import { LicenseProfileModel } from '../../models';
templateUrl: './model-details-license-profile.component.html', templateUrl: './model-details-license-profile.component.html',
styleUrl: './model-details-license-profile.component.scss', styleUrl: './model-details-license-profile.component.scss',
}) })
export class ModelDetailsLicenseProfileComponent { export class ModelDetailsLicenseProfileComponent implements OnInit {
@Input() isExistingLicenseProfile: boolean = true;
modelLicense: LicenseProfileModel | null = null; modelLicense: LicenseProfileModel | null = null;
isLicenseFound = false; isLicenseFound = false;
isLoadingLicense = true; isLoadingLicense = true;
...@@ -29,11 +31,16 @@ export class ModelDetailsLicenseProfileComponent { ...@@ -29,11 +31,16 @@ export class ModelDetailsLicenseProfileComponent {
versionId: string = ''; versionId: string = '';
versionIdSubscription: Subscription | undefined; versionIdSubscription: Subscription | undefined;
isUserIdAvailable$: Observable<boolean | undefined>; isUserIdAvailable$: Observable<boolean | undefined>;
userId$: Observable<string | undefined>;
userId!: string;
private subscription: Subscription = new Subscription(); private subscription: Subscription = new Subscription();
private destroy$: Subscription = new Subscription();
constructor( constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private publicSolutionsService: PublicSolutionsService, private publicSolutionsService: PublicSolutionsService,
private privateCatalogsService: PrivateCatalogsService,
protected sharedDataService: SharedDataService, protected sharedDataService: SharedDataService,
public dialog: MatDialog, public dialog: MatDialog,
private browserStorageService: BrowserStorageService, private browserStorageService: BrowserStorageService,
...@@ -42,6 +49,9 @@ export class ModelDetailsLicenseProfileComponent { ...@@ -42,6 +49,9 @@ export class ModelDetailsLicenseProfileComponent {
this.isUserIdAvailable$ = this.browserStorageService this.isUserIdAvailable$ = this.browserStorageService
.getUserDetails() .getUserDetails()
.pipe(map((details) => !!details?.userId)); .pipe(map((details) => !!details?.userId));
this.userId$ = this.browserStorageService
.getUserDetails()
.pipe(map((details) => details?.userId));
} }
ngOnInit() { ngOnInit() {
...@@ -58,6 +68,11 @@ export class ModelDetailsLicenseProfileComponent { ...@@ -58,6 +68,11 @@ export class ModelDetailsLicenseProfileComponent {
} }
}), }),
); );
this.subscription.add(
this.browserStorageService.getUserDetails().subscribe((details) => {
this.userId = details?.userId ?? '';
}),
);
this.activatedRoute.parent?.paramMap.subscribe((paramMap) => { this.activatedRoute.parent?.paramMap.subscribe((paramMap) => {
this.solutionId = paramMap.get('solutionId') || ''; this.solutionId = paramMap.get('solutionId') || '';
this.revisionId = paramMap.get('revisionId') || ''; this.revisionId = paramMap.get('revisionId') || '';
...@@ -157,14 +172,39 @@ export class ModelDetailsLicenseProfileComponent { ...@@ -157,14 +172,39 @@ export class ModelDetailsLicenseProfileComponent {
}); });
} }
uploadExistingLicenseFile(file: File): Observable<any> {
return this.privateCatalogsService.uploadExistingModelLicenseProfile(
this.userId,
this.solutionId,
this.revisionId,
this.versionId,
file,
);
}
uploadNewLicenseFile(file: File) {
return this.privateCatalogsService.uploadNewModelLicenseProfile(
this.userId,
file,
);
}
onClickUpload() { onClickUpload() {
const dialogRef: MatDialogRef<UploadLicenseProfileComponent> = const dialogRef: MatDialogRef<UploadLicenseProfileComponent> =
this.dialog.open(UploadLicenseProfileComponent, { this.dialog.open(UploadLicenseProfileComponent, {
data: { data: {
dataKey: { dataKey: {
isEditMode: false, isEditMode: false,
solutionId: this.solutionId, title: 'Upload License file',
revisionId: this.revisionId, errorMessage:
'Please update the license profile to correct the following validation errors:',
supportedFileText:
'Maximum file size: 1mb | Supported file type: .json',
action: (file: File) =>
this.isExistingLicenseProfile
? this.uploadExistingLicenseFile(file)
: this.uploadNewLicenseFile(file),
isLicenseProfile: true,
isProcessEvent: true,
}, },
}, },
}); });
......
<div class="dialog-header"> <div class="dialog-header">
<h2 mat-dialog-title>Upload License file</h2> <h2 mat-dialog-title>{{title}}</h2>
<button <button
type="button" type="button"
mat-icon-button mat-icon-button
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
></mat-progress-bar> ></mat-progress-bar>
</div> </div>
<div <div
style=" style="
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -81,15 +82,14 @@ ...@@ -81,15 +82,14 @@
<div *ngIf="file && file.size / 1024 / 1024 > 1"> <div *ngIf="file && file.size / 1024 / 1024 > 1">
<span>License file should be max size of 1MB.</span> <span>License file should be max size of 1MB.</span>
</div> </div>
<small>Maximum file size: 1mb | Supported file type: .json</small> <small>{{supportedFileText}}</small>
<div class="upload-error"> <div class="upload-error">
<small *ngIf="modelUploadError"> <small *ngIf="modelUploadError">
<strong <strong *ngIf="errorMessage"
>Please update the license profile to correct the following validation >{{errorMessage}}</strong
errors:</strong
> >
<dl> <dl *ngIf="!(modelUploadErrorMsg.length === 1 && modelUploadErrorMsg[0] === errorMessage )">
<li *ngFor="let error of modelUploadErrorMsg">{{ error }}</li> <li *ngFor="let error of modelUploadErrorMsg">{{ error }}</li>
</dl> </dl>
</small> </small>
......
...@@ -9,7 +9,11 @@ import { ...@@ -9,7 +9,11 @@ import {
} from '@angular/core'; } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import {
MAT_DIALOG_DATA,
MatDialogModule,
MatDialogRef,
} from '@angular/material/dialog';
import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
...@@ -58,8 +62,6 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -58,8 +62,6 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
filename: string | null = null; filename: string | null = null;
progressBar = 0; progressBar = 0;
modelUploadError: boolean = false; modelUploadError: boolean = false;
@Input() solutionId: string = '';
@Input() revisionId: string = '';
versionId: string = ''; versionId: string = '';
versionIdSubscription: Subscription | undefined; versionIdSubscription: Subscription | undefined;
modelLicense!: LicenseProfileModel; modelLicense!: LicenseProfileModel;
...@@ -71,13 +73,23 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -71,13 +73,23 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
userId$: Observable<string | undefined>; userId$: Observable<string | undefined>;
licenseProfile!: LicenseProfileModel; licenseProfile!: LicenseProfileModel;
private onDestroy = new Subject<void>(); private onDestroy = new Subject<void>();
alertSuccessMessage!: string;
alertErrorMessage!: string;
alertType!: AlertType;
isLicenseProfile!: boolean;
isCheckExtension!: boolean;
expectedExtension!: string;
errorMessage!: string;
supportedFileText!: string;
title!: string;
isProcessEvent!: boolean;
constructor( constructor(
private alertService: AlertService, private alertService: AlertService,
private privateCatalogsService: PrivateCatalogsService,
private browserStorageService: BrowserStorageService, private browserStorageService: BrowserStorageService,
private sharedDataService: SharedDataService, private sharedDataService: SharedDataService,
@Inject(MAT_DIALOG_DATA) public data: any, @Inject(MAT_DIALOG_DATA) public data: any,
public dialogRef: MatDialogRef<UploadLicenseProfileComponent>,
) { ) {
this.userId$ = this.browserStorageService this.userId$ = this.browserStorageService
.getUserDetails() .getUserDetails()
...@@ -94,9 +106,15 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -94,9 +106,15 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
this.versionIdSubscription.unsubscribe(); this.versionIdSubscription.unsubscribe();
} }
} }
ngOnInit(): void { ngOnInit(): void {
this.solutionId = this.data.dataKey.solutionId; this.isLicenseProfile = this.data.dataKey.isLicenseProfile;
this.revisionId = this.data.dataKey.revisionId; this.isCheckExtension = this.data.dataKey.isCheckExtension;
this.expectedExtension = this.data.dataKey.expectedExtension;
this.errorMessage = this.data.dataKey.errorMessage;
this.supportedFileText = this.data.dataKey.supportedFileText;
this.title = this.data.dataKey.title;
this.isProcessEvent = this.data.dataKey.isProcessEvent;
// Get the initial version ID // Get the initial version ID
this.versionId = this.sharedDataService.versionId; this.versionId = this.sharedDataService.versionId;
...@@ -108,56 +126,23 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -108,56 +126,23 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
}, },
); );
} }
uploadFile(file: File) {
if (this.isCheckExtension) {
const fileExtension = this.getFilenameExtension(file.name);
if (fileExtension !== this.expectedExtension) {
this.handleUploadError(this.errorMessage);
uploadLicenseFile(): void { return; // Stop further execution
event?.preventDefault(); }
combineLatest([this.userId$, of(this.file)]) }
.pipe( this.data.dataKey.action(file).subscribe({
filter(([userId, file]) => !!userId && !!file), next: (event: any) => {
switchMap(([userId, file]) => { this.processEvent(event);
if ( },
userId && error: (err: any) => {
file && this.handleUploadError(err);
this.versionId && },
this.solutionId && });
this.versionId
) {
return this.privateCatalogsService.uploadExistingModelLicenseProfile(
userId,
this.solutionId,
this.revisionId,
this.versionId,
file,
);
} else if (
userId &&
file &&
!this.versionId &&
!this.solutionId &&
!this.versionId
) {
return this.privateCatalogsService.uploadNewModelLicenseProfile(
userId,
file,
);
} else {
return throwError(() => new Error('Missing user ID or file'));
}
}),
takeUntil(this.onDestroy),
catchError((error) => {
console.error('Upload failed', error);
this.handleUploadError(error.error);
// Handle the error and continue
return of(null);
}),
finalize(() => this.resetProgress()),
)
.subscribe({
next: (event) => this.processEvent(event),
error: (error) => {}, // To catch any errors not caught by catchError
complete: () => {},
});
} }
processEvent(event: any): void { processEvent(event: any): void {
...@@ -165,29 +150,30 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -165,29 +150,30 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
this.progressBarValue = Math.round((100 * event.loaded) / event.total); this.progressBarValue = Math.round((100 * event.loaded) / event.total);
} else if (event && event.type === HttpEventType.Response) { } else if (event && event.type === HttpEventType.Response) {
this.handleUploadSuccess(event.body); this.handleUploadSuccess(event.body);
this.sharedDataService.licenseProfile = this.licenseProfile; if (this.isLicenseProfile)
this.sharedDataService.licenseProfile = this.licenseProfile;
} }
} }
private handleUploadSuccess(response: any) { private handleUploadSuccess(response: any) {
const alert: Alert = { const alert: Alert = {
message: 'License uploaded successfully', message: 'File uploaded successfully',
type: AlertType.Success, type: AlertType.Success,
}; };
this.alertService.notify(alert, 5000); this.alertService.notify(alert, 5000);
this.dialogRef.close(true);
} }
private handleUploadError(error: any) { private handleUploadError(error: any) {
console.log({ error });
// Error handling logic here // Error handling logic here
this.modelUploadError = true; this.modelUploadError = true;
if (error) { if (error.error) {
this.modelUploadErrorMsg = [error];
} else if (error.error) {
const messageError = error.error.response_detail ?? error.error; const messageError = error.error.response_detail ?? error.error;
this.modelUploadErrorMsg = [messageError]; this.modelUploadErrorMsg = [messageError];
} else {
this.modelUploadErrorMsg = [error];
} }
// Additional error handling
} }
// Function to reset progress // Function to reset progress
...@@ -202,16 +188,17 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -202,16 +188,17 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
readFile(file: File) { readFile(file: File) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = () => { if (this.isLicenseProfile)
try { reader.onload = () => {
this.licenseProfile = JSON.parse(reader.result as string); try {
console.log('License Profile Loaded:', this.licenseProfile); this.licenseProfile = JSON.parse(reader.result as string);
// Proceed with any operations now that the license profile is loaded console.log('License Profile Loaded:', this.licenseProfile);
} catch (e) { // Proceed with any operations now that the license profile is loaded
console.error('Error parsing the license profile:', e); } catch (e) {
// Handle errors in reading or parsing the file console.error('Error parsing the license profile:', e);
} // Handle errors in reading or parsing the file
}; }
};
reader.onerror = () => { reader.onerror = () => {
console.error('Error reading the file:', reader.error); console.error('Error reading the file:', reader.error);
}; };
...@@ -233,7 +220,7 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -233,7 +220,7 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
if (this.file.size / 1024 / 1024 < 1) { if (this.file.size / 1024 / 1024 < 1) {
this.fileSize = Math.ceil(file.size / 1024); this.fileSize = Math.ceil(file.size / 1024);
} }
this.uploadLicenseFile(); this.uploadFile(this.file);
} }
} }
...@@ -242,4 +229,17 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy { ...@@ -242,4 +229,17 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
this.modelUploadErrorMsg = []; this.modelUploadErrorMsg = [];
this.modelUploadError = false; this.modelUploadError = false;
} }
getFilenameExtension(filename: string): string {
// Split the filename by dot (.) and get the last element of the array
const parts = filename.split('.');
return parts[parts.length - 1];
}
idCheckExtensionValid(
fileExtension: string,
expectedExtension: string,
): boolean {
return fileExtension === expectedExtension;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment