diff --git a/src/app/core/config/api-config.ts b/src/app/core/config/api-config.ts index 9fa383de6d193c6ea89bfeb28ccb8cf3dacf9024..b6e448fb0acd52beaaf58cbab0205ebdba83c90a 100644 --- a/src/app/core/config/api-config.ts +++ b/src/app/core/config/api-config.ts @@ -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', }; diff --git a/src/app/core/services/filters.service.ts b/src/app/core/services/filters.service.ts index 5657b49800b73eddab3996320504f3436b4142c9..848ad475021b6ae080026d4bd805eec7a281ca76 100644 --- a/src/app/core/services/filters.service.ts +++ b/src/app/core/services/filters.service.ts @@ -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; + }), + ); + } } diff --git a/src/app/core/services/private-catalogs.service.ts b/src/app/core/services/private-catalogs.service.ts index d076e46778f9fd9a9442b0e6aeab87c6835eb77f..bee923e045c066a95f449f44e369c9efa45ca67c 100644 --- a/src/app/core/services/private-catalogs.service.ts +++ b/src/app/core/services/private-catalogs.service.ts @@ -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; + }), + ); + } } diff --git a/src/app/shared/components/manage-publisher-authors-page/manage-publisher-authors-page.component.ts b/src/app/shared/components/manage-publisher-authors-page/manage-publisher-authors-page.component.ts index ac48c024f9f3f5db31d308b50b5c97c3ba2c369b..8b06d94163334e79ec0e18b1b7e739b074399aa3 100644 --- a/src/app/shared/components/manage-publisher-authors-page/manage-publisher-authors-page.component.ts +++ b/src/app/shared/components/manage-publisher-authors-page/manage-publisher-authors-page.component.ts @@ -1,4 +1,4 @@ -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, diff --git a/src/app/shared/components/model-management/model-management.component.ts b/src/app/shared/components/model-management/model-management.component.ts index 156107b41c190618c397704c12e88454c7878421..7abb9899a35d625abfc40699b567e3a698180eca 100644 --- a/src/app/shared/components/model-management/model-management.component.ts +++ b/src/app/shared/components/model-management/model-management.component.ts @@ -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]); diff --git a/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.html b/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.html index 84a9e419691424e5520112254a79644bec88b79e..39a34fa92022e9f68df2714f5cd92ed04e47969f 100644 --- a/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.html +++ b/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.html @@ -1 +1,91 @@ <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> diff --git a/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.ts b/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.ts index 8f9303136eaf73bcf530fa79fc839f1c4a403bab..79d28973887c53d0c3674cf6f8fd655c655d5e50 100644 --- a/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.ts +++ b/src/app/shared/components/publish-to-marketplace-page/publish-to-marketplace-page.component.ts @@ -1,13 +1,145 @@ -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() {} } diff --git a/src/app/shared/models/filter.model.ts b/src/app/shared/models/filter.model.ts index ca769bc941a5b6a707bba5d34b73d3ef7df35c60..f64c3177d1c1d20dcb4669f677c5725e1618b33f 100644 --- a/src/app/shared/models/filter.model.ts +++ b/src/app/shared/models/filter.model.ts @@ -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];