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

#19: :sparkles: implement first version of publish model to marketplace

parent 67ca9048
No related branches found
No related tags found
1 merge request!12Features/user auth manage my models
......@@ -42,6 +42,7 @@ export const apiConfig = {
urlDeleteFavorite: '/api/solution/deleteFavorite',
urlPrivateCatalogsList: '/api/catalogs',
urlModelTypes: '/api/filter/modeltype',
urlToolkitTypes: '/api/filter/toolkitType',
urlSearchSolutions: '/api/searchSolutionBykeyword',
urlFavoriteSolution: '/api/solution/getFavoriteSolutions',
urlUserAccountDetails: '/api/users/userAccountDetails',
......@@ -59,4 +60,5 @@ export const apiConfig = {
urlMessagingStatus: '/api/webBasedOnBoarding/messagingStatus',
urlUserSolutions: '/api/user/solutions',
urlSearchSolutionsByName: '/api/onboardingDocker/dockerSearchSolutions',
urlAllCatalogsList: '/api/catalogs',
};
......@@ -20,4 +20,15 @@ export class FiltersService {
}),
);
}
getToolkitTypes(): Observable<CatalogFilter[]> {
const url = apiConfig.apiBackendURL + apiConfig.urlToolkitTypes;
return this._httpSharedService.get(url, undefined).pipe(
tap(),
map((res) => res.response_body),
catchError((error) => {
throw error;
}),
);
}
}
......@@ -5,6 +5,7 @@ import { HttpSharedService } from '../http-shared/http-shared.service';
import { HttpClient, HttpEvent, HttpRequest } from '@angular/common/http';
import {
AuthorPublisherModel,
Catalog,
CommentModel,
PublicSolution,
PublicSolutionDetailsModel,
......@@ -58,6 +59,7 @@ export class PrivateCatalogsService {
}),
);
}
getPreferredTag(userId: any) {
let body = {
request_body: {
......@@ -370,7 +372,7 @@ export class PrivateCatalogsService {
getShareWithTeam(solutionId: string): Observable<UserDetails[]> {
const url = `${apiConfig.apiBackendURL}${apiConfig.urlShareWithTeam}/${solutionId}`;
return this._httpSharedService.get(url, undefined).pipe(
map((res) => res.response_body.userList),
map((res) => res.response_body?.userList),
catchError((error) => {
throw error;
}),
......@@ -617,4 +619,26 @@ export class PrivateCatalogsService {
}),
);
}
getAllAvailableCatalogs(): Observable<Catalog[]> {
const request = {
request_body: {
fieldToDirectionMap: {
created: 'DESC',
},
page: 0,
size: 10000,
},
request_from: 'string',
request_id: 'string',
};
const url = apiConfig.apiBackendURL + apiConfig.urlAllCatalogsList;
return this._httpSharedService.post(url, undefined, request).pipe(
map((res) => res.response_body.content),
catchError((error) => {
throw error;
}),
);
}
}
import { Component, OnInit, inject } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
......@@ -6,7 +6,6 @@ import {
AbstractControl,
AsyncValidatorFn,
FormBuilder,
FormControl,
FormGroup,
FormGroupDirective,
FormsModule,
......@@ -17,13 +16,10 @@ import {
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { ActivatedRoute, Router } from '@angular/router';
import { SharedDataService } from 'src/app/core/services/shared-data/shared-data.service';
import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service';
import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
import { Alert, AlertType, AuthorPublisherModel } from '../../models';
import { MatChipsModule } from '@angular/material/chips';
import { MatIconModule } from '@angular/material/icon';
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { DeleteUserDialogConfirmationActionComponent } from '../delete-user-dialog-confirmation-action/delete-user-dialog-confirmation-action.component';
import { Observable, map, of } from 'rxjs';
......@@ -214,9 +210,6 @@ export class ManagePublisherAuthorsPageComponent implements OnInit {
this.publisherNameControl,
);
}
// this.updatePublisherNameControlValidators();
/* this.publisherForm.reset();
formDirective.resetForm(); */
},
error: (error) => {
console.log({ error });
......@@ -241,37 +234,6 @@ export class ManagePublisherAuthorsPageComponent implements OnInit {
this.publisherForm.setValue({ name: this.publisherName });
}
/* notSameAsPublisher(publisherName: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
console.log('publisher name validation', this.publisherName);
console.log('control.value validation', control.value);
const isSame =
control.value.trim().toLowerCase() ===
publisherName.trim().toLowerCase();
console.log({ isSame });
return isSame ? { sameAsPublisher: true } : null;
};
}
*/
/* notSameAsPublisher(publisherName: string): AsyncValidatorFn {
return (
control: AbstractControl,
): Observable<{ [key: string]: any } | null> => {
if (!control.value) {
console.log('inside if');
return of(null); // If no value, return null immediately
}
const isSame =
control.value.trim().toLowerCase() ===
publisherName.trim().toLowerCase();
console.log({ isSame });
return of(isSame ? { sameAsPublisher: true } : null);
};
}
*/
notSameAsPublisher(): AsyncValidatorFn {
return (
control: AbstractControl,
......
......@@ -85,10 +85,6 @@ export class ModelManagementComponent implements OnInit {
}),
tap((solution) => {
this.revisions$ = this.getRevisionsAsObservable(solution);
const initialRevision =
solution.revisions.find(
(rev) => rev.revisionId === this.revisionId,
) || solution.revisions[0];
this.revisions$ = this.getRevisionsAsObservable(solution);
this.updateSelectedRevision(this.revisionId, solution);
this.setRevisionInService(solution.revisions[0]);
......
<div class="workflow-right-header workflow-header">Publish to Marketplace</div>
<div style="display: flex; flex-direction: column; padding: 40px">
<!-- status stepper start-->
<div></div>
<!-- status stepper end-->
<!--Select catalog start-->
<div>
<!-- <mat-form-field>
<mat-label>Select a catalog</mat-label>
<mat-select [(ngModel)]="selectedCatalog" name="catalog">
@for (catalog of catalogs; track catalog) {
<mat-option [value]="catalog">{{ catalog.name }}</mat-option>
}
</mat-select>
</mat-form-field> -->
</div>
<!--Select catalog end-->
<!-- Steps to submit publication start-->
<form [formGroup]="publishToMarketPlaceForm" (ngSubmit)="submit()">
<div style="display: flex; flex-direction: column">
<mat-form-field>
<mat-label>Select a catalog</mat-label>
<mat-select formControlName="catalog">
@for (catalog of catalogs; track catalog) {
<mat-option [value]="catalog">{{ catalog.name }}</mat-option>
}
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Model name</mat-label>
<input matInput formControlName="name" />
</mat-form-field>
<mat-form-field>
<mat-label>Model description</mat-label>
<input matInput formControlName="description" />
</mat-form-field>
<div style="display: flex; gap: 20px; width: 100%">
<mat-form-field style="width: 100%">
<mat-label>Select category</mat-label>
<mat-select formControlName="category">
@for (catalog of catalogs; track catalog) {
<mat-option [value]="catalog">{{ catalog.name }}</mat-option>
}
</mat-select>
</mat-form-field>
<mat-form-field style="width: 100%">
<mat-label>Select toolkitType</mat-label>
<mat-select formControlName="toolkitType">
@for (catalog of catalogs; track catalog) {
<mat-option [value]="catalog">{{ catalog.name }}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<mat-form-field>
<mat-label>Model license profile</mat-label>
<input matInput formControlName="licenseProfile" />
</mat-form-field>
<mat-form-field>
<mat-label>Model documents</mat-label>
<input matInput formControlName="documents" />
</mat-form-field>
<mat-form-field>
<mat-label>Model tags</mat-label>
<input matInput formControlName="tags" />
</mat-form-field>
<mat-form-field>
<mat-label>Model image</mat-label>
<input matInput formControlName="image" />
</mat-form-field>
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 40px;
"
>
<button style="width: 20%" mat-raised-button color="primary">
Unpublish model
</button>
<button style="width: 20%" mat-raised-button color="primary">
Publish model
</button>
</div>
</div>
</form>
<!-- Steps to submit publication end-->
</div>
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service';
import {
Catalog,
CatalogFilter,
Filter,
PublicSolutionDetailsModel,
ToolkitTypeCode,
toolkitTypeCodeMap,
} from '../../models';
import { MatMenuModule } from '@angular/material/menu';
import { MatListModule } from '@angular/material/list';
import { MatButtonModule } from '@angular/material/button';
import { PrivateCatalogsService } from 'src/app/core/services/private-catalogs.service';
import {
FormBuilder,
FormGroup,
FormsModule,
ReactiveFormsModule,
Validators,
} from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { FiltersService } from 'src/app/core/services/filters.service';
@Component({
selector: 'gp-publish-to-marketplace-page',
standalone: true,
imports: [CommonModule],
imports: [
CommonModule,
MatMenuModule,
MatListModule,
MatButtonModule,
FormsModule,
ReactiveFormsModule,
MatFormFieldModule,
MatSelectModule,
MatInputModule,
],
templateUrl: './publish-to-marketplace-page.component.html',
styleUrl: './publish-to-marketplace-page.component.scss'
styleUrl: './publish-to-marketplace-page.component.scss',
})
export class PublishToMarketplacePageComponent {
export class PublishToMarketplacePageComponent implements OnInit {
solutionId!: string;
revisionId!: string;
catalogs!: Catalog[];
selectedCatalog!: Catalog;
publishToMarketPlaceForm!: FormGroup;
solution!: PublicSolutionDetailsModel;
categories: Filter[] = [];
toolkitTypes: Filter[] = [];
constructor(
private activatedRoute: ActivatedRoute,
private privateCatalogsService: PrivateCatalogsService,
private formBuilder: FormBuilder,
private filtersService: FiltersService,
private publicSolutionsService: PublicSolutionsService,
) {
this.publishToMarketPlaceForm = this.formBuilder.group({
catalog: [null, [Validators.required]],
name: [
'',
[
Validators.required,
Validators.pattern('^(?=.*[a-z])[a-z0-9]+(?:[-.][a-z0-9]+)*$'),
],
[],
],
description: ['', [Validators.required]],
category: [null, [Validators.required]],
toolkitType: [null, Validators.required],
licenseProfile: [null, [Validators.required]],
documents: [null, [Validators.required]],
tags: [null, [Validators.required]],
image: [null, [Validators.required]],
});
}
ngOnInit(): void {
this.activatedRoute.parent?.params.subscribe((params) => {
this.solutionId = params['solutionId'];
this.revisionId = params['revisionId'];
this.publicSolutionsService
.getSolutionDetails(this.solutionId, this.revisionId)
.subscribe({
next: (res) => {
this.solution = res;
console.log({ res });
this.publishToMarketPlaceForm.setValue({
name: res.name,
});
},
error: (error) => console.log(),
});
});
this.privateCatalogsService.getAllAvailableCatalogs().subscribe({
next: (res) => {
this.catalogs = res;
console.log({ res });
},
error: (error) => console.log(),
});
this.filtersService.getModelTypes().subscribe(
(res: CatalogFilter[]) => {
this.categories = res.map((catalog: CatalogFilter) => ({
name: catalog.name,
selected: false,
}));
},
(err: any) => {},
);
this.filtersService.getToolkitTypes().subscribe(
(res: CatalogFilter[]) => {
this.toolkitTypes = res.map((catalog: CatalogFilter) => ({
name: catalog.name,
selected: false,
}));
},
(err: any) => {},
);
}
convertToolkitTypesToCodes(
selectedToolkitTypes: string[],
): ToolkitTypeCode[] {
return selectedToolkitTypes.map(
(toolkitTypeName) =>
toolkitTypeCodeMap[toolkitTypeName] as ToolkitTypeCode,
);
}
onChangeCatalog(catalog: Catalog) {
this.selectedCatalog = catalog;
}
submit() {}
}
......@@ -24,6 +24,55 @@ export enum Category {
Regression = 'RG',
}
export enum ToolkitType {
Data_Broker = 'BR',
CC = 'CC',
Collator = 'CO',
Composite_Solution = 'CP',
Data_Source = 'DA',
Design_Studio = 'DS',
H2O = 'H2',
Initializer = 'IN',
Java_Spark = 'JS',
Model_Node = 'MN',
ONAP = 'ON',
Orchestrator = 'OR',
ONNX = 'OX',
Probe = 'PB',
PFA = 'PF',
R = 'RC',
Shared_Folder = 'SF',
Scikit_Learn = 'SK',
Splitter = 'SP',
Training_Client = 'TC',
TensorFlow = 'TF',
}
// Mapping object for toolkit names to codes
export const toolkitTypeCodeMap: Record<string, ToolkitType> = {
'Data Broker': ToolkitType.Data_Broker,
'C/C++': ToolkitType.CC,
Collator: ToolkitType.Collator,
'Composite Solution': ToolkitType.Composite_Solution,
'Data Source': ToolkitType.Data_Source,
'Design Studio': ToolkitType.Design_Studio,
H2O: ToolkitType.H2O,
Initializer: ToolkitType.Initializer,
'Java Spark': ToolkitType.Java_Spark,
'Model Node': ToolkitType.Model_Node,
ONAP: ToolkitType.ONAP,
Orchestrator: ToolkitType.Orchestrator,
ONNX: ToolkitType.ONNX,
Probe: ToolkitType.Probe,
PFA: ToolkitType.PFA,
R: ToolkitType.R,
'Shared Folder': ToolkitType.Shared_Folder,
'Scikit Learn': ToolkitType.Scikit_Learn,
Splitter: ToolkitType.Splitter,
'Training Client': ToolkitType.Training_Client,
TensorFlow: ToolkitType.TensorFlow,
};
// Mapping object for category names to codes
export const categoryCodeMap: Record<string, Category> = {
Classification: Category.Classification,
......@@ -34,3 +83,4 @@ export const categoryCodeMap: Record<string, Category> = {
};
export type CategoryCode = (typeof Category)[keyof typeof Category];
export type ToolkitTypeCode = (typeof ToolkitType)[keyof typeof ToolkitType];
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