diff --git a/.gitignore b/.gitignore
index d7f6b2e..0b0fa46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,20 +17,18 @@ speed-measure-plugin*.json
.idea
.project
.classpath
-.c9/
.history
.settings
.vscode
*.launch
-*.sublime-workspace
# misc
.angular
.eslintcache
-.husky/_
.sass-cache
-.gitlab*
.scannerwork
+.husky/_
+.gitlab*
connect.lock
typings
*.log
diff --git a/package-lock.json b/package-lock.json
index c6c1954..0d66cfe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -41,9 +41,9 @@
"keycloak-angular": "^16.0.1",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
- "primeng": "^17.18.10",
+ "primeng": "^17.18.11",
"rxjs": "7.8.1",
- "tslib": "^2.7.0"
+ "tslib": "^2.8.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.1.2",
@@ -88,7 +88,7 @@
"sonar-scanner": "^3.1.0",
"sonarqube-scanner": "^4.2.3",
"ts-node": "10.9.2",
- "typescript": "5.5",
+ "typescript": "5.5.4",
"url-loader": "^4.1.1",
"webpack": "^5.95.0",
"webpack-merge": "^6.0.1"
diff --git a/package.json b/package.json
index ee0d4d1..fd5d3dc 100644
--- a/package.json
+++ b/package.json
@@ -67,9 +67,9 @@
"keycloak-angular": "^16.0.1",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
- "primeng": "^17.18.10",
+ "primeng": "^17.18.11",
"rxjs": "7.8.1",
- "tslib": "^2.7.0"
+ "tslib": "^2.8.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.1.2",
@@ -114,7 +114,7 @@
"sonar-scanner": "^3.1.0",
"sonarqube-scanner": "^4.2.3",
"ts-node": "10.9.2",
- "typescript": "5.5",
+ "typescript": "5.5.4",
"url-loader": "^4.1.1",
"webpack": "^5.95.0",
"webpack-merge": "^6.0.1"
diff --git a/src/app/_ps-mixins.scss b/src/app/_ps-mixins.scss
index 66b3462..74737ff 100644
--- a/src/app/_ps-mixins.scss
+++ b/src/app/_ps-mixins.scss
@@ -180,7 +180,7 @@
.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item {
padding-top: 0.4rem;
padding-bottom: 0.4rem;
- &:nth-child(odd) {
+ &:nth-child(even) {
background-color: #f8f9fa;
}
}
@@ -377,8 +377,8 @@
@mixin dataview-list-zebra-rows {
:host ::ng-deep {
.p-dataview-list .p-dataview-content .p-grid > div {
- &:nth-child(odd) {
- background-color: #f8f9fa;
+ &:nth-child(even) {
+ background-color: var(--table-body-row-even-bg);
}
}
}
@@ -388,7 +388,7 @@
.p-dataview-list .p-dataview-content .p-grid > div {
&:nth-child(4n + 1),
&:nth-child(4n + 2) {
- background-color: #f8f9fa;
+ background-color: var(--table-body-row-even-bg);
}
}
}
@@ -396,24 +396,24 @@
@mixin dataview-list-flex-zebra-rows {
:host ::ng-deep {
.p-dataview-list .p-dataview-content > div {
- &:nth-child(odd) {
- background-color: #f8f9fa;
+ &:nth-child(even) {
+ background-color: var(--table-body-row-even-bg);
}
}
}
}
@mixin dropdown-zebra-rows {
:host ::ng-deep {
- .p-dropdown-panel .p-dropdown-items *:nth-child(odd) .p-dropdown-item {
- background-color: #f8f9fa;
+ .p-dropdown-panel .p-dropdown-items *:nth-child(even) .p-dropdown-item {
+ background-color: var(--table-body-row-even-bg);
}
}
}
@mixin listbox-zebra-rows {
:host ::ng-deep {
.p-listbox:not(.p-disabled) .p-listbox-item:not(.p-highlight):not(.p-disabled) {
- &:nth-child(odd) {
- background-color: #f8f9fa;
+ &:nth-child(even) {
+ background-color: var(--table-body-row-even-bg);
}
}
}
@@ -421,16 +421,16 @@
@mixin picklist-zebra-rows {
:host ::ng-deep {
.p-picklist-list li {
- &:nth-child(odd) {
- background-color: #f8f9fa;
+ &:nth-child(even) {
+ background-color: var(--table-body-row-even-bg);
}
}
}
}
@mixin table-zebra-rows {
:host ::ng-deep {
- .p-datatable .p-datatable-tbody > tr:nth-child(odd) > td {
- background-color: #f8f9fa;
+ .p-datatable .p-datatable-tbody > tr:nth-child(even) > td {
+ background-color: var(--table-body-row-even-bg);
}
}
}
@@ -490,6 +490,15 @@
}
}
}
+@mixin tabview-fix-color-selected-tab {
+ :host ::ng-deep {
+ // correct the background color on inital selected tab
+ .p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link[aria-selected='true'] {
+ background-color: rgba(var(--primary-color-rgb), 0.12);
+ }
+ }
+}
+
/* **********************************************
* TABLE
* **********************************************/
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2a2fd88..87c994b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,39 +1,39 @@
-import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, NgModule } from '@angular/core'
+import { APP_INITIALIZER, NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
-import { HttpClient, HttpClientModule } from '@angular/common/http'
+import { HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { RouterModule, Routes } from '@angular/router'
import { BrowserModule } from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'
-import {
- APP_CONFIG,
- AppStateService,
- createTranslateLoader,
- translateServiceInitializer,
- PortalCoreModule,
- UserService
-} from '@onecx/portal-integration-angular'
import { KeycloakAuthModule } from '@onecx/keycloak-auth'
+import { createTranslateLoader } from '@onecx/angular-accelerator'
+import { APP_CONFIG, AppStateService, UserService } from '@onecx/angular-integration-interface'
+import { translateServiceInitializer, PortalCoreModule } from '@onecx/portal-integration-angular'
-import { AppComponent } from './app.component'
import { environment } from 'src/environments/environment'
+import { AppComponent } from './app.component'
+
+const routes: Routes = [
+ {
+ path: '',
+ loadChildren: () => import('./product-store/product-store.module').then((m) => m.ProductStoreModule)
+ }
+]
-const routes: Routes = [{ path: '', pathMatch: 'full' }]
@NgModule({
bootstrap: [AppComponent],
declarations: [AppComponent],
imports: [
CommonModule,
BrowserModule,
- HttpClientModule,
- KeycloakAuthModule,
BrowserAnimationsModule,
+ KeycloakAuthModule,
+ PortalCoreModule.forRoot('onecx-product-store-ui'),
RouterModule.forRoot(routes, {
initialNavigation: 'enabledBlocking',
enableTracing: true
}),
- PortalCoreModule.forRoot('onecx-product-store-ui'),
TranslateModule.forRoot({
isolate: true,
loader: {
@@ -50,12 +50,12 @@ const routes: Routes = [{ path: '', pathMatch: 'full' }]
useFactory: translateServiceInitializer,
multi: true,
deps: [UserService, TranslateService]
- }
- ],
- schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA]
+ },
+ provideHttpClient(withInterceptorsFromDi())
+ ]
})
export class AppModule {
constructor() {
- console.info('App Module constructor')
+ console.info('OneCX Product Store Module constructor')
}
}
diff --git a/src/app/onecx-product-store-remote.module.ts b/src/app/onecx-product-store-remote.module.ts
index f78fa93..3cfd0f8 100644
--- a/src/app/onecx-product-store-remote.module.ts
+++ b/src/app/onecx-product-store-remote.module.ts
@@ -1,24 +1,23 @@
-import { HttpClient, HttpClientModule } from '@angular/common/http'
-import { BrowserModule } from '@angular/platform-browser'
import { APP_INITIALIZER, DoBootstrap, Injector, NgModule } from '@angular/core'
-import { Router, RouterModule, Routes } from '@angular/router'
-import { MissingTranslationHandler, TranslateLoader, TranslateModule } from '@ngx-translate/core'
+import { HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
+import { RouterModule, Routes, Router } from '@angular/router'
+import { BrowserModule } from '@angular/platform-browser'
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
+import { TranslateLoader, TranslateModule, MissingTranslationHandler } from '@ngx-translate/core'
+import { AngularAuthModule } from '@onecx/angular-auth'
+import { createTranslateLoader } from '@onecx/angular-accelerator'
+import { createAppEntrypoint, initializeRouter, startsWith } from '@onecx/angular-webcomponents'
+import { addInitializeModuleGuard, AppStateService, ConfigurationService } from '@onecx/angular-integration-interface'
import {
- AppStateService,
- ConfigurationService,
- createTranslateLoader,
PortalApiConfiguration,
PortalCoreModule,
PortalMissingTranslationHandler
} from '@onecx/portal-integration-angular'
-import { addInitializeModuleGuard } from '@onecx/angular-integration-interface'
-import { createAppEntrypoint, initializeRouter, startsWith } from '@onecx/angular-webcomponents'
-import { AppEntrypointComponent } from './app-entrypoint.component'
-import { AngularAuthModule } from '@onecx/angular-auth'
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
-import { environment } from 'src/environments/environment'
+
import { Configuration } from './shared/generated'
+import { environment } from 'src/environments/environment'
+import { AppEntrypointComponent } from './app-entrypoint.component'
function apiConfigProvider(configService: ConfigurationService, appStateService: AppStateService) {
return new PortalApiConfiguration(Configuration, environment.apiPrefix, configService, appStateService)
@@ -30,13 +29,13 @@ const routes: Routes = [
loadChildren: () => import('./product-store/product-store.module').then((m) => m.ProductStoreModule)
}
]
+
@NgModule({
declarations: [AppEntrypointComponent],
imports: [
AngularAuthModule,
- BrowserAnimationsModule,
BrowserModule,
- HttpClientModule,
+ BrowserAnimationsModule,
PortalCoreModule.forMicroFrontend(),
RouterModule.forRoot(addInitializeModuleGuard(routes)),
TranslateModule.forRoot({
@@ -49,18 +48,17 @@ const routes: Routes = [
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: PortalMissingTranslationHandler }
})
],
- exports: [],
providers: [
ConfigurationService,
+ { provide: Configuration, useFactory: apiConfigProvider, deps: [ConfigurationService, AppStateService] },
{
provide: APP_INITIALIZER,
useFactory: initializeRouter,
multi: true,
deps: [Router, AppStateService]
},
- { provide: Configuration, useFactory: apiConfigProvider, deps: [ConfigurationService, AppStateService] }
- ],
- schemas: []
+ provideHttpClient(withInterceptorsFromDi())
+ ]
})
export class OneCXProductStoreModule implements DoBootstrap {
constructor(private readonly injector: Injector) {
diff --git a/src/app/product-store/app-delete/app-delete.component.html b/src/app/product-store/app-delete/app-delete.component.html
index 1c4518b..b686306 100644
--- a/src/app/product-store/app-delete/app-delete.component.html
+++ b/src/app/product-store/app-delete/app-delete.component.html
@@ -10,11 +10,12 @@
-
- {{ ('ACTIONS.DELETE.MESSAGE' | translate).replace("{{ITEM}}", appAbstract?.appId ?? '') }}
+
{{ 'ACTIONS.DELETE.APP.MESSAGE' | translate }}
+
+ {{ appAbstract?.appId }}
-
{{ 'ACTIONS.DELETE.APP.OPERATOR_TEXT' | translate }}
-
{{ 'ACTIONS.DELETE.MESSAGE_INFO' | translate }}
+
{{ 'ACTIONS.DELETE.APP.OPERATOR_TEXT' | translate }}
+
{{ 'ACTIONS.DELETE.MESSAGE_INFO' | translate }}
diff --git a/src/app/product-store/app-detail/app-detail.component.scss b/src/app/product-store/app-detail/app-detail.component.scss
index ca0cb4d..bd65084 100644
--- a/src/app/product-store/app-detail/app-detail.component.scss
+++ b/src/app/product-store/app-detail/app-detail.component.scss
@@ -4,6 +4,8 @@
@include table-zebra-rows;
@include table-inline-buttons;
@include table-vertical-lines;
+@include dialog-footer-buttons;
+@include dialog-modal-dialog-content;
:host ::ng-deep {
/**
diff --git a/src/app/product-store/app-search/app-search.component.html b/src/app/product-store/app-search/app-search.component.html
index e757d6c..f81f26d 100644
--- a/src/app/product-store/app-search/app-search.component.html
+++ b/src/app/product-store/app-search/app-search.component.html
@@ -153,6 +153,7 @@
+
@@ -245,13 +246,20 @@
{{ app.exposedModule }}
+
+ {{ app.appVersion }}
+
+
0"
[toggleable]="false"
[collapsed]="false"
- styleClass="surface-100 py-0 mb-3"
+ styleClass="surface-100 py-0 mt-1 mb-3 mx-1"
>
diff --git a/src/app/product-store/product-detail/product-detail.component.html b/src/app/product-store/product-detail/product-detail.component.html
index 4f459eb..a4918d8 100644
--- a/src/app/product-store/product-detail/product-detail.component.html
+++ b/src/app/product-store/product-detail/product-detail.component.html
@@ -8,30 +8,41 @@
[figureBackground]="!currentLogoUrl"
>
-
-
+
+
+
+
+
@@ -40,12 +51,17 @@
id="ps_product_detail_panel_intern"
[disabled]="changeMode !== 'VIEW'"
[header]="'DIALOG.TABS.INTERN' | translate"
+ [attr.aria-label]="'DIALOG.TABS.INTERN' | translate"
[tooltip]="'DIALOG.TABS.TOOLTIPS.INTERN' | translate"
+ tooltipPosition="top"
+ tooltipEvent="hover"
>
@@ -68,9 +87,11 @@
-
- {{('ACTIONS.DELETE.MESSAGE' | translate).replace('{{ITEM}}', product?.name)}}
+
{{ 'ACTIONS.DELETE.PRODUCT.MESSAGE' | translate }}
+
+ {{ product?.name }}
-
{{ 'ACTIONS.DELETE.PRODUCT.OPERATOR_TEXT' | translate }}
+
{{ 'ACTIONS.DELETE.PRODUCT.OPERATOR_TEXT' | translate }}
{{ 'ACTIONS.DELETE.MESSAGE_INFO' | translate }}
@@ -92,6 +114,7 @@
icon="pi pi-times"
(onClick)="productDeleteVisible = false"
[label]="'ACTIONS.CONFIRMATION.NO' | translate"
+ [ariaLabel]="'ACTIONS.CONFIRMATION.NO' | translate"
[pTooltip]="'ACTIONS.CONFIRMATION.NO.TOOLTIP' | translate"
tooltipPosition="top"
tooltipEvent="hover"
@@ -101,6 +124,7 @@
icon="pi pi-check"
(onClick)="onDeleteConfirmation()"
[label]="'ACTIONS.CONFIRMATION.YES' | translate"
+ [ariaLabel]="'ACTIONS.CONFIRMATION.YES' | translate"
[pTooltip]="'ACTIONS.CONFIRMATION.YES.TOOLTIP' | translate"
tooltipPosition="top"
tooltipEvent="hover"
diff --git a/src/app/product-store/product-detail/product-detail.component.scss b/src/app/product-store/product-detail/product-detail.component.scss
index 9f747cc..339151f 100644
--- a/src/app/product-store/product-detail/product-detail.component.scss
+++ b/src/app/product-store/product-detail/product-detail.component.scss
@@ -7,3 +7,4 @@
@include dialog-footer-buttons;
@include dialog-non-full-size-modal;
@include displaying-text-responsive;
+@include tabview-fix-color-selected-tab;
diff --git a/src/app/product-store/product-detail/product-detail.component.ts b/src/app/product-store/product-detail/product-detail.component.ts
index e769d16..7d40eb5 100644
--- a/src/app/product-store/product-detail/product-detail.component.ts
+++ b/src/app/product-store/product-detail/product-detail.component.ts
@@ -1,7 +1,7 @@
import { Component, OnInit, ViewChild } from '@angular/core'
import { Location } from '@angular/common'
import { ActivatedRoute, Router } from '@angular/router'
-import { Observable, finalize, map } from 'rxjs'
+import { catchError, Observable, of, finalize, map } from 'rxjs'
import { TranslateService } from '@ngx-translate/core'
import { Action, PortalMessageService, UserService } from '@onecx/portal-integration-angular'
@@ -22,12 +22,14 @@ export type ChangeMode = 'VIEW' | 'CREATE' | 'EDIT' | 'COPY'
styleUrls: ['./product-detail.component.scss']
})
export class ProductDetailComponent implements OnInit {
+ public exceptionKey: string | undefined
+ public loading = false
public actions$: Observable | undefined
- public productName: string
+ public productName: string | null = null
+ public product$!: Observable
public product: ProductAndWorkspaces | undefined
public product_for_apps: ProductAndWorkspaces | undefined
- public changeMode: ChangeMode = 'CREATE'
- public loading = false
+ public changeMode: ChangeMode = 'VIEW'
public dateFormat = 'medium'
public headerImageUrl?: string
public productDeleteVisible = false
@@ -48,46 +50,45 @@ export class ProductDetailComponent implements OnInit {
private readonly translate: TranslateService
) {
this.dateFormat = this.user.lang$.getValue() === 'de' ? 'dd.MM.yyyy HH:mm:ss' : 'medium'
- this.productName = this.route.snapshot.paramMap.get('name') || ''
+ this.productName = this.route.snapshot.paramMap.get('name')
}
ngOnInit(): void {
- if (this.productName !== '') {
+ this.product = undefined
+ if (this.productName) {
this.changeMode = 'VIEW'
this.getProduct()
} else {
- this.product = undefined
+ this.changeMode = 'CREATE'
+ this.product$ = of({} as ProductAndWorkspaces)
this.prepareActionButtons()
}
}
- public onTabChange($event: any) {
+ public onTabChange($event: any, product: ProductAndWorkspaces) {
this.selectedTabIndex = $event.index
- this.prepareActionButtons()
- if (this.selectedTabIndex === 2) this.product_for_apps = this.product // lazy load
+ this.prepareActionButtons(product)
+ if (this.selectedTabIndex === 3) this.product_for_apps = product // lazy load
}
- public getProduct() {
+ public getProduct(): void {
this.loading = true
- this.productApi
- .getProductByName({ name: this.productName })
- .pipe(
- finalize(() => {
- this.loading = false
- })
- )
- .subscribe({
- next: (data: any) => {
- if (data) {
- this.product = data
- this.prepareActionButtons()
- this.currentLogoUrl = this.getLogoUrl(this.product!)
- }
- }
- })
- }
-
- public prepareActionButtons(): void {
+ this.product$ = this.productApi.getProductByName({ name: this.productName! }).pipe(
+ map((data: ProductAndWorkspaces) => {
+ this.prepareActionButtons(data)
+ this.currentLogoUrl = this.getLogoUrl(data)
+ return data
+ }),
+ catchError((err) => {
+ this.exceptionKey = 'EXCEPTIONS.HTTP_STATUS_' + err.status + '.PRODUCT'
+ console.error('getProductByName():', err)
+ return of({} as ProductAndWorkspaces)
+ }),
+ finalize(() => (this.loading = false))
+ )
+ }
+
+ public prepareActionButtons(product?: ProductAndWorkspaces): void {
this.actions$ = this.translate
.get([
'ACTIONS.COPY.LABEL',
@@ -114,17 +115,7 @@ export class ProductDetailComponent implements OnInit {
icon: 'pi pi-arrow-left',
show: 'always',
conditional: true,
- showCondition: this.changeMode === 'VIEW'
- },
- {
- label: data['ACTIONS.COPY.LABEL'],
- title: data['ACTIONS.COPY.PRODUCT.HEADER'],
- actionCallback: () => this.onCopy(),
- icon: 'pi pi-copy',
- show: 'always',
- conditional: true,
- showCondition: this.selectedTabIndex === 0 && this.changeMode === 'VIEW' && this.product !== undefined,
- permission: 'PRODUCT#CREATE'
+ showCondition: product && this.changeMode === 'VIEW'
},
{
label: data['ACTIONS.EDIT.LABEL'],
@@ -136,8 +127,8 @@ export class ProductDetailComponent implements OnInit {
showCondition:
this.selectedTabIndex === 0 &&
this.changeMode === 'VIEW' &&
- this.product !== undefined &&
- !this.product.undeployed,
+ product !== undefined &&
+ !product.undeployed,
permission: 'PRODUCT#EDIT'
},
{
@@ -159,17 +150,24 @@ export class ProductDetailComponent implements OnInit {
showCondition: this.changeMode !== 'VIEW',
permission: 'PRODUCT#EDIT'
},
+ {
+ label: data['ACTIONS.COPY.LABEL'],
+ title: data['ACTIONS.COPY.PRODUCT.HEADER'],
+ actionCallback: () => this.onCopy(product),
+ icon: 'pi pi-copy',
+ show: 'asOverflow',
+ conditional: true,
+ showCondition: this.selectedTabIndex === 0 && this.changeMode === 'VIEW' && product !== undefined,
+ permission: 'PRODUCT#CREATE'
+ },
{
label: data['ACTIONS.DELETE.LABEL'],
title: data['ACTIONS.DELETE.PRODUCT.TOOLTIP'],
- actionCallback: () => {
- this.productDeleteMessage = data['ACTIONS.DELETE.MESSAGE'].replace('{{ITEM}}', this.product?.name)
- this.productDeleteVisible = true
- },
+ actionCallback: () => this.onDelete(product),
icon: 'pi pi-trash',
show: 'asOverflow',
conditional: true,
- showCondition: this.changeMode === 'VIEW' && this.product !== undefined,
+ showCondition: this.changeMode === 'VIEW' && product !== undefined,
permission: 'PRODUCT#DELETE'
}
]
@@ -184,9 +182,9 @@ export class ProductDetailComponent implements OnInit {
this.close()
}
- public onCopy(): void {
+ public onCopy(item: any): void {
this.changeMode = 'COPY'
- this.prepareActionButtons()
+ this.prepareActionButtons(item)
}
public onEdit() {
this.changeMode = 'EDIT'
@@ -204,20 +202,20 @@ export class ProductDetailComponent implements OnInit {
this.productPropsComponent.onSave()
}
- public onCreate(data: any) {
- this.product = data
+ public onRouteToCreatedProduct(product: any) {
this.changeMode = 'VIEW'
- this.router.navigate(['./../', this.product?.name], { relativeTo: this.route })
+ this.router.navigate(['../', product?.name], { relativeTo: this.route })
}
- public onChange() {
+ public onChange(product?: Product) {
this.changeMode = 'VIEW'
+ // update observable with response data => null
+ // this.product$ = new Observable((sub) => sub.next(product as ProductAndWorkspaces))
this.getProduct()
}
- public onDelete(ev: MouseEvent, item: Product): void {
- ev.stopPropagation()
- this.product = item
+ public onDelete(product?: Product): void {
+ this.product = product
this.productDeleteVisible = true
}
public onDeleteConfirmation(): void {
diff --git a/src/app/product-store/product-detail/product-intern/product-intern.component.html b/src/app/product-store/product-detail/product-intern/product-intern.component.html
index 4f21f7b..a201370 100644
--- a/src/app/product-store/product-detail/product-intern/product-intern.component.html
+++ b/src/app/product-store/product-detail/product-intern/product-intern.component.html
@@ -1,97 +1,95 @@
-
-
diff --git a/src/app/product-store/product-detail/product-props/product-props.component.html b/src/app/product-store/product-detail/product-props/product-props.component.html
index 2f9d54e..f895872 100644
--- a/src/app/product-store/product-detail/product-props/product-props.component.html
+++ b/src/app/product-store/product-detail/product-props/product-props.component.html
@@ -1,5 +1,5 @@