Skip to content

Commit

Permalink
Adapt product custom sort standard
Browse files Browse the repository at this point in the history
  • Loading branch information
ndkhanh-axonivy committed Jul 29, 2024
1 parent ea583c0 commit b175230
Show file tree
Hide file tree
Showing 16 changed files with 78 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class ProductJsonConstants {
public static final String MAVEN_IMPORT_INSTALLER_ID = "maven-import";
public static final String MAVEN_DROPIN_INSTALLER_ID = "maven-dropins";
public static final String MAVEN_DEPENDENCY_INSTALLER_ID = "maven-dependency";
public static final String CUSTOM_ORDER = "customOrder";

private ProductJsonConstants() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,6 @@ public ResponseEntity<Message> syncProducts(@RequestHeader(value = CommonConstan
return new ResponseEntity<>(message, HttpStatus.OK);
}

@GetMapping(CUSTOM_SORT)
public ResponseEntity<List<String>> getCustomSortProducts(@RequestHeader(value = CommonConstants.AUTHORIZATION) String authorizationHeader) {
String token = getBearerToken(authorizationHeader);
gitHubService.validateUserOrganization(token, GitHubConstants.AXONIVY_MARKET_ORGANIZATION_NAME);
return new ResponseEntity<>(productService.getCustomSortProduct(), HttpStatus.OK);
}

@PostMapping(CUSTOM_SORT)
public ResponseEntity<Message> createCustomSortProducts(@RequestHeader(value = CommonConstants.AUTHORIZATION) String authorizationHeader,
@RequestBody @Valid ProductCustomSortRequest productCustomSortRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class Product implements Serializable {
private List<ProductModuleContent> productModuleContents;
private List<MavenArtifact> artifacts;
private Boolean synchronizedInstallationCount;
private Integer customOrder;

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@
@NoArgsConstructor
@Document(PRODUCT_CUSTOM_SORT)
public class ProductCustomSort {
private List<ProductSortEntry> orderedListOfProducts;
private String ruleForRemainder;
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;

@Getter
@AllArgsConstructor
public enum SortOption {
POPULARITY("popularity", "installationCount"), ALPHABETICALLY("alphabetically", "names"),
RECENT("recent", "newestPublishedDate");
POPULARITY("popularity", "installationCount", Sort.Direction.DESC),
ALPHABETICALLY("alphabetically", "names", Sort.Direction.ASC),
RECENT("recent", "newestPublishedDate", Sort.Direction.DESC),
STANDARD("standard", "customOrder", Sort.Direction.DESC);

private String option;
private String code;
private Sort.Direction direction;

public static SortOption of(String option) {
option = StringUtils.isBlank(option) ? option : option.trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ public class ProductCustomSortRequest {
@NotEmpty(message = "orderedListOfProducts must not be empty")
private List<String> orderedListOfProducts;

@NotBlank(message = "sortRuleForRemainder must not be null or blank")
private String sortRuleForRemainder;

@NotBlank(message = "sortDirectionForRemainder must not be null or blank")
private String sortDirectionForRemainder;
@NotBlank(message = "ruleForRemainder must not be null or blank")
private String ruleForRemainder;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
Expand All @@ -28,7 +29,4 @@ 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(value = "{ $and: [{ type: ?0 }, { $addFields: { customOrder: { $switch: { branches: [ { case: { $eq: [_id, customIdList] }, then: 1 } ], default: 3 } } } } , { $sort: { customOrder: 1, newestPublishedDate: sortDirection } } ] }", count = true)
Page<Product> findByTypeAndCustomOrderAndSort(String type, List<String> customIdList, Sort.Direction sortDirection, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,4 @@ public interface ProductService {
void clearAllProducts();

void addCustomSortProduct(ProductCustomSortRequest customSort) throws InvalidParamException;

List<String> getCustomSortProduct();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.entity.*;
import com.axonivy.market.enums.*;
import com.axonivy.market.constants.ProductJsonConstants;
import com.axonivy.market.entity.GitHubRepoMeta;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductCustomSort;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.ErrorCode;
import com.axonivy.market.enums.FileType;
import com.axonivy.market.enums.SortOption;
import com.axonivy.market.enums.TypeOption;
import com.axonivy.market.exceptions.model.InvalidParamException;
import com.axonivy.market.factory.ProductFactory;
import com.axonivy.market.github.model.GitHubFile;
Expand Down Expand Up @@ -33,6 +40,9 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

Expand Down Expand Up @@ -62,6 +72,8 @@ public class ProductServiceImpl implements ProductService {
private final GitHubService gitHubService;
private final ProductCustomSortRepository productCustomSortRepository;

private final MongoTemplate mongoTemplate;

private GHCommit lastGHCommit;
private GitHubRepoMeta marketRepoMeta;
private final ObjectMapper mapper = new ObjectMapper();
Expand All @@ -71,15 +83,18 @@ public class ProductServiceImpl implements ProductService {

public static final String NON_NUMERIC_CHAR = "[^0-9.]";
private final SecureRandom random = new SecureRandom();

public ProductServiceImpl(ProductRepository productRepository, GHAxonIvyMarketRepoService axonIvyMarketRepoService,
GHAxonIvyProductRepoService axonIvyProductRepoService, GitHubRepoMetaRepository gitHubRepoMetaRepository,
GitHubService gitHubService, ProductCustomSortRepository productCustomSortRepository) {
GHAxonIvyProductRepoService axonIvyProductRepoService, GitHubRepoMetaRepository gitHubRepoMetaRepository,
GitHubService gitHubService, ProductCustomSortRepository productCustomSortRepository,
MongoTemplate mongoTemplate) {
this.productRepository = productRepository;
this.axonIvyMarketRepoService = axonIvyMarketRepoService;
this.axonIvyProductRepoService = axonIvyProductRepoService;
this.gitHubRepoMetaRepository = gitHubRepoMetaRepository;
this.gitHubService = gitHubService;
this.productCustomSortRepository = productCustomSortRepository;
this.mongoTemplate = mongoTemplate;
}

@Override
Expand Down Expand Up @@ -140,7 +155,8 @@ private void syncInstallationCountWithProduct(Product product) {
try {
String installationCounts = Files.readString(Paths.get(installationCountPath));
Map<String, Integer> mapping = mapper.readValue(installationCounts,
new TypeReference<HashMap<String, Integer>>(){});
new TypeReference<HashMap<String, Integer>>() {
});
List<String> keyList = mapping.keySet().stream().toList();
int currentInstallationCount = keyList.contains(product.getId())
? mapping.get(product.getId())
Expand Down Expand Up @@ -244,15 +260,32 @@ private Pageable refinePagination(String language, Pageable pageable) {
if (pageable != null) {
List<Order> orders = new ArrayList<>();
for (var sort : pageable.getSort()) {
final var sortOption = SortOption.of(sort.getProperty());
Order order = new Order(sort.getDirection(), sortOption.getCode(language));
SortOption sortOption = SortOption.of(sort.getProperty());
Order order = createOrder(sortOption, language);
orders.add(order);
if (SortOption.STANDARD.equals(sortOption)) {
orders.add(getExtensionOrder(language));
}
}
pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(orders));
}
return pageRequest;
}

private Order createOrder(SortOption sortOption, String language) {
return new Order(sortOption.getDirection(), sortOption.getCode(language));
}

private Order getExtensionOrder(String language) {
List<ProductCustomSort> customSorts = productCustomSortRepository.findAll();

if (!customSorts.isEmpty()) {
SortOption sortOptionExtension = SortOption.of(customSorts.get(0).getRuleForRemainder());
return createOrder(sortOptionExtension, language);
}
return createOrder(SortOption.POPULARITY, language);
}

private boolean isLastGithubCommitCovered() {
boolean isLastCommitCovered = false;
long lastCommitTime = 0L;
Expand Down Expand Up @@ -352,39 +385,36 @@ public void clearAllProducts() {

@Override
public void addCustomSortProduct(ProductCustomSortRequest customSort) throws InvalidParamException {
refineRuleInCustomSort(customSort.getSortRuleForRemainder(), customSort.getSortDirectionForRemainder());
SortOption.of(customSort.getRuleForRemainder());

ProductCustomSort productCustomSort = new ProductCustomSort();
productCustomSort.setOrderedListOfProducts(refineOrderedListOfProductsInCustomSort(customSort.getOrderedListOfProducts()));
productCustomSort.setRuleForRemainder(customSort.getSortRuleForRemainder() + " " + customSort.getSortDirectionForRemainder());
ProductCustomSort productCustomSort = new ProductCustomSort(customSort.getRuleForRemainder());
productCustomSortRepository.deleteAll();
removeFieldFromAllProductDocuments(ProductJsonConstants.CUSTOM_ORDER);
productCustomSortRepository.save(productCustomSort);
productRepository.saveAll(refineOrderedListOfProductsInCustomSort(customSort.getOrderedListOfProducts()));
}

@Override
public List<String> getCustomSortProduct() {
return List.of();
}

private void refineRuleInCustomSort(String sortOption, String sortDirection) throws InvalidParamException {
SortOption.of(sortOption);
SortDirection.of(sortDirection);
}
private List<Product> refineOrderedListOfProductsInCustomSort(List<String> orderedListOfProducts)
throws InvalidParamException {
List<Product> productEntries = new ArrayList<>();

private List<ProductSortEntry> refineOrderedListOfProductsInCustomSort(List<String> orderedListOfProducts) throws InvalidParamException {
List<ProductSortEntry> productSortEntries = new ArrayList<>();

for (int i = 0; i < orderedListOfProducts.size(); i++) {
String productId = orderedListOfProducts.get(i);
int descendingOrder = orderedListOfProducts.size();
for (String productId : orderedListOfProducts) {
Optional<Product> productOptional = productRepository.findById(productId);

if (productOptional.isEmpty()) {
throw new InvalidParamException(ErrorCode.PRODUCT_NOT_FOUND, "Not found product with id: " + productId);
}

productSortEntries.add(new ProductSortEntry(productId, i + 1));
Product product = productOptional.get();
product.setCustomOrder(descendingOrder--);
productEntries.add(product);
}

return productSortEntries;
return productEntries;
}

public void removeFieldFromAllProductDocuments(String fieldName) {
Update update = new Update().unset(fieldName);
mongoTemplate.updateMulti(new Query(), update, Product.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class ProductFilterComponent {

selectedType = TypeOption.All_TYPES;
types = FILTER_TYPES;
selectedSort: SortOption = SortOption.POPULARITY;
selectedSort: SortOption = SortOption.STANDARD;
sorts = SORT_TYPES;

searchText = '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class ProductComponent implements AfterViewInit, OnDestroy {
criteria: Criteria = {
search: '',
type: TypeOption.All_TYPES,
sort: SortOption.POPULARITY,
sort: SortOption.STANDARD,
language: Language.EN
};
responseLink!: Link;
Expand Down
4 changes: 4 additions & 0 deletions marketplace-ui/src/app/shared/constants/common.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export const FILTER_TYPES = [
];

export const SORT_TYPES = [
{
value: SortOption.STANDARD,
label: 'common.sort.value.standard'
},
{
value: SortOption.POPULARITY,
label: 'common.sort.value.popularity'
Expand Down
1 change: 1 addition & 0 deletions marketplace-ui/src/app/shared/enums/sort-option.enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum SortOption {
STANDARD = 'standard',
POPULARITY = 'popularity',
ALPHABETICALLY = 'alphabetically',
RECENT = 'recent'
Expand Down
1 change: 1 addition & 0 deletions marketplace-ui/src/assets/i18n/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ common:
popularity: Beliebtheit
alphabetically: Alphabetisch
recent: Datum der Veröffentlichung
standard: Standard
newest: Neuestes
oldest: Älteste
highest: Höchste
Expand Down
1 change: 1 addition & 0 deletions marketplace-ui/src/assets/i18n/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ common:
popularity: Popularity
alphabetically: Alphabetically
recent: Recent
standard: Standard
newest: Newest
oldest: Oldest
highest: Highest
Expand Down

0 comments on commit b175230

Please sign in to comment.