Skip to content

Commit

Permalink
Update service for rest client
Browse files Browse the repository at this point in the history
  • Loading branch information
nntthuy-axonivy committed Jul 26, 2024
1 parent 661b860 commit 034bbc2
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ public ResponseEntity<PagedModel<ProductModel>> findProducts(@RequestParam(name
return new ResponseEntity<>(pageResources, HttpStatus.OK);
}

@GetMapping("/designer")
public ResponseEntity<PagedModel<ProductModel>> findProductsInDesigner(@RequestParam(required = false, name = "search") String search,
Pageable pageable) {
Page<Product> results = productService.findProductsInDesigner(search, pageable);
if (results.isEmpty()) {
return generateEmptyPagedModel();
}
var responseContent = new PageImpl<>(results.getContent(), pageable, results.getTotalElements());
var pageResources = pagedResourcesAssembler.toModel(responseContent, assembler);
return new ResponseEntity<>(pageResources, HttpStatus.OK);
}

@PutMapping(SYNC)
public ResponseEntity<Message> syncProducts(@RequestHeader(value = "Authorization") String authorizationHeader,
@RequestParam(value = "resetSync", required = false) Boolean resetSync) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ public interface ProductRepository extends MongoRepository<Product, String> {

Product findByLogoUrl(String logoUrl);

Product findByIdAndType(String id, String type);

Optional<Product> findById(String productId);

@Query("{'marketDirectory': {$regex : ?0, $options: 'i'}}")
Expand All @@ -28,4 +26,7 @@ public interface ProductRepository extends MongoRepository<Product, String> {

@Query("{ $or: [ { 'names.?1': { $regex: ?0, $options: 'i' } }, { 'shortDescriptions.?1': { $regex: ?0, $options: 'i' } } ] }")
Page<Product> searchByNameOrShortDescriptionRegex(String keyword, String language, Pageable unifiedPageabe);

@Query("{ $and: [ { $or: [ { 'names.?': { $regex: ?0, $options: 'i' } } ] }")
Page<Product> searchByNameAndType(String search, String type, String language, Pageable unifiedPageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
public interface ProductService {
Page<Product> findProducts(String type, String keyword, String language, Pageable pageable);

Page<Product> findProductsInDesigner(String search, Pageable pageable);

boolean syncLatestDataFromMarketRepo();

int updateInstallationCountForProduct(String key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.FileType;
import com.axonivy.market.enums.Language;
import com.axonivy.market.enums.SortOption;
import com.axonivy.market.enums.TypeOption;
import com.axonivy.market.factory.ProductFactory;
Expand Down Expand Up @@ -107,6 +108,18 @@ public Page<Product> findProducts(String type, String keyword, String language,
return result;
}

@Override
public Page<Product> findProductsInDesigner(String search, Pageable pageable) {
final var searchPageable = refinePagination(Language.EN.getValue(), pageable);
Page<Product> result;
if (StringUtils.isBlank(search)) {
result = productRepository.findByType(TypeOption.CONNECTORS.getCode(), searchPageable);
} else {
result = productRepository.searchByNameAndType(search, TypeOption.CONNECTORS.getCode(), Language.EN.getValue(), searchPageable);
}
return result;
}

@Override
public boolean syncLatestDataFromMarketRepo() {
var isAlreadyUpToDate = isLastGithubCommitCovered();
Expand Down
64 changes: 49 additions & 15 deletions marketplace-ui/src/app/cookie.management.service.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,98 @@

import { computed, Injectable, Signal, signal } from '@angular/core';
import { computed, Injectable, signal } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { DESIGNER_COOKIE_VARIABLE } from './shared/constants/common.constant';
import {
Router,
NavigationEnd,
Params,
NavigationStart
NavigationStart,
ActivatedRoute
} from '@angular/router';
import { Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class CookieManagementService {
private isDesigner = signal(false);
isDesigner = signal(false);
isDesignerEnv = computed(() => this.isDesigner());
designerVersion = signal('');
resultsOnly = WritableS
isResultsOnly = computed(() => this.resultsOnly());

constructor(private cookieService: CookieService, private router: Router) {
this.getNavigationStartEvent().subscribe(()=> {
constructor(
private cookieService: CookieService,
private router: Router,
private route: ActivatedRoute
) {
this.getNavigationStartEvent().subscribe(() => {
if (!this.isDesigner()) {
this.isDesigner.set(this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyViewerParamName) == DESIGNER_COOKIE_VARIABLE.defaultDesignerViewer);
this.isDesigner.set(
this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyViewerParamName) ==
DESIGNER_COOKIE_VARIABLE.defaultDesignerViewer
);
}
})
});
}

ngOnInit(): void {
// Accessing query parameters
this.resultsOnly = this.route.snapshot.queryParamMap.has('resultsOnly');
console.log('resultsOnly:', this.resultsOnly);
}

// ngOnInit(): void {
// this.route.queryParams.subscribe(params => {
// if (params['resultsOnly']) {
// this.resultsOnly.set(true);
// console.log('resultsOnly:', this.resultsOnly);
// }
// });
// }

checkCookieForDesignerVersion(params: Params) {
const versionParam = params[DESIGNER_COOKIE_VARIABLE.ivyVersionParamName];
if (versionParam != undefined) {
this.cookieService.set(DESIGNER_COOKIE_VARIABLE.ivyVersionParamName, versionParam);
this.cookieService.set(
DESIGNER_COOKIE_VARIABLE.ivyVersionParamName,
versionParam
);
this.designerVersion.set(versionParam);
}
}

checkCookieForDesignerEnv(params: Params) {
const ivyViewerParam = params[DESIGNER_COOKIE_VARIABLE.ivyViewerParamName];
if (ivyViewerParam == DESIGNER_COOKIE_VARIABLE.defaultDesignerViewer) {
this.cookieService.set(DESIGNER_COOKIE_VARIABLE.ivyViewerParamName, ivyViewerParam);
this.cookieService.set(
DESIGNER_COOKIE_VARIABLE.ivyViewerParamName,
ivyViewerParam
);
this.isDesigner.set(true);
}
}

getDesignerVersionFromCookie() {
if (this.designerVersion() == '') {
this.designerVersion.set(this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyVersionParamName))
this.designerVersion.set(
this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyVersionParamName)
);
}
return this.designerVersion();
}

isDesignerViewer() {
if (!this.isDesigner()) {
this.isDesigner.set(this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyViewerParamName) == DESIGNER_COOKIE_VARIABLE.defaultDesignerViewer);
this.isDesigner.set(
this.cookieService.get(DESIGNER_COOKIE_VARIABLE.ivyViewerParamName) ==
DESIGNER_COOKIE_VARIABLE.defaultDesignerViewer
);
}
return this.isDesigner();
}

getNavigationStartEvent():Observable<NavigationStart>{
getNavigationStartEvent(): Observable<NavigationStart> {
return this.router.events.pipe(
filter(event => event instanceof NavigationStart)
) as Observable<NavigationStart>;
}
}
}
48 changes: 25 additions & 23 deletions marketplace-ui/src/app/modules/product/product.component.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
<div class="container">
<div class="row col-md-12 mt-8">
<h1 class="text-primary">
{{ translateService.get('common.branch') | async }}
</h1>
<div class="d-sm-block col-md-6">
<h3 class="text-secondary">
{{ translateService.get('common.introduction.about') | async }}
</h3>
</div>
<div class="d-sm-block col-md-6 align-items-center">
<h4 class="text-secondary">
{{ translateService.get('common.introduction.contribute') | async }}
</h4>
<h4
class="text-secondary"
[innerHTML]="
translateService.get('common.introduction.link') | async
"></h4>
@if (!isRestClient()) {
<div class="row col-md-12 mt-8">
<h1 class="text-primary">
{{ translateService.get('common.branch') | async }}
</h1>
<div class="d-sm-block col-md-6">
<h3 class="text-secondary">
{{ translateService.get('common.introduction.about') | async }}
</h3>
</div>
<div class="d-sm-block col-md-6 align-items-center">
<h4 class="text-secondary">
{{ translateService.get('common.introduction.contribute') | async }}
</h4>
<h4
class="text-secondary"
[innerHTML]="
translateService.get('common.introduction.link') | async
"></h4>
</div>
</div>
</div>

<app-product-filter
(searchChange)="onSearchChanged($event)"
(filterChange)="onFilterChange($event)"
(sortChange)="onSortChange($event)"></app-product-filter>
<app-product-filter
(searchChange)="onSearchChanged($event)"
(filterChange)="onFilterChange($event)"
(sortChange)="onSortChange($event)"></app-product-filter>
}

@if (products().length > 0) {
<div class="row product-container">
Expand Down
80 changes: 66 additions & 14 deletions marketplace-ui/src/app/modules/product/product.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
WritableSignal
} from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NavigationStart, Router } from '@angular/router';
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { debounceTime, Subject, Subscription } from 'rxjs';
import { ThemeService } from '../../core/services/theme/theme.service';
Expand All @@ -27,6 +27,7 @@ import { Page } from '../../shared/models/apis/page.model';
import { Language } from '../../shared/enums/language.enum';
import { ProductDetail } from '../../shared/models/product-detail.model';
import { LanguageService } from '../../core/services/language/language.service';
import { CookieManagementService } from '../../cookie.management.service';

const SEARCH_DEBOUNCE_TIME = 500;

Expand Down Expand Up @@ -55,30 +56,58 @@ export class ProductComponent implements AfterViewInit, OnDestroy {
sort: SortOption.POPULARITY,
language: Language.EN
};

designerCriteria: Criteria = {
search: '',
type: TypeOption.CONNECTORS,
sort: SortOption.POPULARITY,
language: Language.EN
};

responseLink!: Link;
responsePage!: Page;
isRestClient = signal(false);

productService = inject(ProductService);
themeService = inject(ThemeService);
translateService = inject(TranslateService);
languageService = inject(LanguageService);
cookieService = inject(CookieManagementService);

router = inject(Router);
@ViewChild('observer', { static: true }) observerElement!: ElementRef;

constructor() {
this.loadProductItems();
this.subscriptions.push(
this.searchTextChanged
.pipe(debounceTime(SEARCH_DEBOUNCE_TIME))
.subscribe(value => {
this.criteria = {
...this.criteria,
search: value
};
this.loadProductItems(true);
})
);
this.isRestClient.set(this.cookieService.isResultsOnly());
console.log(this.isRestClient());
if (this.isRestClient()) {
this.loadProductInDesigner();
this.subscriptions.push(
this.searchTextChanged
.pipe(debounceTime(SEARCH_DEBOUNCE_TIME))
.subscribe(value => {
this.designerCriteria = {
...this.designerCriteria,
search: value
};
this.loadProductInDesigner(true);
})
);
} else {
this.loadProductItems();
this.subscriptions.push(
this.searchTextChanged
.pipe(debounceTime(SEARCH_DEBOUNCE_TIME))
.subscribe(value => {
this.criteria = {
...this.criteria,
search: value
};
this.loadProductItems(true);
})
);
}

this.router.events?.subscribe(event => {
if (!(event instanceof NavigationStart)) {
return;
Expand Down Expand Up @@ -137,13 +166,36 @@ export class ProductComponent implements AfterViewInit, OnDestroy {
);
}

loadProductInDesigner(shouldCleanData = false) {
this.subscriptions.push(
this.productService
.findProductsInDesignerByCriteria(this.designerCriteria)
.subscribe((response: ProductApiResponse) => {
const newProducts = response._embedded.products;
if (shouldCleanData) {
this.products.set(newProducts);
} else {
this.products.update(existingProducts =>
existingProducts.concat(newProducts)
);
}
this.responseLink = response._links;
this.responsePage = response.page;
})
);
}

setupIntersectionObserver() {
const options = { root: null, rootMargin: '0px', threshold: 0.1 };
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && this.hasMore()) {
this.criteria.nextPageHref = this.responseLink?.next?.href;
this.loadProductItems();
if (this.isRestClient()) {
this.loadProductInDesigner();
} else {
this.loadProductItems();
}
}
});
}, options);
Expand Down
Loading

0 comments on commit 034bbc2

Please sign in to comment.