From c7aabdd65a8355b6a948e2851885ebfd058f8e37 Mon Sep 17 00:00:00 2001
From: kaw67872 <kawtar.laariche@iais.fraunhofer.de>
Date: Mon, 27 May 2024 16:33:46 +0200
Subject: [PATCH] #22: implement onboarding page

---
 src/app/core/config/api-config.ts             |   2 +
 .../shared-data/shared-data.service.ts        |  26 +-
 .../on-boarding-model.component.html          | 237 +++++++++++++++-
 .../on-boarding-model.component.scss          | 121 +++++++++
 .../on-boarding-model.component.ts            | 257 +++++++++++++++++-
 .../local-login/local-login.component.ts      |   2 +-
 .../marketplace/marketplace.component.html    |   4 +-
 .../marketplace/marketplace.component.ts      |   2 +
 .../model-details.component.html              |   4 +-
 .../breadcrumb-navigation.component.html      |  38 ++-
 .../breadcrumb-navigation.component.scss      |   4 +
 .../breadcrumb-navigation.component.ts        |   6 +-
 .../create-edit-license-profile.component.ts  |   2 +
 ...er-dialog-confirmation-action.component.ts |   4 +-
 .../headline/headline.component.html          |   3 +
 .../headline/headline.component.scss          |  14 +
 .../headline/headline.component.spec.ts       |  23 ++
 .../components/headline/headline.component.ts |  13 +
 .../components/home/home.component.html       |   1 -
 .../shared/components/home/home.component.ts  |   8 -
 ...del-details-license-profile.component.html |   7 +-
 ...model-details-license-profile.component.ts |  21 +-
 .../model-management.component.html           |   4 +-
 .../upload-license-profile.component.html     |   6 -
 .../upload-license-profile.component.ts       |  88 ++++--
 src/app/shared/models/index.ts                |   1 +
 src/app/shared/models/message-status.model.ts |  15 +
 .../shared/models/navigation-label.model.ts   |   4 +
 src/assets/images/ico-checkmark.png           | Bin 0 -> 1159 bytes
 src/assets/images/ico_add_to_repository.png   | Bin 0 -> 1685 bytes
 .../images/ico_add_to_repository_green.png    | Bin 0 -> 1693 bytes
 .../images/ico_add_to_repository_red.png      | Bin 0 -> 2155 bytes
 .../images/ico_create_micro_service.png       | Bin 0 -> 1003 bytes
 .../images/ico_create_micro_service_green.png | Bin 0 -> 983 bytes
 .../images/ico_create_micro_service_red.png   | Bin 0 -> 1460 bytes
 src/assets/images/ico_not_yet_onboarded.png   | Bin 0 -> 1526 bytes
 src/assets/images/loading_deactive.png        | Bin 0 -> 620 bytes
 .../images/stepper_progress_completed.png     | Bin 0 -> 1302 bytes
 38 files changed, 835 insertions(+), 82 deletions(-)
 create mode 100644 src/app/shared/components/headline/headline.component.html
 create mode 100644 src/app/shared/components/headline/headline.component.scss
 create mode 100644 src/app/shared/components/headline/headline.component.spec.ts
 create mode 100644 src/app/shared/components/headline/headline.component.ts
 create mode 100644 src/app/shared/models/message-status.model.ts
 create mode 100644 src/app/shared/models/navigation-label.model.ts
 create mode 100644 src/assets/images/ico-checkmark.png
 create mode 100644 src/assets/images/ico_add_to_repository.png
 create mode 100644 src/assets/images/ico_add_to_repository_green.png
 create mode 100644 src/assets/images/ico_add_to_repository_red.png
 create mode 100644 src/assets/images/ico_create_micro_service.png
 create mode 100644 src/assets/images/ico_create_micro_service_green.png
 create mode 100644 src/assets/images/ico_create_micro_service_red.png
 create mode 100644 src/assets/images/ico_not_yet_onboarded.png
 create mode 100644 src/assets/images/loading_deactive.png
 create mode 100644 src/assets/images/stepper_progress_completed.png

diff --git a/src/app/core/config/api-config.ts b/src/app/core/config/api-config.ts
index b2da3f1..01952b4 100644
--- a/src/app/core/config/api-config.ts
+++ b/src/app/core/config/api-config.ts
@@ -55,4 +55,6 @@ export const apiConfig = {
   urlComment: '/api/comments',
   urlGetActiveUsers: '/api/users/activeUserDetails',
   urlShareWithTeam: '/api/solution/userAccess',
+  urlAddToCatalog: '/api/webBasedOnBoarding/addToCatalog',
+  urlMessagingStatus: '/api/webBasedOnBoarding/messagingStatus',
 };
diff --git a/src/app/core/services/shared-data/shared-data.service.ts b/src/app/core/services/shared-data/shared-data.service.ts
index 8cf26e5..bc50def 100644
--- a/src/app/core/services/shared-data/shared-data.service.ts
+++ b/src/app/core/services/shared-data/shared-data.service.ts
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
 import { BehaviorSubject, Observable } from 'rxjs';
 import {
   AuthorPublisherModel,
+  LicenseProfileModel,
   PublicSolution,
   Revision,
 } from 'src/app/shared/models';
@@ -47,19 +48,20 @@ export class SharedDataService {
   private _authorListSubject: BehaviorSubject<AuthorPublisherModel[]> =
     new BehaviorSubject<AuthorPublisherModel[]>([]);
 
-  private _selectedRevisionSubject: BehaviorSubject<{
-    version: string;
-    revisionId: string;
-  }> = new BehaviorSubject<Revision>({
-    version: '',
-    revisionId: '',
-    onBoarded: '',
-  });
+  private _selectedRevisionSubject: BehaviorSubject<Revision> =
+    new BehaviorSubject<Revision>({
+      version: '',
+      revisionId: '',
+      onBoarded: '',
+    });
 
   private _ratingSubject: BehaviorSubject<number> = new BehaviorSubject<number>(
     0,
   );
 
+  private _licenseProfileSubject =
+    new BehaviorSubject<LicenseProfileModel | null>(null);
+
   constructor() {}
 
   get versionId$(): Observable<string> {
@@ -117,4 +119,12 @@ export class SharedDataService {
   set rating(value: number) {
     this._ratingSubject.next(value);
   }
+
+  get licenseProfile$(): Observable<LicenseProfileModel | null> {
+    return this._licenseProfileSubject.asObservable();
+  }
+
+  set licenseProfile(value: LicenseProfileModel | null) {
+    this._licenseProfileSubject.next(value);
+  }
 }
diff --git a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.html b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.html
index b19248e..d2fb782 100644
--- a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.html
+++ b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.html
@@ -1 +1,236 @@
-<p>on-boarding-model works!</p>
+<div style="display: flex; flex-direction: column; margin: 40px">
+  <gp-headline [headlineTitle]="'On-Boarding Model'"></gp-headline>
+  <gp-breadcrumb-navigation
+    [firstNavigationLabel]="{ label: 'Home' }"
+    [secondNavigationLabel]="{ label: 'On-Boarding Model', disabled: true }"
+    (firstNavigationClicked)="onHomeClick()"
+  ></gp-breadcrumb-navigation>
+</div>
+<mat-divider></mat-divider>
+<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%">
+    <mat-divider></mat-divider>
+    <!-- on boarding-->
+    <div>
+      <gp-headline
+        [headlineTitle]="'ON-BOARD DOCKERIZED MODEL URI'"
+      ></gp-headline>
+    </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; flex-direction: column; width: 100%">
+        <!-- onboarding model form-->
+        <form style="width: 100" [formGroup]="onboardingModelForm">
+          <!--model name-->
+          <div style="display: flex; flex-direction: column">
+            <mat-label>Model name</mat-label>
+            <mat-form-field>
+              <input matInput formControlName="name" />
+              @if (
+                onboardingModelForm.controls["name"].errors?.["pattern"] &&
+                onboardingModelForm.controls["name"].touched
+              ) {
+                <mat-error class="modal-error"
+                  >Name must consist of lower case alphanumeric characters, '-'
+                  or '.', and must start and end with an alphanumeric
+                  character</mat-error
+                >
+              }
+              @if (
+                onboardingModelForm.controls["name"].errors?.["required"] &&
+                onboardingModelForm.controls["name"].touched
+              ) {
+                <mat-error class="modal-error">Name is required</mat-error>
+              }
+            </mat-form-field>
+          </div>
+          <!--docker URI-->
+          <div style="display: flex; flex-direction: column">
+            <mat-label>Docker URI </mat-label>
+            <mat-hint class="modal-note green"
+              ><strong>Dockerhub image example:</strong>
+              docker.io/myimage:latest
+            </mat-hint>
+            <mat-hint class="modal-note green"
+              ><strong>General public registry image example:</strong>
+              cicd.ai4eu-dev.eu:7444/myimage:v1
+            </mat-hint>
+            <mat-form-field>
+              <input matInput formControlName="dockerURI" />
+              @if (
+                onboardingModelForm.controls["dockerURI"].errors?.[
+                  "required"
+                ] && onboardingModelForm.controls["dockerURI"].touched
+              ) {
+                <mat-error class="modal-error"
+                  >Docker URI is required</mat-error
+                >
+              }
+            </mat-form-field>
+          </div>
+          <!--protobuf file-->
+          <div style="display: flex; flex-direction: column; width: 100%">
+            <mat-label>Upload Protobuf File </mat-label>
+            <div style="display: flex; width: 100%; gap: 10px">
+              <mat-form-field style="height: 70px">
+                <input matInput [value]="fileName" />
+                <mat-hint class="modal-note full-width no-padding">
+                  Supported files type: .proto</mat-hint
+                >
+
+                <input
+                  #fileDropRef
+                  type="file"
+                  id="fileInput"
+                  name="fileInput"
+                  (change)="selectFile($event)"
+                  hidden
+                  formControlName="protobufFile"
+                />
+              </mat-form-field>
+
+              <button
+                style="height: 48px"
+                color="primary"
+                mat-raised-button
+                (click)="uploadFile()"
+              >
+                Upload file
+              </button>
+            </div>
+            @if (message !== "") {
+              <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>
+          <!--license profile-->
+          <div style="display: flex; flex-direction: column">
+            <mat-checkbox
+              color="primary"
+              formControlName="addLicenseProfile"
+              (change)="onClickUpload($event)"
+              >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>
+          @if (
+            onboardingModelForm.controls["addLicenseProfile"].value === true
+          ) {
+            <gp-model-details-license-profile></gp-model-details-license-profile>
+          }
+
+          <div style="display: flex">
+            <button mat-raised-button (click)="resetData()">Reset form</button>
+            <button
+              mat-raised-button
+              color="primary"
+              [disabled]="!enableSubmit"
+            >
+              On-board model
+            </button>
+          </div>
+        </form>
+      </div>
+      <!--onboarding history-->
+      <div></div>
+    </div>
+  </div>
+</div>
diff --git a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.scss b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.scss
index e69de29..36effac 100644
--- a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.scss
+++ b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.scss
@@ -0,0 +1,121 @@
+.flex-column {
+  display: flex;
+  flex-direction: column;
+}
+#fileInput {
+  position: absolute;
+  cursor: pointer;
+  z-index: 10;
+  opacity: 0;
+  height: 100%;
+  left: 0px;
+  top: 0px;
+}
+.asterisk--after:after {
+  content: "*";
+  color: red;
+}
+
+.modal-error {
+  color: red;
+  font-size: 12px;
+  font-family: "Open Sans", sans-serif !important;
+  padding: 0;
+}
+
+.modal-note {
+  color: #888;
+  font-size: 12px;
+  font-family: "Open Sans", sans-serif !important;
+}
+
+.full-width {
+  width: 100%;
+}
+
+.green {
+  color: green;
+}
+::ng-deep.mat-mdc-form-field-hint-wrapper,
+::ng-deep.mat-mdc-form-field-error-wrapper {
+  padding: 0 !important;
+}
+.micro-service {
+  background-image: url(../../../../assets/images/ico_create_micro_service.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.micro-service-process-completed {
+  background-image: url(../../../../assets/images/ico_create_micro_service_green.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+/* .progress-status:after {
+  content: "" !important;
+  background: url("../../../../assets/images/loading_deactive.png") no-repeat
+    left center;
+  display: inline-block;
+  width: 45px;
+  height: 12px;
+  transform: scale(0.8);
+}
+ */
+.process-status-not-yet-started {
+  background: url("../../../../assets/images/loading_deactive.png") no-repeat
+    left center;
+}
+
+.progress-status-completed {
+  background: url("../../../../assets/images/stepper_progress_completed.png")
+    no-repeat left center;
+}
+
+.progress-status {
+  display: inline-block;
+  width: 47px;
+  height: 11px;
+  transform: scale(0.8);
+}
+
+.add-repository {
+  background-image: url(../../../../assets/images/ico_add_to_repository.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.add-repository-completed {
+  background-image: url(../../../../assets/images/ico_add_to_repository_green.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.not-yet-onboarded {
+  background-image: url(../../../../assets/images/ico_not_yet_onboarded.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.onboarded-completed {
+  background-image: url(../../../../assets/images/ico-checkmark.png);
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.image-content {
+  width: 62px;
+  height: 62px;
+  border-radius: 62px;
+
+  border: 3px solid #fff;
+  background-color: #ebebeb;
+  display: inline-block;
+  position: relative;
+  text-align: center;
+  line-height: 68px;
+}
+
+.mdc-list-item.mdc-list-item--with-one-line {
+  height: 90px;
+}
diff --git a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.ts b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.ts
index 26137a8..69ca6e2 100644
--- a/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.ts
+++ b/src/app/features/dashboard/on-boarding-model/on-boarding-model.component.ts
@@ -1,13 +1,262 @@
-import { Component } from '@angular/core';
+import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
 import { CommonModule } from '@angular/common';
+import { HeadlineComponent } from 'src/app/shared/components/headline/headline.component';
+import { BreadcrumbNavigationComponent } from 'src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component';
+import { MatDividerModule } from '@angular/material/divider';
+import {
+  FormBuilder,
+  FormGroup,
+  ReactiveFormsModule,
+  Validators,
+} from '@angular/forms';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import {
+  MatCheckboxChange,
+  MatCheckboxModule,
+} from '@angular/material/checkbox';
+import { MatButtonModule } from '@angular/material/button';
+import { UploadLicenseProfileComponent } from 'src/app/shared/components/upload-license-profile/upload-license-profile.component';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
+import { CreateEditLicenseProfileComponent } from 'src/app/shared/components/create-edit-license-profile/create-edit-license-profile.component';
+import { MatRadioModule } from '@angular/material/radio';
+import { ModelDetailsLicenseProfileComponent } from 'src/app/shared/components/model-details-license-profile/model-details-license-profile.component';
+import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service';
+import { Alert, AlertType, LicenseProfileModel } from 'src/app/shared/models';
+import { HttpEventType } from '@angular/common/http';
+import { AlertService } from 'src/app/core/services/alert.service';
+import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
+import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service';
+import { Observable, Subject, Subscription, map, takeUntil } from 'rxjs';
+import { MatListModule } from '@angular/material/list';
 
 @Component({
   selector: 'gp-on-boarding-model',
   standalone: true,
-  imports: [CommonModule],
+  imports: [
+    CommonModule,
+    HeadlineComponent,
+    BreadcrumbNavigationComponent,
+    MatDividerModule,
+    ReactiveFormsModule,
+    MatFormFieldModule,
+    MatInputModule,
+    MatCheckboxModule,
+    MatButtonModule,
+    UploadLicenseProfileComponent,
+    MatRadioModule,
+    ModelDetailsLicenseProfileComponent,
+    MatListModule,
+  ],
   templateUrl: './on-boarding-model.component.html',
-  styleUrl: './on-boarding-model.component.scss'
+  styleUrl: './on-boarding-model.component.scss',
 })
-export class OnBoardingModelComponent {
+export class OnBoardingModelComponent implements OnInit {
+  @ViewChild('fileDropRef') fileDropRef!: ElementRef<HTMLInputElement>;
+  currentFile?: File;
+  fileSize = 0;
+  message = '';
+  fileName = 'No chosen file';
+  onboardingModelForm!: FormGroup;
+  modelUploadError: boolean = false;
+  modelUploadErrorMsg: string[] = [];
+  userId$: Observable<string | undefined>;
+  solutionTrackId!: string;
+  enableSubmit: boolean = false;
+  private onDestroy = new Subject<void>();
+  private subscription: Subscription = new Subscription();
+  modelLicense: LicenseProfileModel | null = null;
 
+  constructor(
+    private formBuilder: FormBuilder,
+    private sharedDataService: SharedDataService,
+    public dialog: MatDialog,
+    private alertService: AlertService,
+    private privateCatalogsService: PrivateCatalogsService,
+    private browserStorageService: BrowserStorageService,
+  ) {
+    this.onboardingModelForm = this.formBuilder.group({
+      name: [
+        '',
+        [
+          Validators.required,
+          Validators.pattern('^(?=.*[a-z])[A-Za-z0-9]+[-.][A-Za-z0-9]+$'),
+          // this.notSameAsPublisher(this.publisherName),
+        ],
+        // [],
+      ],
+      dockerURI: ['', [Validators.required]],
+      protobufFile: [null, [Validators.required]],
+      addLicenseProfile: [false],
+      licenseProfile: [null],
+    });
+
+    this.userId$ = this.browserStorageService
+      .getUserDetails()
+      .pipe(map((details) => details?.userId));
+  }
+  ngOnInit(): void {
+    this.subscription.add(
+      this.sharedDataService.licenseProfile$.subscribe((licenseProfile) => {
+        this.modelLicense = licenseProfile;
+        this.onboardingModelForm.patchValue({
+          licenseProfile: licenseProfile,
+        });
+        /**
+         * this.cd.detectChanges();  // Manually trigger change detection
+         */
+        if (licenseProfile) {
+          console.log('License profile updated:', licenseProfile);
+        } else {
+          console.log('License profile reset to null');
+        }
+      }),
+    );
+
+    this.onboardingModelForm.valueChanges
+      .pipe(takeUntil(this.onDestroy))
+      .subscribe(() => {
+        this.checkFormValidity();
+      });
+  }
+
+  checkFormValidity() {
+    const { name, dockerURI, addLicenseProfile, protobufFile } =
+      this.onboardingModelForm.value;
+    console.log({ protobufFile });
+    if (!addLicenseProfile) {
+      console.log('currentFile', this.currentFile);
+      this.enableSubmit = name && dockerURI && protobufFile;
+    } else {
+      this.enableSubmit =
+        name && dockerURI && this.currentFile && this.modelLicense;
+    }
+  }
+
+  onHomeClick() {}
+
+  ngOnDestroy() {
+    this.onDestroy.next();
+    this.onDestroy.complete();
+  }
+
+  selectFile(event: any): void {
+    this.message = '';
+
+    if (event.target.files && event.target.files[0]) {
+      const file: File = event.target.files[0];
+      this.currentFile = file;
+      this.fileName = this.currentFile.name;
+      this.onboardingModelForm.patchValue({ protobufFile: file });
+      console.log('file info', this.currentFile);
+      const extensionFile = this.getFilenameExtension(this.fileName);
+      if (extensionFile !== 'proto') {
+        this.message = '.proto file is required.';
+      } else if (this.currentFile && extensionFile === 'proto') {
+        console.log('inside proto');
+        this.privateCatalogsService
+          .uploadProtoBufFile(this.currentFile)
+          .subscribe({
+            next: (event) => this.processEvent(event),
+            error: (error) => {}, // To catch any errors not caught by catchError
+            complete: () => {},
+          });
+      }
+    } else {
+      this.fileName = 'No chosen file';
+    }
+  }
+  /* 
+  handleFileInput(event: Event | File) {
+    let file: File | null = null;
+    if (event instanceof File) {
+      file = event;
+    } else {
+      const element = event.target as HTMLInputElement;
+      file = element.files?.[0] || null;
+    }
+    if (file) {
+      this.currentFile = file;
+      if (this.currentFile.size / 1024 / 1024 < 1) {
+        this.fileSize = Math.ceil(file.size / 1024);
+      }
+    }
+  } */
+
+  uploadFile() {
+    event?.preventDefault();
+    this.fileDropRef.nativeElement.click();
+    if (this.currentFile) {
+      console.log('current file', this.currentFile);
+      this.privateCatalogsService
+        .uploadProtoBufFile(this.currentFile)
+        .subscribe({
+          next: (event) => this.processEvent(event),
+          error: (error) => {}, // To catch any errors not caught by catchError
+          complete: () => {},
+        });
+    }
+  }
+
+  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];
+  }
+
+  onClickUpload(event: MatCheckboxChange) {}
+
+  onCreateLicenseProfile() {
+    const dialogRef: MatDialogRef<CreateEditLicenseProfileComponent> =
+      this.dialog.open(CreateEditLicenseProfileComponent, {
+        data: {
+          dataKey: {
+            isEditMode: false,
+            solutionId: '',
+            revisionId: '',
+          },
+        },
+      });
+    dialogRef.afterClosed().subscribe((result) => {
+      // This will be executed when the dialog is closed
+      // Reload data to fetch the updated license profile
+    });
+  }
+
+  onClickUploadLicenseProfile() {
+    const dialogRef: MatDialogRef<UploadLicenseProfileComponent> =
+      this.dialog.open(UploadLicenseProfileComponent);
+  }
+
+  resetData() {
+    this.onboardingModelForm.reset();
+    this.sharedDataService.licenseProfile = null;
+  }
+
+  processEvent(event: any): void {
+    if (event && event.type === HttpEventType.Response) {
+      this.handleUploadSuccess(event.body);
+    }
+  }
+
+  private handleUploadSuccess(response: any) {
+    const alert: Alert = {
+      message: 'File uploaded successfully',
+      type: AlertType.Success,
+    };
+    this.alertService.notify(alert, 5000);
+  }
+
+  private handleUploadError(error: any) {
+    // Error handling logic here
+    this.modelUploadError = true;
+    if (error) {
+      this.modelUploadErrorMsg = [error];
+    } else if (error.error) {
+      const messageError = error.error.response_detail ?? error.error;
+      this.modelUploadErrorMsg = [messageError];
+    }
+
+    // Additional error handling
+  }
 }
diff --git a/src/app/features/login/local-login/local-login.component.ts b/src/app/features/login/local-login/local-login.component.ts
index 45e4c6b..866f1d4 100644
--- a/src/app/features/login/local-login/local-login.component.ts
+++ b/src/app/features/login/local-login/local-login.component.ts
@@ -19,7 +19,7 @@ import {
 
 import { AuthService } from 'src/app/core/services/auth/auth.service';
 import { LocalLoginService } from 'src/app/core/services/auth/local-login.service';
-import { NavigationStart, Router } from '@angular/router';
+import { Router } from '@angular/router';
 import { MatButtonModule } from '@angular/material/button';
 import { MatIconModule } from '@angular/material/icon';
 import {
diff --git a/src/app/features/marketplace/marketplace.component.html b/src/app/features/marketplace/marketplace.component.html
index b40fe12..c6b476c 100644
--- a/src/app/features/marketplace/marketplace.component.html
+++ b/src/app/features/marketplace/marketplace.component.html
@@ -1,9 +1,7 @@
 <section class="pageheadsection mob-pageheadsection1">
   <div class="mdl-grid mdl-grid.mdl-grid--no-spacing">
     <div>
-      <div class="headline">
-        <span>Marketplace | </span>
-      </div>
+      <gp-headline [headlineTitle]="'Marketplace |'"></gp-headline>
       <div
         style="display: flex; flex-direction: row; align-items: center"
         *ngIf="loginUserId"
diff --git a/src/app/features/marketplace/marketplace.component.ts b/src/app/features/marketplace/marketplace.component.ts
index 069ef68..da672de 100644
--- a/src/app/features/marketplace/marketplace.component.ts
+++ b/src/app/features/marketplace/marketplace.component.ts
@@ -34,6 +34,7 @@ import { BrowserStorageService } from 'src/app/core/services/storage/browser-sto
 import { Observable, Subscription, map } from 'rxjs';
 import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
 import { MatButtonModule } from '@angular/material/button';
+import { HeadlineComponent } from 'src/app/shared/components/headline/headline.component';
 
 @Component({
   selector: 'gp-marketplace',
@@ -50,6 +51,7 @@ import { MatButtonModule } from '@angular/material/button';
     SolutionsToggleViewComponent,
     ListItemComponent,
     MatButtonModule,
+    HeadlineComponent,
   ],
   templateUrl: './marketplace.component.html',
   styleUrl: './marketplace.component.scss',
diff --git a/src/app/features/model-details/model-details.component.html b/src/app/features/model-details/model-details.component.html
index 4b6be61..92898d7 100644
--- a/src/app/features/model-details/model-details.component.html
+++ b/src/app/features/model-details/model-details.component.html
@@ -89,8 +89,8 @@
   <div class="md-head-container2" style="margin-top: 12px">
     <gp-breadcrumb-navigation
       [solution]="data.solution"
-      [firstNavigationLabel]="'Home'"
-      [secondNavigationLabel]="'MarketPlace'"
+      [firstNavigationLabel]="{ label: 'Home' }"
+      [secondNavigationLabel]="{ label: 'MarketPlace' }"
       (firstNavigationClicked)="onHomeClick()"
       (secondNavigationClicked)="onMarketPlaceClick()"
     ></gp-breadcrumb-navigation>
diff --git a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.html b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.html
index f6cb9cd..ee84a48 100644
--- a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.html
+++ b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.html
@@ -1,18 +1,26 @@
 <ul class="c-breadcrumb">
-  <li>
-    <a (click)="onFirstNavigationLabelClick()">{{ firstNavigationLabel }}</a>
-  </li>
-  <li>
-    <a (click)="onSecondNavigationClick()">{{ secondNavigationLabel }}</a>
-  </li>
-  <li>
-    <span
-      class="md-breadcrumb-item"
-      matTooltip="{{ solution?.name?.toString()?.split('_')?.join(' ') }}"
-      >{{ solution?.name?.toString()?.split("_")?.join(" ") }}</span
-    >
-  </li>
-  <li>
-    <gp-solution-id [solutionId]="solution.solutionId"></gp-solution-id>
+  <li [ariaDisabled]="firstNavigationLabel.disabled">
+    <a (click)="onFirstNavigationLabelClick()">{{
+      firstNavigationLabel.label
+    }}</a>
   </li>
+  @if (secondNavigationLabel) {
+    <li [ariaDisabled]="secondNavigationLabel.disabled">
+      <a (click)="onSecondNavigationClick()">{{
+        secondNavigationLabel.label
+      }}</a>
+    </li>
+  }
+  @if (solution) {
+    <li>
+      <span
+        class="md-breadcrumb-item"
+        matTooltip="{{ solution?.name?.toString()?.split('_')?.join(' ') }}"
+        >{{ solution?.name?.toString()?.split("_")?.join(" ") }}</span
+      >
+    </li>
+    <li>
+      <gp-solution-id [solutionId]="solution.solutionId"></gp-solution-id>
+    </li>
+  }
 </ul>
diff --git a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.scss b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.scss
index 6124c00..bbae9c7 100644
--- a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.scss
+++ b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.scss
@@ -54,3 +54,7 @@
   display: inline-block;
   padding: 0 5px;
 }
+
+[aria-disabled="true"] {
+  pointer-events: none;
+}
diff --git a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.ts b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.ts
index 2fbc2db..be996a5 100644
--- a/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.ts
+++ b/src/app/shared/components/breadcrumb-navigation/breadcrumb-navigation.component.ts
@@ -1,7 +1,7 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { SolutionIdComponent } from '../solution-id/solution-id.component';
-import { PublicSolutionDetailsModel } from '../../models';
+import { NavigationLabelModel, PublicSolutionDetailsModel } from '../../models';
 import { MatTooltipModule } from '@angular/material/tooltip';
 
 @Component({
@@ -12,8 +12,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
   styleUrl: './breadcrumb-navigation.component.scss',
 })
 export class BreadcrumbNavigationComponent {
-  @Input() firstNavigationLabel!: string;
-  @Input() secondNavigationLabel!: string;
+  @Input() firstNavigationLabel!: NavigationLabelModel;
+  @Input() secondNavigationLabel!: NavigationLabelModel;
   @Input() solution!: PublicSolutionDetailsModel;
 
   @Output() firstNavigationClicked = new EventEmitter<void>();
diff --git a/src/app/shared/components/create-edit-license-profile/create-edit-license-profile.component.ts b/src/app/shared/components/create-edit-license-profile/create-edit-license-profile.component.ts
index 9dc835d..6328626 100644
--- a/src/app/shared/components/create-edit-license-profile/create-edit-license-profile.component.ts
+++ b/src/app/shared/components/create-edit-license-profile/create-edit-license-profile.component.ts
@@ -117,6 +117,7 @@ export class CreateEditLicenseProfileComponent implements OnInit {
     this.isEditMode = this.data.dataKey.isEditMode;
     this.solutionId = this.data.dataKey.solutionId;
     this.revisionId = this.data.dataKey.revisionId;
+
     this.initializeForm();
     this.setupFormValueChangesSubscription();
     if (this.modelLicense) this.updateFormValues();
@@ -235,6 +236,7 @@ export class CreateEditLicenseProfileComponent implements OnInit {
           next: (event) => {
             if (event.type === HttpEventType.Response) {
               this.handleUploadSuccess(event.body);
+              this.sharedDataService.licenseProfile = licenseProfile;
               this.dialogRef.close();
             }
           },
diff --git a/src/app/shared/components/delete-user-dialog-confirmation-action/delete-user-dialog-confirmation-action.component.ts b/src/app/shared/components/delete-user-dialog-confirmation-action/delete-user-dialog-confirmation-action.component.ts
index fbfaa3a..ac06ec9 100644
--- a/src/app/shared/components/delete-user-dialog-confirmation-action/delete-user-dialog-confirmation-action.component.ts
+++ b/src/app/shared/components/delete-user-dialog-confirmation-action/delete-user-dialog-confirmation-action.component.ts
@@ -8,9 +8,7 @@ import {
 import { MatButtonModule } from '@angular/material/button';
 import { MatToolbarModule } from '@angular/material/toolbar';
 import { MatIconModule } from '@angular/material/icon';
-import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
-import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service';
-import { Alert, AlertType, UserDetails } from '../../models';
+import { AlertType } from '../../models';
 import { AlertService } from 'src/app/core/services/alert.service';
 
 @Component({
diff --git a/src/app/shared/components/headline/headline.component.html b/src/app/shared/components/headline/headline.component.html
new file mode 100644
index 0000000..1448e86
--- /dev/null
+++ b/src/app/shared/components/headline/headline.component.html
@@ -0,0 +1,3 @@
+<div class="headline">
+  <span>{{ headlineTitle }} </span>
+</div>
diff --git a/src/app/shared/components/headline/headline.component.scss b/src/app/shared/components/headline/headline.component.scss
new file mode 100644
index 0000000..f370b20
--- /dev/null
+++ b/src/app/shared/components/headline/headline.component.scss
@@ -0,0 +1,14 @@
+.headline {
+  font-size: 20px;
+  height: 30px;
+  font-weight: 600;
+  line-height: 24px;
+  letter-spacing: 0.02em;
+  margin: 3px 0;
+  padding: 0;
+  color: #671c9d;
+  text-overflow: ellipsis;
+  float: left;
+  overflow: hidden;
+  white-space: nowrap;
+}
diff --git a/src/app/shared/components/headline/headline.component.spec.ts b/src/app/shared/components/headline/headline.component.spec.ts
new file mode 100644
index 0000000..e3fa01a
--- /dev/null
+++ b/src/app/shared/components/headline/headline.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HeadlineComponent } from './headline.component';
+
+describe('HeadlineComponent', () => {
+  let component: HeadlineComponent;
+  let fixture: ComponentFixture<HeadlineComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HeadlineComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(HeadlineComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/shared/components/headline/headline.component.ts b/src/app/shared/components/headline/headline.component.ts
new file mode 100644
index 0000000..4979684
--- /dev/null
+++ b/src/app/shared/components/headline/headline.component.ts
@@ -0,0 +1,13 @@
+import { Component, Input } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@Component({
+  selector: 'gp-headline',
+  standalone: true,
+  imports: [CommonModule],
+  templateUrl: './headline.component.html',
+  styleUrl: './headline.component.scss',
+})
+export class HeadlineComponent {
+  @Input() headlineTitle!: string;
+}
diff --git a/src/app/shared/components/home/home.component.html b/src/app/shared/components/home/home.component.html
index 68855e5..00ac690 100644
--- a/src/app/shared/components/home/home.component.html
+++ b/src/app/shared/components/home/home.component.html
@@ -15,7 +15,6 @@
           >
             Marketplace
           </button>
-          <button mat-button (click)="onClickUpload()">Onboard Model</button>
         </div>
       </div>
     </div>
diff --git a/src/app/shared/components/home/home.component.ts b/src/app/shared/components/home/home.component.ts
index ef2cba0..6129ac5 100644
--- a/src/app/shared/components/home/home.component.ts
+++ b/src/app/shared/components/home/home.component.ts
@@ -35,7 +35,6 @@ export class HomeComponent {
   constructor(
     private publicSolutionsService: PublicSolutionsService,
     private router: Router,
-    public dialog: MatDialog,
     private browserStorageService: BrowserStorageService,
   ) {
     this.userId$ = this.browserStorageService
@@ -77,11 +76,4 @@ export class HomeComponent {
       }),
     );
   }
-
-  onClickUpload() {
-    if (this.userId$) {
-      const dialogRef: MatDialogRef<UploadLicenseProfileComponent> =
-        this.dialog.open(UploadLicenseProfileComponent);
-    }
-  }
 }
diff --git a/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.html b/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.html
index 15b3f0c..8bb11d0 100644
--- a/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.html
+++ b/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.html
@@ -35,7 +35,9 @@
 <div style="margin-left: 20px" *ngIf="!modelLicense">
   {{ modelLicenseError }}
 </div>
-<div style="margin-left: 20px">
+<!--<div *ngIf="(sharedDataService.licenseProfile$ | async) as modelLicense; else noLicenseTemplate">
+-->
+<div style="margin-left: 20px" *ngIf="modelLicense; else noLicenseTemplate">
   <pre class="licensedisplay">
     <span *ngIf="modelLicense?.keyword"><strong>keyword: </strong></span>{{ modelLicense?.keyword }}
     <span *ngIf="modelLicense?.licenseName"><strong>licenseName: </strong></span>{{ modelLicense?.licenseName }}
@@ -53,3 +55,6 @@
             <span *ngIf="modelLicense?.additionalInfo"><strong>additionalInfo: </strong></span>{{ modelLicense?.additionalInfo }}
     </pre>
 </div>
+<ng-template #noLicenseTemplate>
+  <p>No license found.</p>
+</ng-template>
diff --git a/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.ts b/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.ts
index 138f5ed..fefd446 100644
--- a/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.ts
+++ b/src/app/shared/components/model-details-license-profile/model-details-license-profile.component.ts
@@ -1,4 +1,4 @@
-import { Component } from '@angular/core';
+import { ChangeDetectorRef, Component, Input } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service';
 import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service';
@@ -19,7 +19,7 @@ import { LicenseProfileModel } from '../../models';
   styleUrl: './model-details-license-profile.component.scss',
 })
 export class ModelDetailsLicenseProfileComponent {
-  modelLicense!: LicenseProfileModel;
+  modelLicense: LicenseProfileModel | null = null;
   isLicenseFound = false;
   isLoadingLicense = true;
   isLicenseJson = false;
@@ -29,13 +29,15 @@ export class ModelDetailsLicenseProfileComponent {
   versionId: string = '';
   versionIdSubscription: Subscription | undefined;
   isUserIdAvailable$: Observable<boolean | undefined>;
+  private subscription: Subscription = new Subscription();
 
   constructor(
     private activatedRoute: ActivatedRoute,
     private publicSolutionsService: PublicSolutionsService,
-    private sharedDataService: SharedDataService,
+    protected sharedDataService: SharedDataService,
     public dialog: MatDialog,
     private browserStorageService: BrowserStorageService,
+    private cd: ChangeDetectorRef,
   ) {
     this.isUserIdAvailable$ = this.browserStorageService
       .getUserDetails()
@@ -43,6 +45,19 @@ export class ModelDetailsLicenseProfileComponent {
   }
 
   ngOnInit() {
+    this.subscription.add(
+      this.sharedDataService.licenseProfile$.subscribe((profile) => {
+        this.modelLicense = profile;
+        /**
+         * this.cd.detectChanges();  // Manually trigger change detection
+         */
+        if (profile) {
+          console.log('License profile updated:', profile);
+        } else {
+          console.log('License profile reset to null');
+        }
+      }),
+    );
     this.activatedRoute.parent?.paramMap.subscribe((paramMap) => {
       this.solutionId = paramMap.get('solutionId') || '';
       this.revisionId = paramMap.get('revisionId') || '';
diff --git a/src/app/shared/components/model-management/model-management.component.html b/src/app/shared/components/model-management/model-management.component.html
index caf10af..5d8139d 100644
--- a/src/app/shared/components/model-management/model-management.component.html
+++ b/src/app/shared/components/model-management/model-management.component.html
@@ -74,8 +74,8 @@
     <div>
       <gp-breadcrumb-navigation
         [solution]="data"
-        [firstNavigationLabel]="'Home'"
-        [secondNavigationLabel]="'Manage my model'"
+        [firstNavigationLabel]="{ label: 'Home' }"
+        [secondNavigationLabel]="{ label: 'Manage my model' }"
         (firstNavigationClicked)="onHomeClick()"
         (secondNavigationClicked)="onManageMyModelClick()"
       ></gp-breadcrumb-navigation>
diff --git a/src/app/shared/components/upload-license-profile/upload-license-profile.component.html b/src/app/shared/components/upload-license-profile/upload-license-profile.component.html
index 9935a52..8161fa9 100644
--- a/src/app/shared/components/upload-license-profile/upload-license-profile.component.html
+++ b/src/app/shared/components/upload-license-profile/upload-license-profile.component.html
@@ -57,12 +57,6 @@
                 mode="determinate"
                 [value]="progressBarValue"
               ></mat-progress-bar>
-              <!-- <div class="pro-status" *ngIf="progressBarValue > 0">
-                <span *ngIf="progressBarValue != 100 && progressBarValue != 0"
-                  >Uploading</span
-                >
-                <span *ngIf="progressBarValue === 100">Done</span> 
-              </div>-->
             </div>
             <div
               style="
diff --git a/src/app/shared/components/upload-license-profile/upload-license-profile.component.ts b/src/app/shared/components/upload-license-profile/upload-license-profile.component.ts
index a8739d7..079e1d0 100644
--- a/src/app/shared/components/upload-license-profile/upload-license-profile.component.ts
+++ b/src/app/shared/components/upload-license-profile/upload-license-profile.component.ts
@@ -2,6 +2,7 @@ import {
   Component,
   ElementRef,
   Inject,
+  Input,
   OnDestroy,
   OnInit,
   ViewChild,
@@ -29,6 +30,7 @@ import {
   of,
   switchMap,
   takeUntil,
+  tap,
   throwError,
 } from 'rxjs';
 import { BrowserStorageService } from 'src/app/core/services/storage/browser-storage.service';
@@ -56,8 +58,8 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
   filename: string | null = null;
   progressBar = 0;
   modelUploadError: boolean = false;
-  solutionId: string = '';
-  revisionId: string = '';
+  @Input() solutionId: string = '';
+  @Input() revisionId: string = '';
   versionId: string = '';
   versionIdSubscription: Subscription | undefined;
   modelLicense!: LicenseProfileModel;
@@ -67,6 +69,7 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
   modelUploadErrorMsg: string[] = [];
   fileSize = 0;
   userId$: Observable<string | undefined>;
+  licenseProfile!: LicenseProfileModel;
   private onDestroy = new Subject<void>();
 
   constructor(
@@ -107,18 +110,36 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
   }
 
   uploadLicenseFile(): void {
+    event?.preventDefault();
     combineLatest([this.userId$, of(this.file)])
       .pipe(
         filter(([userId, file]) => !!userId && !!file),
         switchMap(([userId, file]) => {
-          if (userId && file) {
-            return this.privateCatalogsService.uploadFileToUrl(
+          if (
+            userId &&
+            file &&
+            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'));
           }
@@ -126,26 +147,28 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
         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((event) => {
-        if (
-          event &&
-          event.type === HttpEventType.UploadProgress &&
-          event.total
-        ) {
-          this.progressBarValue = Math.round(
-            (100 * event.loaded) / event.total,
-          );
-        } else if (event && event.type === HttpEventType.Response) {
-          this.handleUploadSuccess(event.body);
-        }
+      .subscribe({
+        next: (event) => this.processEvent(event),
+        error: (error) => {}, // To catch any errors not caught by catchError
+        complete: () => {},
       });
   }
 
+  processEvent(event: any): void {
+    if (event && event.type === HttpEventType.UploadProgress && event.total) {
+      this.progressBarValue = Math.round((100 * event.loaded) / event.total);
+    } else if (event && event.type === HttpEventType.Response) {
+      this.handleUploadSuccess(event.body);
+      this.sharedDataService.licenseProfile = this.licenseProfile;
+    }
+  }
+
   private handleUploadSuccess(response: any) {
     const alert: Alert = {
       message: 'License uploaded successfully',
@@ -157,10 +180,13 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
   private handleUploadError(error: any) {
     // Error handling logic here
     this.modelUploadError = true;
-    const messageError = error.error.response_detail
-      ? error.error.response_detail
-      : error.error;
-    this.modelUploadErrorMsg = [messageError];
+    if (error) {
+      this.modelUploadErrorMsg = [error];
+    } else if (error.error) {
+      const messageError = error.error.response_detail ?? error.error;
+      this.modelUploadErrorMsg = [messageError];
+    }
+
     // Additional error handling
   }
 
@@ -174,7 +200,26 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
     this.filename = file.name;
   }
 
-  handleFileInput(event: Event | File) {
+  readFile(file: File) {
+    const reader = new FileReader();
+    reader.onload = () => {
+      try {
+        this.licenseProfile = JSON.parse(reader.result as string);
+        console.log('License Profile Loaded:', this.licenseProfile);
+        // Proceed with any operations now that the license profile is loaded
+      } catch (e) {
+        console.error('Error parsing the license profile:', e);
+        // Handle errors in reading or parsing the file
+      }
+    };
+    reader.onerror = () => {
+      console.error('Error reading the file:', reader.error);
+    };
+    reader.readAsText(file);
+  }
+
+  handleFileInput(event: any) {
+    event.preventDefault();
     let file: File | null = null;
     if (event instanceof File) {
       file = event;
@@ -184,6 +229,7 @@ export class UploadLicenseProfileComponent implements OnInit, OnDestroy {
     }
     if (file) {
       this.file = file;
+      this.readFile(this.file);
       if (this.file.size / 1024 / 1024 < 1) {
         this.fileSize = Math.ceil(file.size / 1024);
       }
diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts
index d9d61d6..937eb62 100644
--- a/src/app/shared/models/index.ts
+++ b/src/app/shared/models/index.ts
@@ -3,3 +3,4 @@ export * from './filter.model';
 export * from './user-details';
 export * from './public-solution.model';
 export * from './comment';
+export * from './navigation-label.model';
diff --git a/src/app/shared/models/message-status.model.ts b/src/app/shared/models/message-status.model.ts
new file mode 100644
index 0000000..93761dc
--- /dev/null
+++ b/src/app/shared/models/message-status.model.ts
@@ -0,0 +1,15 @@
+export interface MessageStatusModel {
+  taskId: string;
+  stepResultId: string;
+  trackingId: string;
+  stepCode: string;
+  solutionId: string;
+  revisionId: string;
+  artifactId: string;
+  userId: string;
+  name: string;
+  statusCode: string;
+  result: string;
+  startDate: string;
+  endDate: string;
+}
diff --git a/src/app/shared/models/navigation-label.model.ts b/src/app/shared/models/navigation-label.model.ts
new file mode 100644
index 0000000..c4c4dd9
--- /dev/null
+++ b/src/app/shared/models/navigation-label.model.ts
@@ -0,0 +1,4 @@
+export interface NavigationLabelModel {
+  label: string;
+  disabled?: boolean;
+}
diff --git a/src/assets/images/ico-checkmark.png b/src/assets/images/ico-checkmark.png
new file mode 100644
index 0000000000000000000000000000000000000000..68f1686279b683ee53e82a4a2a29f2b5e758a368
GIT binary patch
literal 1159
zcmaJ>PiPcZ93HJHsU~C;N;PPGoq#B2=g%f_Gh^1w?#!;PWYT3_NQ7FQoq5TQ$;=yP
zUffAera@UT)f|LK3$2ydv=pkIEA(L0iV8hgXnT+lJP0bb7Y!1`H!&MMxDL#`KYZW!
z`}4jxC$rtV>sL3frYNdDvq#O5aUFT<YCj}jwC>4OGHk%9Uc3+W;gaq_Dq*4m1Q}cJ
zhdHR5!$)qx4vP9<i<R%iy;_%KAe+@g3>(-kVN+B`XW;6_0K}jG`z<HVJpJu=23TgC
z>1oq=%~fF0+B4$8eIwm@V`RV(O{Q}f=m;btU_-2fz#epbDTp(Rx)Pa(+Z+QHA$TCp
zyiTfD%K`;?5VWy7B8Je?4q_rJw2AG})@Bgpg&iC(azbl_7bISkcmXUu42kBMeNs+M
zFU2COI8(&fl{l_cDzT*&7J2=gAc`W#N4aP;LJ$#u*ui=bar~x=f(m`Zvs`Q;2ZV}x
z0S)0eLo$6`g6%HLI{s3dNW-{5cR7LO!;&gMO?yAowwKX9&cQeNzEjxG54(`dK_3ly
z206ICrZAK%DIU}@^704`R=SuiB8>bZa)F|RU5kOOJ(gpllD}<{qiIsc@v-h0Fr&s9
zqQY91De=*Sl4ucAsicw;gj7sa1tFmb>4X?dtLgSsg{vZC$c7HCaLqT|bX9I>2iql)
zRp?nqp_%rO4HnCmtm?TaRrQv*X7yaus$7mF!-a?Y)?rt+h=aoEvUSN~+5FHUj`xVQ
z?`@u(CfDM5Mor{{e+y?1{&-j3@?TBib8x?5=9m3{@YK|FL)rgfp$i;s`U~jb%bJ<)
z;@pX@?1>otl$!flzH{apy$S64`uYTtuWoq2d<5=OL($r;O8v`IQ|(lFk`iLyeAY1f
z_vZ4YmPCE>*@c~SDf!R1{6)jeqbut@x~v_WXPRf_@oVznsi~jVm(keDwdJwPf!|1f
zLj8}<QBAEcu8+>w(YNW^!HF9i!FR{m6>A<({^`!2zB$n&KOVnJn`829Gd(@aKiEir
zn;bhfI*|aE>$aWO57o3Te7bh;#fRq`%bhE)w9#nQoG34RpWRzi%Tv2Q-VQo99XK5R
O8ZxPF_1EN~uU-K*D0?pe

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_add_to_repository.png b/src/assets/images/ico_add_to_repository.png
new file mode 100644
index 0000000000000000000000000000000000000000..832ab796b44a493bd18f89433e4fd3688b902be1
GIT binary patch
literal 1685
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
VeEwhR%bUMRY;*#-?QfYSe*l+o*>nH^

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_add_to_repository_green.png b/src/assets/images/ico_add_to_repository_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..a53a33ce31ee54497da50b09ecf0668bc092dd5e
GIT binary patch
literal 1693
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

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_add_to_repository_red.png b/src/assets/images/ico_add_to_repository_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..36369caee5882085b7431e43caa7bf08eebd6b2e
GIT binary patch
literal 2155
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
RH^8OezmG=%=MpP6<G<qJb$S2*

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_create_micro_service.png b/src/assets/images/ico_create_micro_service.png
new file mode 100644
index 0000000000000000000000000000000000000000..7385f982364e66f7161fee248bfe5103b1bdb225
GIT binary patch
literal 1003
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i1|)m0d<kV>VD!!mi71Ki^|4CM&(%vz$xlkv
ztH><?$}=$7*jE%JCTFLXC?ut(XXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdi
zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}<Os4*A;LF6
z!8yMuRl!uxOgGuk*h0bFQqR!T(!$6@N5ROz&`jUJQs2--*TB%qz|zXVPyq^*?6?$c
zic-?7f?V97mH~OTN*N_31y=g{<>lpi<;HsXMd|v6mX?<K21fcuM!G;1y2X`wC5aWf
zdBw^gBOqqDq!uR^WfqiV=I1GZ%uGzmFD<cEQql)mq7StN=skV7|9~8L2&Lu$gQW=Q
ze+AEVRtyYG(Vi}jAs(G~r#X6v28y)pzvzC^OFLGjDd5<eIdgd&69ilyJ`?=X!lB|3
z?J-+pk;ami_SrmlSl)|<D0l`YxNx$rjXG1Nkx?aiMM>OEFJ_0wT(M#`{p&kFKU3QB
zqW!q__c{OX)So+JS$?eZv4r;u&OYCy?zNZ70=#&ye=hC}lt}qC`{~M^u3EPld3MgT
ze_i#@-8VyQ1;=ttFW*P%jhYLN3&>BpZ~j2(gH671aH{SBl@C6`zw#b@=O{Ny_fJlc
z+M)D~t$_bU_aTS%8~AtV%c!K^a$CdH)47+4he<h5qUJ*9BWv|JqJ{m8%ey+>vgCE|
zWt_wI%r|^hf}F+SwASDhlU}_r#$8A2IQHl$OnJom!Q)NdP3`bCYi@*^KB)RPZRV*N
zhNjEcu>apyC&IR4-hKVk=Ygi4ys@L^#|wq*{nuCA+toKqI|C@gz{m9Wm*ax-k<<U^
zzX(@dp{x6s<-xJDs~QhAb(FqjRNrRN$<HhE{Q4&&2HEQGAO78ay=Y~_Q%4)ax~b>R
z@s(}gZfsb0){8?&`?j8!#(S0PpW7SRH?46`G+1?nq2rK3SWVxLOQmyDPB6ADHt=v~
z^w0`6zwP>|;XC8&1Dp?fcPZXF9h~_;`GEEU(I1Rom{w=4`*$X+@pRI5CjUmpzhx;8
zI6k-(G3YII(%K}I!nQ-ZO!|Y^ik<WBuNFQUF6=jZ$9snU&FfBF=@oC-bwf3wB_+W=
zb5GlmOI=wx_hueSdVN6S<ilMne#A1@2kv;TdfiLsC{F={1@{@o_^m(Y9Qnp=E?#9W
o6}Uip_OpMN{VkvG|LgIWdH;m9F1BLtE`su?r>mdKI;Vst0Aco(XaE2J

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_create_micro_service_green.png b/src/assets/images/ico_create_micro_service_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fd720776498a4daa90eaefd2e6bd62b3cfc1e80
GIT binary patch
literal 983
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i1|)m0d<kV>VD!!mi71Ki^|4CM&(%vz$xlkv
ztH><?$}=$7*jE%JCTFLXC?ut(XXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdi
zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}<Os4*A;LF6
z!8yMuRl!uxOgGuk*h0bFQqR!T(!$6@N5ROz&`jUJQs2--*TB%qz|zXVPyq^*?6?$c
zic-?7f?V97mH~OTN*N_31y=g{<>lpi<;HsXMd|v6mX?<K21fcuM!G;1y2X`wC5aWf
zdBw^gBOqqDq!uR^WfqiV=I1GZ%uGzmFD<cEQql)mq7StN=skV7|9~8L2&Lu$gQW=Q
ze+AEVRtyYG?w&4=As(G~r)|s@aTGaLuWxzf#u84>auz13jb1a&HVPeiCa|YL!_gpF
zFvsPi{R9&?59KqJ3l1g(h$tyBuKgn|a>TevEKVWy0EeQv*zar7$L8*hWfH3^xHG%*
z{_OmFZ>l$IpR@Ej#6Q8PkvVlLU$a+M$JzT!jBl!6&_CC&JL#rig5R1o-BbG;FIZg&
z@QV-m^+TWG^Z}P6_RII@AMkyUdM|0?8MX%12d)ZVY!A&3co%eTR^V~20{6Fi9|UF;
z9cz{JW7K`Rz)(B&h}3~aw{{<>OgJd{T~X!L9n+_8UVTw2*w}F+@WH%Wu@8hcNZwxA
z?)$)KFVFOo8nXh{F!rqeD^U^apm9_?A@prwtakXCcQ?yx+arFiUT#!%rhjGoIs2vW
zdz{z!y#BD+_?`E$Ltk%Amim3SHfpo(p9t6JHCq~k50q30w$z4Q{=c>$oa^?_n~Vqc
zm<w`6YlU&kKJvPAWbx|7Z~ok3OvuUTd8>Wf)wyw!_{O;#L;AxdEzO$dZd}^3ASJEc
zmG%8xm9S@x?p8Tgk9(doADDUX*^#anF;;n#Oe_!VG1kj%Ju+WySvT)Qn+IA240D+8
z{o)qdW3%^@J@+0)wnq5_DjS|3Z#$pEzhmt;g%2__c>9%^(;L#Im<zN;KTQl($UeZl
zwY{;tK~#IPV&L;NMQx?O>^_)eyKl_e!)S7K9Rs%t?{CcqTdz(}OL;lhCvhY5feA6|
zWb^-(wA>GTSK6zqIxUIUf-{EItYLj)y>qSll-b=Iq!w!g^wuW-f4O|lpY8H1_cOMK
Wt?i3f->?&uA3a_DT-G@yGywpetBoW8

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_create_micro_service_red.png b/src/assets/images/ico_create_micro_service_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..d044b5d2e91fe65f3547854ad68948c5609fb41d
GIT binary patch
literal 1460
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i1|)m0d<g|ok|nMYCBgY=CFO}lsSJ)O`AMk?
zp1FzXsX?iUDV2pMQ*9U+nDa72B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+*
zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn
zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk*h0bFQqR!T
z(!$6@N5ROz&`jUJQs2--*TB%qz|zXVPyq^*fVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj
z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5
zFD<cE0=g99h1>#PU%0_}#n6BP2AO_EVu8M)o`HUDF34YC)x{-2sR(CaRb3oXS&*t9
zlv<o$T9gcok2GbNW?<Oiw+N&V=o%~kqD)|<B<8r}Czs}?=9PH5*eU^K^incYtlSLT
z91V?~ERCEjj9twQ4K19ET-;nO4b3eLolKl94Pa(q)oW?tY;I<5>1J-`YG~+c?r3RX
zW@+N;>}+i2=3-{#4AbkGS6q^qmz)Z-HxpzpM6U&2y;jaesfi`|MIrh5Ij|HEkda@K
zU!0L&py2Ebig9xVjquF8l>G8yO;8j;eC(21lv$RV;#QQOs{jsTt4u6zNHQ@=G)*;5
z(lt#qP1H3uF|p81vNTB11qvBiSeRHErzM#xLG`DQ6L$JQ2kC<n2~whg2?0|ghzZXE
zKn^?;rRD*1P7yGRsO<ii#lXOL$J50zq~g||u!COAh627>E34w8zQyJLW#6kI>f*9N
zN$Xp2)u#}a+l#KtiQMY0>s-(jAX=TF|7hz}i_Em$lW&wvc9pJ3-Cdb~FJ-dNp;m!2
zn*$lY3#Q#*iZ(lEsOWiH`~hFH^V-uViW;0bZn4=&xaIy>t8n~ih{l5yi5u)+T2A>k
zZu?QozjO2B1?^{bm{(+~ajh5I%wc+^YUWkXhI|L%04F_DZN{h*oj*$DH**QrF`f!h
z=;802WmKemx3T-C(Sx}?8OKE;&Zv}~<Vfv_nRHY0<h!h}vf?u;>pK6boP0BFLie<(
zuFucBiC6w5y?drnjq{_)-|YO-{96_ZI4Zbo*G}t+`d6=}9sb(5Gg;+c<QcZhXSi8s
z-?S}qOY2z^7V&t}mRymTtJBXLo5{QqJs5XwQyR~Hr#l%2Vr@OFjaA=rVwPAWU)shq
z&y#CTxO!;J!ptw4FIp|C#0#Tb>X*G#?P1-(_2Mzh>7$!oZaly31k>*W5uHz8&3H4_
z|G=*1n`}T|O!QaWr*KGcf#J<3`?(7Re;;e9e;56Ax<N-}i;bF$;q(<>jTX<}^1h(r
z+r-(gJ}j9a9Lrk5px+kB{yXg1i{)}PyUyOxxA_(Nu3z8gf5BAmXb+nbZrPjt49pC#
WGcwuZ=Vt8zm7|`nelF{r5}E+2a1b*9

literal 0
HcmV?d00001

diff --git a/src/assets/images/ico_not_yet_onboarded.png b/src/assets/images/ico_not_yet_onboarded.png
new file mode 100644
index 0000000000000000000000000000000000000000..672cccf271b839c48e6c860f2641a8d2f1d1ac9a
GIT binary patch
literal 1526
zcmX|BeK?bA7=O*=Yno0{3B6WU)b?(^vb7;rTG{68;2<9{t1TOAo4kmODeBCnP^ie&
zS*1cLiimSMeV$6CMLIII;>a>qDCg)*r>p0>?&o>#=f1Ds@BaP%cnX4<fmRlF761TP
z(KpiAh7+0%vpI%cvZDAr02poNhlESR89`)DvJfAakQ~p&!$Ogv4geHiSQN)e<VwMK
z?sk3>6*GFR9Ru<csF<HU83cwXfXm}=Oc!&1N@s>}(i1tP1dOkb1qCJ>0EAp=90&^q
zNfI(l#eBsj8}75u5C;6(B2A=X*3A-v;f!D~AX&@>J@H;R4$<8kTtmVWJxShf9;-n&
z0?`X1kRYN5jzA<6NMr&L{I)PY79d5Ou#L>7ZTLoJ$fy{eR4O7vP-<!_KGhwcEZz<g
zNhA_PaD&|3aE1<?BrQoA2jh|?%Vr_|$DnZ~95G)c<tHbBvzT%5$thAQ1_RBKK;Kvl
z@}Tef49RzgxJd?E#0LE!y^ah3$Zd4mx)7dBRmR{g3k7cPNgL(1ToqRIYF(u*j3)$3
zTX_r(oxX)tw?988uznZ%V{V&SooV!f4-N2#SD5^F>s%@+X+uixnDHu)_~N19@GU$q
z;ibR-Y^~YHf7awxPPgmQpwWl!TI#1COqWf@2>AShbau^CYn{Dr!3lG^Pt^+B1J#Wi
zHWd)DBanl_TbFi6-<q0zv;)^M>`GrUuO`IeMbqQR*p%o=t4=*osYD}(Sy|5-&Yz1+
zjOtd#B9Xc??BV^w7xx-gf2R8Z?MACMxd>jIszM^wMi4^(FE)5oU*Tip?HxLCJllJ`
ztsYtUdjL(gN!eg5K<GO{CX2o>1euv_kCSb6o}%Y^N>umyL<KjZr%A!KaB*&oRK#Bl
zpUC{OfO9{!FTi)^Zuk6N#H~do>>w6vh1@z8SlE*5@atmAh~>!p_b>U&)zdzz9i;^Y
z1#)ggH||_UfD_8mufDeS=Ib%<2gp}rFzV`MUu?^vo>#BpOVX9)<>doft&q}r^6?_V
zt)kAs)Xe_mylN!HL=%~}Fe4*_=JN6B^rxLTP`Ui*gCugH<l)X^?tUd=WB5|22yl{v
z{-2to@XM6T%Y!g--b#Ri`e!bRT$pQJP1VmO^w_pOt1x?0>tB7rlR(HWIYh(Ei#XwM
z=8kUOJDeToWo%5$%eoL(;2`oBVygM)55J8sB>ZI#tNi=WXH~=6($Z2E=VA{`aXfOX
zY<OyFDneP(Ae^27cST?E$zP8xKA7h}uy-)+BXtaWL1jL5hIPGi)F?19le>NUU|3^h
z8>qB5vb%07x6Z8z*%9Uv>I9FMGPAE3vueXQOV#+`IZZM_e#aw?Mw8<7ho{=EXvlSU
zZP;25t|R?Sb_qM-(({bM*HQM17rT%OyQote?!FOg#H4JkN~MAn#H>3Y-sts;Hb@Fw
zuZ+U)8%*oBIdBu5+27B9f)EP?BVL5EAS_GTxod#a0TfZ#S>u$^lM036Ku13#QthNh
z=h(t0q6@=L-OD8zx1yrR?{BkfXw6YC8K=88xHvBfIyo2^7<k}~xLGqj1NF(<O?S_|
z?{!u^J=46~XOCpZj$xwmX|5GA0b5*9Usso8nD?+#uhwg?XiPpj&9bq`BUP|Y76f7S
zDB)`7cuPx5ZAX=9mdRmRANC_w=9_2jcAV+!qP%Q}J8f>ui^$<m?#VNSk#ObP+DSXz
z;^5Ft5eDO!X2c$vI#9h6V_#ooGqcslD2Dp>b41RSF~@A{94VQ)Txr8VzBQkCSdBPd
zF&I18-nH$A{Q2j>(b!`4+^z%^aKxO6^IvnrA%osn^hk-EXTmggM95IO8+0Vo(lO_v
z&f@{=ZH2`#EQPi<Qm|6gs}mt)G1>dPOwvspd##6@Vcw4?y46lC9h=+C&;y92#{Cnn
z6njX`ukDvaPeyM&cVuATg5Sd?ElDk$K-c#6(No;*VA)plEZ(&#v}XRY;kC}04YS`h
MeLa&_=f5@QKc(`F_5c6?

literal 0
HcmV?d00001

diff --git a/src/assets/images/loading_deactive.png b/src/assets/images/loading_deactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d737e07b46bccaa738e2511d13cabe3b70d3625
GIT binary patch
literal 620
zcmeAS@N?(olHy`uVBq!ia0vp^HbBh7!3HGl+V0(FU|{sl42dX-@b$4u&d=3LOvz75
z)vL%Y0LlZ^+E)}LCTFLXC?ut(XXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdi
zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}<Os4*A;LF6
z!8yMuRl!uxOgGuk*h0bFQqR!T(!$6@N5ROz&`jUJQs2--*TB%qz|zXVPyq^*?6?$c
zic-?7f?V97mH~OTN*N_31y=g{<>lpi<;HsXMd|v6mX?<K21fcuM!G;1y2X`wC5aWf
zdBw^gBOqqDq!uR^WfqiV=I1GZ%uGzmFD<cEQql)mq7StN=skV7|9~8L2&Lu$gQW=Q
ze+AEVR=}{k<LTlU;?a5a+J0YVLy5MJ^J7`c5}G_b7B<N?usU4%Gn0eOA&GI?0!J3t
zq^6SlOzgZz@0uPIpQBfI>iYZS)0bY_E$=WeIBdJFz$Qg|&jZf;+b*}vZ{wDKD5@?z
zyY_+5>&~xfe?$b0_vC8!>lC)-Dd(R$zhkw=VW#b^do=AI?^<LN^vdk%@{Si@=DYIB
z@^MER*R9j(`}5|;eQW#2wd{$ZCuV)xT<3QcqRQgJ|7+s^r`Q+1dLNN->il6g@m~*Z
zjtV_*J-p@F^4{f7nez<fH|g6v4!nCg@BQES_BBnl>)RIifD(zPtDnm{r-UW|d%5EM

literal 0
HcmV?d00001

diff --git a/src/assets/images/stepper_progress_completed.png b/src/assets/images/stepper_progress_completed.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2ef453bedbf98b8b6c3ce86716d0292fd383c7e
GIT binary patch
literal 1302
zcmeAS@N?(olHy`uVBq!ia0vp^-ayR9!3HGLZ$C5zQj#UE5hcO-X(i=}MX3yqDfvmM
z3ZA)%>8U}fi7AzZCsS=07?@QuLn2Bde0{8v^K<nQL2C3WatnaE85nHrD+&^mvr|hH
zl2X$%^K6yg@7}MZkeOnu6mIHk;9KCFnvv;IRg@ZB<rk7%m7Q#vqGWHUU{hfQG$1#%
zBvGLvHz%*ys=`(YY_1iM4HDK@QUEI{$+lI3I4Z(7K*2e`C{@8!&rCPj(AYx3+)~fb
z)Y8JpL`T8Mz|c(Jz*67PMAyL3%D~dfz)%4Slz_GsrKDK}xwt{?0`hE?GD=Dctn~HE
z%ggo3jrH=2()A53EiLs8jP#9+bb%^#i!1X=5-W7`ij`p|xTF>*7iAWdWaj57fJ{tG
z$}cUkRRX#c;)UD-xUqS~&|m@vn0`fKfxe-h0mw@*g}%P{mFDKcRTq~8r6Sym)!^cg
z%7Rq=pw#00(xPNw#HA^NtSYc_E=o--$uA1Y&(DE{Vn9ZINq%ugeu09sGbq%|6~Z&~
zQu51-!8&|>tvvIJOA_;vQ$1a5m4IgGWoD*WnLC=BI~%*0JGnU-8ydQrJ6ak$x>>k5
zSy)<{n_D_N!t}c2Czs}?=9R$orXciM;M5CB47mkBn_W_iGRsm^+=}vZ6~Lah%Eav!
zQ=H~O^`_u<iy2P6`as9%gQ6BGs$oLF^aEnT6E2VgPx`5O!1P`OOxO}DFE=nSFm`yl
zIEGZ*N=lh=(qPfS|6BeSm_62Ub5~GhJF>d*(f<oqjSPF3A{-<cSJpc0Vd_}U@U!O!
z(`oTlKa541Z`h^Wu)c9dQLI3DqjBR7ZrcM1jaQkD%x;jF!c)0G;>bOosmfwJX2l+i
z?hQNmJL8#-eAQUVACdOcLAH_qhv34r4KtnnX0m#DZf>w(_4Jes@HN-j@XaxqSN;b7
z5kHnIK&=-V#RX;yF6@)+_}nmq-&03gBH^+_<5$iT4^<Nmq???*aUj8%U2+BEM_(@C
zg;pE4Dk^W)n#*YN+@AGY<1E4Y$c7`5N|XL(D)GqVJX2_nc6h^iWSYwgR@DVD3StgI
z-ppx-cP}{bO8rpbUzZ4@8)qEZtryM+V6+$3UGS+f>)9bE!I0Hk9&KDQ^~9`npkuQZ
zPZ5;jT<LM>>Vbw?E%(l?Voa*f(ETjh_1$^(3n`&DKuabt<v6b7=)BLzv%)NeRmbCv
zZ-9@cM9wn-ZaYV9#sIF_JYJ!TYn|`(UgmZ<#n;ii;Hik)TTX!lhOeBxKc23=_!(4E
NdAj<!taD0e0sw1(zd`^2

literal 0
HcmV?d00001

-- 
GitLab