Skip to content

Commit

Permalink
Optimize searching products and apps (#65)
Browse files Browse the repository at this point in the history
* fix: added exceptionKey handling

* feat: code optimization

* fix: double import
  • Loading branch information
HenryT-CG authored Mar 3, 2024
1 parent eaae683 commit 95c9216
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 173 deletions.
31 changes: 5 additions & 26 deletions src/app/product-store/app-detail/app-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SelectItem } from 'primeng/api'

import { PortalMessageService, UserService } from '@onecx/portal-integration-angular'
import { IconService } from 'src/app/shared/iconservice'
import { dropDownSortItemsByLabel } from 'src/app/shared/utils'
import { dropDownSortItemsByLabel, convertToUniqueStringArray } from 'src/app/shared/utils'
import {
CreateMicrofrontendRequest,
CreateMicroserviceRequest,
Expand Down Expand Up @@ -57,7 +57,6 @@ export class AppDetailComponent implements OnChanges {
@Input() displayDialog = false
@Output() appChanged = new EventEmitter<boolean>()

private debug = true
public mfe: Microfrontend | undefined
public ms: Microservice | undefined
public formGroupMfe: FormGroup
Expand All @@ -66,6 +65,7 @@ export class AppDetailComponent implements OnChanges {
public hasCreatePermission = false
public hasEditPermission = false
public iconItems: SelectItem[] = [{ label: '', value: null }] // default value is empty
public convertToUniqueStringArray = convertToUniqueStringArray

constructor(
private user: UserService,
Expand Down Expand Up @@ -139,11 +139,7 @@ export class AppDetailComponent implements OnChanges {
this.loading = true
this.mfeApi
.getMicrofrontendByAppId({ appId: this.appAbstract?.appId } as GetMicrofrontendByAppIdRequestParams)
.pipe(
finalize(() => {
this.loading = false
})
)
.pipe(finalize(() => (this.loading = false)))
.subscribe({
next: (data: any) => {
if (data) {
Expand All @@ -166,11 +162,7 @@ export class AppDetailComponent implements OnChanges {
this.loading = true
this.msApi
.getMicroserviceByAppId({ appId: this.appAbstract?.appId } as GetMicroserviceByAppIdRequestParams)
.pipe(
finalize(() => {
this.loading = false
})
)
.pipe(finalize(() => (this.loading = false)))
.subscribe({
next: (data: any) => {
if (data) {
Expand Down Expand Up @@ -229,7 +221,7 @@ export class AppDetailComponent implements OnChanges {
}
this.mfe = { ...this.formGroupMfe.value, id: this.mfe?.id }
if (this.mfe)
this.mfe.classifications = this.makeStringArrayUnique(this.formGroupMfe.controls['classifications'].value)
this.mfe.classifications = this.convertToUniqueStringArray(this.formGroupMfe.controls['classifications'].value)
this.changeMode === 'CREATE' ? this.createMfe() : this.updateMfe()
}
if (this.appAbstract?.appType === 'MS') {
Expand All @@ -242,19 +234,6 @@ export class AppDetailComponent implements OnChanges {
}
}

private makeStringArrayUnique(unsorted: string | undefined): string[] | undefined {
if (!unsorted || unsorted?.length === 0) return undefined
let ar: Array<string> = []
unsorted
.toString()
.split(',')
.map((a) => ar?.push(a.trim()))
return ar.sort(this.sortStrings)
}
private sortStrings(a: string, b: string): number {
return (a as String).toUpperCase().localeCompare((b as String).toUpperCase())
}

private createMfe() {
this.mfeApi.createMicrofrontend({ createMicrofrontendRequest: this.mfe as CreateMicrofrontendRequest }).subscribe({
next: () => {
Expand Down
9 changes: 9 additions & 0 deletions src/app/product-store/app-search/app-search.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,16 @@
</ocx-search-header>

<ocx-page-content>
<div *ngIf="exceptionKey" id="app_search_criteria_error" class="card px-3 align-items-center">
<p-message
id="app_search_criteria_error_message"
severity="error"
styleClass="p-2"
[text]="exceptionKey | translate"
></p-message>
</div>
<p-dataView
*ngIf="!exceptionKey"
id="product_search_dataview"
[value]="(apps$ | async) ?? []"
[paginator]="true"
Expand Down
5 changes: 2 additions & 3 deletions src/app/product-store/app-search/app-search.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,8 @@ describe('AppSearchComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(AppSearchComponent)
component = fixture.componentInstance
fixture.detectChanges()
apiMfeServiceSpy.searchMicrofrontends.and.returnValue(of({} as MicrofrontendPageResult))
apiMsServiceSpy.searchMicroservice.and.returnValue(of({} as MicroservicePageResult))
// fixture.detectChanges()
fixture.componentInstance.ngOnInit() // solved ExpressionChangedAfterItHasBeenCheckedError
})

afterEach(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/app/product-store/app-search/app-search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type ChangeMode = 'VIEW' | 'CREATE' | 'EDIT' | 'COPY'
export class AppSearchComponent implements OnInit, OnDestroy {
private readonly destroy$ = new Subject()
private readonly debug = true // to be removed after finalization
public exceptionKey = ''
public exceptionKey: string | undefined
public loading = true
public actions$: Observable<Action[]> | undefined

Expand Down Expand Up @@ -180,7 +180,7 @@ export class AppSearchComponent implements OnInit, OnDestroy {

public searchApps(): void {
this.searchInProgress = true
this.exceptionKey = ''
this.exceptionKey = undefined
switch (this.appSearchCriteriaGroup.controls['appType'].value) {
case 'ALL':
this.apps$ = combineLatest([this.searchMfes(), this.searchMss()]).pipe(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, OnChanges, ViewChild } from '@angular/core'
import { SelectItem } from 'primeng/api'
import { combineLatest, finalize, map, of, Observable, catchError } from 'rxjs'
import { SelectItem } from 'primeng/api'
import { DataView } from 'primeng/dataview'

import { DataViewControlTranslations, UserService } from '@onecx/portal-integration-angular'
Expand Down Expand Up @@ -29,6 +29,7 @@ export class ProductAppsComponent implements OnChanges {

private readonly debug = true // to be removed after finalization
public exceptionKey = ''
public searchInProgress = false
public apps$!: Observable<AppAbstract[]>
public mfes$!: Observable<MicrofrontendPageResult>
public mss$!: Observable<MicroservicePageResult>
Expand All @@ -38,7 +39,6 @@ export class ProductAppsComponent implements OnChanges {
public viewMode = 'grid'
public sortField = 'appId'
public sortOrder = 1
public searchInProgress = false
public displayDetailDialog = false
public displayDeleteDialog = false
public hasCreatePermission = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@ export type ChangeMode = 'VIEW' | 'CREATE' | 'EDIT' | 'COPY'
styleUrls: ['./product-detail.component.scss']
})
export class ProductDetailComponent implements OnInit {
@ViewChild(ProductPropertyComponent, { static: false }) productPropsComponent!: ProductPropertyComponent

public actions$: Observable<Action[]> | undefined
public productName: string
public product: ProductAndWorkspaces | undefined
public product_for_apps: ProductAndWorkspaces | undefined
public changeMode: ChangeMode = 'CREATE'
public loading = false
public dateFormat = 'medium'
public actions: Action[] = []
public headerImageUrl?: string
public productDeleteVisible = false
public productDeleteMessage = ''
public selectedTabIndex = 0

@ViewChild(ProductPropertyComponent, { static: false }) productPropsComponent!: ProductPropertyComponent

constructor(
private router: Router,
private route: ActivatedRoute,
Expand Down Expand Up @@ -190,7 +189,7 @@ export class ProductDetailComponent implements OnInit {
if (this.changeMode === 'CREATE') this.close()
}
public onSave() {
this.productPropsComponent.onSubmit()
this.productPropsComponent.onSave()
}

public onCreate(data: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()">
<form [formGroup]="formGroup" (ngSubmit)="onSave()">
<div class="surface-section flex flex-column row-gap-4 my-3 sm:my-5">
<div class="flex flex-wrap row-gap-4">
<div class="w-full sm:w-10 md:w-9 lg:w-6 px-3">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ describe('ProductPropertyComponent', () => {
expect(component.formGroup.reset).toHaveBeenCalled()
})

it('should call createProduct onSubmit in new mode', () => {
it('should call createProduct onSave in new mode', () => {
apiServiceSpy.createProduct.and.returnValue(of({}))
const formGroup = new FormGroup<ProductDetailForm>({
id: new FormControl<string | null>('id'),
Expand All @@ -169,13 +169,13 @@ describe('ProductPropertyComponent', () => {
component.formGroup = formGroup as FormGroup<ProductDetailForm>
component.changeMode = 'CREATE'

component.onSubmit()
component.onSave()

expect(apiServiceSpy.createProduct).toHaveBeenCalled()
expect(msgServiceSpy.success).toHaveBeenCalledWith({ summaryKey: 'ACTIONS.CREATE.PRODUCT.OK' })
})

it('should call updateProduct onSubmit in edit mode', () => {
it('should call updateProduct onSave in edit mode', () => {
apiServiceSpy.updateProduct.and.returnValue(of({}))
const formGroup = new FormGroup<ProductDetailForm>({
id: new FormControl<string | null>('id'),
Expand All @@ -192,7 +192,7 @@ describe('ProductPropertyComponent', () => {
component.formGroup = formGroup as FormGroup<ProductDetailForm>
component.changeMode = 'EDIT'

component.onSubmit()
component.onSave()

expect(apiServiceSpy.updateProduct).toHaveBeenCalled()
expect(msgServiceSpy.success).toHaveBeenCalledWith({ summaryKey: 'ACTIONS.EDIT.PRODUCT.OK' })
Expand All @@ -216,7 +216,7 @@ describe('ProductPropertyComponent', () => {
component.formGroup.controls['name'].setValue('')
component.changeMode = 'EDIT'

component.onSubmit()
component.onSave()

expect(component.formGroup.valid).toBeTrue()
expect(msgServiceSpy.error).toHaveBeenCalledWith({
Expand Down Expand Up @@ -247,7 +247,7 @@ describe('ProductPropertyComponent', () => {
component.formGroup.controls['name'].setValue('')
component.changeMode = 'EDIT'

component.onSubmit()
component.onSave()

expect(component.formGroup.valid).toBeTrue()
expect(msgServiceSpy.error).toHaveBeenCalledWith({
Expand All @@ -262,7 +262,7 @@ describe('ProductPropertyComponent', () => {
const focusSpy = jasmine.createSpy('focus')
spyOn((component as any).elements.nativeElement, 'querySelector').and.returnValue({ focus: focusSpy })

component.onSubmit()
component.onSave()

expect(component.formGroup.valid).toBeFalse()
expect(msgServiceSpy.error).toHaveBeenCalledWith({ summaryKey: 'VALIDATION.FORM_INVALID' })
Expand All @@ -286,15 +286,15 @@ describe('ProductPropertyComponent', () => {
component.formGroup = formGroup as FormGroup<ProductDetailForm>
component.changeMode = 'CREATE'

component.onSubmit()
component.onSave()

expect(component.formGroup.valid).toBeTrue()
expect(msgServiceSpy.error).toHaveBeenCalledWith({
summaryKey: 'ACTIONS.CREATE.PRODUCT.NOK'
})
})

it('should display error onSubmit if formGroup invalid', () => {
it('should display error onSave if formGroup invalid', () => {
const formGroup = new FormGroup<ProductDetailForm>({
id: new FormControl<string | null>(null, Validators.required),
name: new FormControl<string | null>('name'),
Expand All @@ -309,7 +309,7 @@ describe('ProductPropertyComponent', () => {
})
component.formGroup = formGroup as FormGroup<ProductDetailForm>

component.onSubmit()
component.onSave()

expect(component.formGroup.valid).toBeFalse()
expect(msgServiceSpy.error).toHaveBeenCalledWith({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
UploadImageRequestParams
} from 'src/app/shared/generated'
import { IconService } from 'src/app/shared/iconservice'
import { dropDownSortItemsByLabel } from 'src/app/shared/utils'
import { dropDownSortItemsByLabel, convertToUniqueStringArray } from 'src/app/shared/utils'
import { ChangeMode } from '../product-detail.component'

export interface ProductDetailForm {
Expand Down Expand Up @@ -56,8 +56,7 @@ export class ProductPropertyComponent implements OnChanges, OnInit {
public fetchingLogoUrl: string | undefined
public iconItems: SelectItem[] = [{ label: '', value: null }]
public logoImageWasUploaded: boolean | undefined

//private productNamePattern = '^(?!new$)(.*)$' // matching for valid product names
public convertToUniqueStringArray = convertToUniqueStringArray

constructor(
private icon: IconService,
Expand Down Expand Up @@ -124,7 +123,7 @@ export class ProductPropertyComponent implements OnChanges, OnInit {

/** CREATE/UPDATE product
*/
public onSubmit() {
public onSave() {
if (this.formGroup.valid) {
this.changeMode === 'EDIT' ? this.updateProduct() : this.createProduct()
} else {
Expand All @@ -150,7 +149,7 @@ export class ProductPropertyComponent implements OnChanges, OnInit {
basePath: this.formGroup.value['basePath'],
displayName: this.formGroup.value['displayName'],
iconName: this.formGroup.value['iconName'],
classifications: this.formGroup.value['classifications']?.toString().split(',')
classifications: this.convertToUniqueStringArray(this.formGroup.value['classifications']?.toString())
} as CreateProductRequest
})
.subscribe({
Expand Down Expand Up @@ -178,7 +177,7 @@ export class ProductPropertyComponent implements OnChanges, OnInit {
basePath: this.formGroup.value['basePath'],
displayName: this.formGroup.value['displayName'],
iconName: this.formGroup.value['iconName'],
classifications: this.formGroup.value['classifications']?.toString().split(',')
classifications: this.convertToUniqueStringArray(this.formGroup.value['classifications']?.toString())
} as UpdateProductRequest
})
.subscribe({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const product = {
}

class MockProductPropertyComponent {
onSubmit = jasmine.createSpy('onSubmit')
onSave = jasmine.createSpy('onSave')
}

describe('ProductDetailComponent', () => {
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('ProductDetailComponent', () => {

component.onSave()

expect(component.productPropsComponent.onSubmit).toHaveBeenCalled()
expect(component.productPropsComponent.onSave).toHaveBeenCalled()
})

it('should behave correctly onCreate', () => {
Expand Down
Loading

0 comments on commit 95c9216

Please sign in to comment.