Skip to content

Commit

Permalink
Create slot in product detail to show use of product in workspaces (#300
Browse files Browse the repository at this point in the history
)

* fix: create product detail use component and do init slot setup

* fix: finish slot setup

* fix: add info box in case of undefined slot

* fix: delete used ws in intern tab, update all test files to drop deprecated http components

---------

Co-authored-by: Christian Badura <[email protected]>
  • Loading branch information
cbadura and Christian Badura authored Nov 1, 2024
1 parent 1bad883 commit d8e10b6
Show file tree
Hide file tree
Showing 19 changed files with 143 additions and 65 deletions.
6 changes: 6 additions & 0 deletions helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ app:
path: /apps
- name: slots
path: /slots
slot:
enabled: true
specs:
onecx-product-list-workspaces-using-product:
name: 'onecx-product-list-workspaces-using-product'
description: 'List Workspaces using a given Product'
# Permission
permission:
enabled: true
Expand Down
6 changes: 4 additions & 2 deletions src/app/product-store/app-delete/app-delete.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { TranslateTestingModule } from 'ngx-translate-testing'
import { of, throwError } from 'rxjs'

import { PortalMessageService } from '@onecx/portal-integration-angular'
import { MicrofrontendsAPIService, MicroservicesAPIService } from 'src/app/shared/generated'
import { AppAbstract } from '../app-search/app-search.component'
import { AppDeleteComponent } from './app-delete.component'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

describe('AppDeleteComponent', () => {
let component: AppDeleteComponent
Expand Down Expand Up @@ -38,13 +39,14 @@ describe('AppDeleteComponent', () => {
TestBed.configureTestingModule({
declarations: [AppDeleteComponent],
imports: [
HttpClientTestingModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [
provideHttpClientTesting(),
provideHttpClient(),
{ provide: MicrofrontendsAPIService, useValue: apiMfeServiceSpy },
{ provide: MicroservicesAPIService, useValue: apiMsServiceSpy },
{ provide: PortalMessageService, useValue: msgServiceSpy }
Expand Down
8 changes: 4 additions & 4 deletions src/app/product-store/app-detail/app-detail.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { of, throwError } from 'rxjs'
import { FormControl, FormGroup, Validators } from '@angular/forms'
import { TranslateTestingModule } from 'ngx-translate-testing'
Expand All @@ -16,6 +14,8 @@ import {
MicrofrontendType
} from 'src/app/shared/generated'
import { AppAbstract } from '../app-search/app-search.component'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

const form = new FormGroup<MfeForm>({
appId: new FormControl('id', Validators.minLength(2)),
Expand Down Expand Up @@ -135,14 +135,14 @@ describe('AppDetailComponent', () => {
TestBed.configureTestingModule({
declarations: [AppDetailComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [
provideHttpClientTesting(),
provideHttpClient(),
{ provide: MicrofrontendsAPIService, useValue: mfeApiServiceSpy },
{ provide: MicroservicesAPIService, useValue: msApiServiceSpy },
{ provide: PortalMessageService, useValue: msgServiceSpy },
Expand Down
8 changes: 4 additions & 4 deletions src/app/product-store/app-search/app-search.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { Router, ActivatedRoute } from '@angular/router'
import { of, throwError } from 'rxjs'
import { FormControl, FormGroup, Validators } from '@angular/forms'
Expand All @@ -18,6 +16,8 @@ import {
MicroservicePageResult,
MicroservicesAPIService
} from 'src/app/shared/generated'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

const form = new FormGroup<AppSearchCriteria>({
appId: new FormControl<string | null>(null, Validators.minLength(2)),
Expand Down Expand Up @@ -88,14 +88,14 @@ describe('AppSearchComponent', () => {
TestBed.configureTestingModule({
declarations: [AppSearchComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [
provideHttpClientTesting(),
provideHttpClient(),
{ provide: MicrofrontendsAPIService, useValue: apiMfeServiceSpy },
{ provide: MicroservicesAPIService, useValue: apiMsServiceSpy },
{ provide: UserService, useValue: mockUserService },
Expand Down
10 changes: 10 additions & 0 deletions src/app/product-store/product-detail/product-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@
<app-product-intern [product]="product" [dateFormat]="dateFormat"></app-product-intern>
</p-tabPanel>

<p-tabPanel
[header]="'DIALOG.TABS.USE' | translate"
[attr.aria-label]="'DIALOG.TABS.USE' | translate"
[tooltip]="'DIALOG.TABS.TOOLTIPS.USE' | translate"
tooltipPosition="top"
tooltipEvent="hover"
>
<app-product-use [product]="product"></app-product-use>
</p-tabPanel>

<p-tabPanel
id="ps_product_detail_panel_apps"
[disabled]="changeMode !== 'VIEW'"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,5 @@
>
</span>
</div>

<!-- row 4 -->
<span class="p-float-label">
<textarea
#usedInWorkspaces
pInputTextarea
readonly
rows="4"
class="w-full"
autoresize="true"
id="ps_product_detail_intern_field_workspaces"
[pTooltip]="'PRODUCT.TOOLTIPS.WORKSPACES' | translate"
tooltipPosition="top"
tooltipEvent="hover"
>
</textarea>
<label for="ps_product_detail_intern_field_workspaces">{{ 'PRODUCT.WORKSPACES' | translate }}</label>
</span>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { TranslateTestingModule } from 'ngx-translate-testing'

import { ProductInternComponent } from './product-intern.component'
import { ProductAndWorkspaces } from 'src/app/shared/generated'
import { provideHttpClient } from '@angular/common/http'

const prodAndWsUndeployed: ProductAndWorkspaces = {
id: 'id',
Expand All @@ -28,13 +28,12 @@ describe('ProductInternComponent', () => {
TestBed.configureTestingModule({
declarations: [ProductInternComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [provideHttpClientTesting(), provideHttpClient()],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents()
}))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
import { Component, Input, OnChanges, ElementRef, ViewChild } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { Component, Input, OnChanges } from '@angular/core'

import { ProductAndWorkspaces } from 'src/app/shared/generated'
import { sortByLocale } from 'src/app/shared/utils'
import { Product } from 'src/app/shared/generated'

@Component({
selector: 'app-product-intern',
templateUrl: './product-intern.component.html'
})
export class ProductInternComponent implements OnChanges {
@Input() product: ProductAndWorkspaces | undefined
@Input() product: Product | undefined
@Input() dateFormat = 'medium'

@ViewChild('usedInWorkspaces') usedInWorkspaces: ElementRef = {} as ElementRef
public operator = false
public undeployed = false

constructor(private readonly translate: TranslateService) {}

public ngOnChanges(): void {
if (this.product) {
this.operator = this.product.operator ?? false
this.undeployed = this.product.undeployed ?? false
}
setTimeout(() => {
if (this.usedInWorkspaces?.nativeElement) {
const wList = this.product?.workspaces?.sort(sortByLocale)
this.usedInWorkspaces.nativeElement.innerHTML = wList?.join(', ')
}
}, 2)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="sm:pt-2 pb-2 sm:pb-3 px-3">
<ocx-slot
*ngIf="isListWorkspacesUsingProductComponentDefined$ | async"
[name]="listWorkspacesUsingProductSlotName"
[inputs]="{ productName: product?.name }"
>
</ocx-slot>
<div *ngIf="(isListWorkspacesUsingProductComponentDefined$ | async) === false" id="ps_product_use_error">
<p-message
id="ps_product_use_error_message"
severity="info"
styleClass="p-2"
[text]="'SLOT.NOT_DEFINED' | translate"
></p-message>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'
import { TranslateTestingModule } from 'ngx-translate-testing'

import { ProductUseComponent } from './product-use.component'

describe('ProductUseComponent', () => {
let component: ProductUseComponent
let fixture: ComponentFixture<ProductUseComponent>

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProductUseComponent],
imports: [
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
schemas: [NO_ERRORS_SCHEMA],
providers: [provideHttpClientTesting(), provideHttpClient()]
}).compileComponents()
}))

beforeEach(() => {
fixture = TestBed.createComponent(ProductUseComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component, Input } from '@angular/core'

import { SlotService } from '@onecx/angular-remote-components'
import { Observable } from 'rxjs'
import { Product } from 'src/app/shared/generated'

@Component({
selector: 'app-product-use',
templateUrl: './product-use.component.html'
})
export class ProductUseComponent {
@Input() product: Product | undefined
public isListWorkspacesUsingProductComponentDefined$: Observable<boolean> | undefined
public listWorkspacesUsingProductSlotName = 'onecx-product-list-workspaces-using-product'

constructor(private readonly slotService: SlotService) {
this.isListWorkspacesUsingProductComponentDefined$ = this.slotService.isSomeComponentDefinedForSlot(
this.listWorkspacesUsingProductSlotName
)
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { Location } from '@angular/common'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { Router } from '@angular/router'
import { provideRouter, Router } from '@angular/router'
import { of, throwError } from 'rxjs'
import { TranslateTestingModule } from 'ngx-translate-testing'

import { PortalMessageService, ConfigurationService, UserService } from '@onecx/portal-integration-angular'
import { ProductDetailComponent } from './product-detail.component'
import { ProductPropertyComponent } from './product-props/product-props.component'
import { ProductsAPIService } from 'src/app/shared/generated'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

const product = {
id: 'id',
Expand Down Expand Up @@ -65,14 +65,15 @@ describe('ProductDetailComponent', () => {
TestBed.configureTestingModule({
declarations: [ProductDetailComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [
provideHttpClientTesting(),
provideHttpClient(),
provideRouter([{ path: '', component: ProductDetailComponent }]),
{ provide: ProductsAPIService, useValue: apiServiceSpy },
{ provide: PortalMessageService, useValue: msgServiceSpy },
{ provide: ConfigurationService, useValue: configServiceSpy },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { RouterTestingModule } from '@angular/router/testing'
import { Router } from '@angular/router'
import { provideRouter, Router } from '@angular/router'
import { of, throwError } from 'rxjs'
import { DataViewModule } from 'primeng/dataview'
import { TranslateTestingModule } from 'ngx-translate-testing'
import { Product, ProductAbstract, ProductPageResult, ProductsAPIService } from 'src/app/shared/generated'

import { ProductSearchComponent } from './product-search.component'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

describe('ProductSearchComponent', () => {
let component: ProductSearchComponent
Expand All @@ -30,15 +30,18 @@ describe('ProductSearchComponent', () => {
TestBed.configureTestingModule({
declarations: [ProductSearchComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule,
DataViewModule,
TranslateTestingModule.withTranslations({
de: require('src/assets/i18n/de.json'),
en: require('src/assets/i18n/en.json')
}).withDefaultLanguage('en')
],
providers: [{ provide: ProductsAPIService, useValue: apiProductServiceSpy }],
providers: [
provideHttpClientTesting(),
provideHttpClient(),
provideRouter([{ path: '', component: ProductSearchComponent }]),
{ provide: ProductsAPIService, useValue: apiProductServiceSpy }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents()
}))
Expand Down
2 changes: 2 additions & 0 deletions src/app/product-store/product-store.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ProductInternComponent } from './product-detail/product-intern/product-
import { ProductAppsComponent } from './product-detail/product-apps/product-apps.component'
import { SlotSearchComponent } from './slot-search/slot-search.component'
import { SlotDeleteComponent } from './slot-delete/slot-delete.component'
import { ProductUseComponent } from './product-detail/product-use/product-use.component'

const routes: Routes = [
{
Expand Down Expand Up @@ -65,6 +66,7 @@ const routes: Routes = [
ProductDetailComponent,
ProductPropertyComponent,
ProductInternComponent,
ProductUseComponent,
ProductAppsComponent,
SlotSearchComponent,
SlotDeleteComponent
Expand Down
Loading

0 comments on commit d8e10b6

Please sign in to comment.