Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize searching products and apps #65

Merged
merged 3 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading