Skip to content

Commit

Permalink
MARP-1293 Improve performance when navigating between homepage and pr…
Browse files Browse the repository at this point in the history
…oduct detail page (#211)
  • Loading branch information
vhhoang-axonivy authored Oct 24, 2024
1 parent 4621e97 commit c65c39c
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
class="product-detail-container d-flex flex-column justify-content-center p-0">
<div class="flexible-gap d-flex flex-column justify-content-center">
<div class="link-to-main align-content-center">
<a
href=""
class="back-link text-decoration-none"
<div
id="back-to-homepage-button"
[ngClass]="
themeService.isDarkMode() ? 'text-light' : 'text-link-blue'
">
"
(click)="onClickingBackToHomepageButton()">
&lt;
<span [lang]="languageService.selectedLanguage()">
{{ 'common.product.detail.backToMainPage' | translate }}
</span>
</a>
</div>
</div>
<div class="version-gap d-flex flex-column flex-xl-row justify-content-between">
<div class="connector-title-container d-flex flex-column module-gap">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
}
}

.back-link {
#back-to-homepage-button {
font-size: 1.6rem;
font-weight: 500;
line-height: 120%;
cursor: pointer;
}

.analysis-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { DisplayValue } from '../../../shared/models/display-value.model';
import { CookieService } from 'ngx-cookie-service';
import { ROUTER } from '../../../shared/constants/router.constant';
import { Title } from '@angular/platform-browser';
import { API_URI } from '../../../shared/constants/api.constant';

export interface DetailTab {
activeClass: string;
Expand Down Expand Up @@ -166,6 +167,10 @@ export class ProductDetailComponent {
this.updateDropdownSelection();
}

onClickingBackToHomepageButton() {
this.router.navigate([API_URI.APP]);
}

onLogoError() {
this.logoUrl = DEFAULT_IMAGE_URL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h4 [lang]="languageService.selectedLanguage()" class="text-secondary">
@if (products().length > 0) {
<div class="row product-container">
@for (product of products(); track product.id) {
<div (click)="viewProductDetail(product.id, '')" class="col-sm-12 col-md-6 col-lg-4 col-xxl-3 mt-2 mb-2">
<div (click)="viewProductDetail(product.id, '')" class="product-card col-sm-12 col-md-6 col-lg-4 col-xxl-3 mt-2 mb-2">
<app-product-card [product]="product" [tabIndex]="product.id"></app-product-card>
</div>
}
Expand Down
48 changes: 39 additions & 9 deletions marketplace-ui/src/app/modules/product/product.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '@angular/core/testing';

import { provideHttpClient } from '@angular/common/http';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, provideRouter, Router } from '@angular/router';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { of, Subscription } from 'rxjs';
import { TypeOption } from '../../shared/enums/type-option.enum';
Expand All @@ -17,16 +17,17 @@ import { MockProductService } from '../../shared/mocks/mock-services';
import { RoutingQueryParamService } from '../../shared/services/routing.query.param.service';
import { DESIGNER_COOKIE_VARIABLE } from '../../shared/constants/common.constant';
import { ItemDropdown } from '../../shared/models/item-dropdown.model';

const router = {
navigate: jasmine.createSpy('navigate')
};
import { By } from '@angular/platform-browser';
import { Location } from '@angular/common';
import { ProductDetailComponent } from './product-detail/product-detail.component';

describe('ProductComponent', () => {
let component: ProductComponent;
let fixture: ComponentFixture<ProductComponent>;
let mockIntersectionObserver: any;
let routingQueryParamService: jasmine.SpyObj<RoutingQueryParamService>;
let location: Location;
let router: Router;

beforeAll(() => {
mockIntersectionObserver = jasmine.createSpyObj('IntersectionObserver', [
Expand Down Expand Up @@ -65,10 +66,6 @@ describe('ProductComponent', () => {
await TestBed.configureTestingModule({
imports: [ProductComponent, TranslateModule.forRoot()],
providers: [
{
provide: Router,
useValue: router
},
{
provide: ActivatedRoute,
useValue: {
Expand All @@ -81,6 +78,12 @@ describe('ProductComponent', () => {
provide: RoutingQueryParamService,
useValue: routingQueryParamService
},
provideRouter([
{
path: ':id',
component: ProductDetailComponent
}
]),
ProductService,
TranslateService,
provideHttpClient()
Expand All @@ -93,12 +96,17 @@ describe('ProductComponent', () => {
}
})
.compileComponents();

location = TestBed.inject(Location);
router = TestBed.inject(Router);

routingQueryParamService = TestBed.inject(
RoutingQueryParamService
) as jasmine.SpyObj<RoutingQueryParamService>;

fixture = TestBed.createComponent(ProductComponent);
component = fixture.componentInstance;

fixture.detectChanges();
});

Expand Down Expand Up @@ -196,6 +204,10 @@ describe('ProductComponent', () => {
});

it('should set isRESTClient true based on query params and designer environment', () => {
component.route.queryParams = of({
[DESIGNER_COOKIE_VARIABLE.restClientParamName]: 'resultsOnly',
});

routingQueryParamService.isDesignerEnv.and.returnValue(true);
const fixtureTest = TestBed.createComponent(ProductComponent);
component = fixtureTest.componentInstance;
Expand All @@ -215,4 +227,22 @@ describe('ProductComponent', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.row col-md-12 mt-8')).toBeNull();
});

it('should navigate to product detail page when clicking on a product card', async () => {
routingQueryParamService.isDesignerEnv.and.returnValue(false);
const fixtureTest = TestBed.createComponent(ProductComponent);
component = fixtureTest.componentInstance;

expect(component.isRESTClient()).toBeFalse();

const productName = 'amazon-comprehend';

const productCardComponent = fixture.debugElement.query(
By.css('.product-card')
).nativeElement as HTMLDivElement;

productCardComponent.click();
await router.navigate([productName]);
expect(location.path()).toBe('/amazon-comprehend');
});
});
5 changes: 4 additions & 1 deletion marketplace-ui/src/app/modules/product/product.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ export class ProductComponent implements AfterViewInit, OnDestroy {
}

viewProductDetail(productId: string, _productTag: string) {
window.location.href = `/${productId}`;
if(this.isRESTClient()) {
window.location.href = `/${productId}`;
}
this.router.navigate([`/${productId}`]);
}

onFilterChange(selectedType: ItemDropdown<TypeOption>) {
Expand Down

0 comments on commit c65c39c

Please sign in to comment.