Skip to content

Commit

Permalink
Merge branch 'feature/MARP-661-Open-Marketplace-from-within-AxonIvy' …
Browse files Browse the repository at this point in the history
…into feature/MARP-315-Open-REST-editor-detail-pages-from-within-AI-designer
  • Loading branch information
nntthuy-axonivy committed Jul 29, 2024
2 parents 034bbc2 + 232c650 commit 44fa6aa
Show file tree
Hide file tree
Showing 55 changed files with 653 additions and 367 deletions.
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

Dear @ivy-sgi, we have found the following bug:

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

Dear @ivy-sgi, it would be cool to have the following feature in the market place:

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.axonivy.market.assembler;

import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.controller.ProductDetailsController;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.NonStandardProduct;
import com.axonivy.market.model.ProductDetailModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
Expand All @@ -26,11 +30,12 @@ public ProductDetailModelAssembler(ProductModelAssembler productModelAssembler)

@Override
public ProductDetailModel toModel(Product product) {
return createModel(product, null);
return createModel(product, StringUtils.EMPTY);
}

public ProductDetailModel toModel(Product product, String tag) {
return createModel(product, tag);
public ProductDetailModel toModel(Product product, String version) {
String productId = Optional.ofNullable(product).map(Product::getId).orElse(StringUtils.EMPTY);
return createModel(product, convertVersionToTag(productId, version));
}

private ProductDetailModel createModel(Product product, String tag) {
Expand Down Expand Up @@ -70,4 +75,17 @@ private void createDetailResource(ProductDetailModel model, Product product, Str
private ProductModuleContent getProductModuleContentByTag(List<ProductModuleContent> contents, String tag) {
return contents.stream().filter(content -> StringUtils.equals(content.getTag(), tag)).findAny().orElse(null);
}

public String convertVersionToTag(String productId, String version) {
if (StringUtils.isBlank(version)) {
return version;
}
String[] versionParts = version.split(CommonConstants.SPACE_SEPARATOR);
String versionNumber = versionParts[versionParts.length - 1];
NonStandardProduct product = NonStandardProduct.findById(productId);
if (product.isVersionTagNumberOnly()) {
return versionNumber;
}
return GitHubConstants.STANDARD_TAG_PREFIX.concat(versionNumber);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public class CommonConstants {
public static final String PLUS = "+";
public static final String DASH_SEPARATOR = "-";
public static final String SPACE_SEPARATOR = " ";
public static final String BEARER = "Bearer";
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class GitHubConstants {
public static final String GITHUB_PROVIDER_NAME = "GitHub";
public static final String GITHUB_GET_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
public static final String README_FILE_LOCALE_REGEX = "_(..)";
public static final String STANDARD_TAG_PREFIX = "v";
public static final String COMMON_IMAGES_FOLDER_NAME = "images";

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Json {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class ProductJsonConstants {
public static final String TYPE = "type";
public static final String DEPENDENCIES = "dependencies";
public static final String INSTALLERS = "installers";
public static final String DEPENDENCY_SUFFIX = "-dependency";
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";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.axonivy.market.controller;

import com.axonivy.market.assembler.FeedbackModelAssembler;
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.entity.Feedback;
import com.axonivy.market.model.FeedbackModel;
import com.axonivy.market.model.ProductRating;
Expand Down Expand Up @@ -82,8 +83,8 @@ public ResponseEntity<FeedbackModel> findFeedbackByUserIdAndProductId(@RequestPa
public ResponseEntity<Void> createFeedback(@RequestBody @Valid FeedbackModel feedback,
@RequestHeader(value = "Authorization") String authorizationHeader) {
String token = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
token = authorizationHeader.substring(7); // Remove "Bearer " prefix
if (authorizationHeader != null && authorizationHeader.startsWith(CommonConstants.BEARER)) {
token = authorizationHeader.substring(CommonConstants.BEARER.length()).trim(); // Remove "Bearer " prefix
}

// Validate the token
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.axonivy.market.controller;

import com.axonivy.market.assembler.ProductModelAssembler;
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.entity.Product;
import com.axonivy.market.enums.ErrorCode;
Expand Down Expand Up @@ -69,8 +70,8 @@ public ResponseEntity<PagedModel<ProductModel>> findProductsInDesigner(@RequestP
public ResponseEntity<Message> syncProducts(@RequestHeader(value = "Authorization") String authorizationHeader,
@RequestParam(value = "resetSync", required = false) Boolean resetSync) {
String token = null;
if (authorizationHeader.startsWith("Bearer ")) {
token = authorizationHeader.substring(7); // Remove "Bearer " prefix
if (authorizationHeader.startsWith(CommonConstants.BEARER)) {
token = authorizationHeader.substring(CommonConstants.BEARER.length()).trim(); // Remove "Bearer " prefix
}
gitHubService.validateUserOrganization(token, GitHubConstants.AXONIVY_MARKET_ORGANIZATION_NAME);
if (Boolean.TRUE.equals(resetSync)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,8 @@
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_DETAILS;
Expand All @@ -33,11 +28,11 @@ public ProductDetailsController(VersionService versionService, ProductService pr
this.detailModelAssembler = detailModelAssembler;
}

@GetMapping("/{id}/{tag}")
@GetMapping("/{id}/{version}")
public ResponseEntity<ProductDetailModel> findProductDetailsByVersion(@PathVariable("id") String id,
@PathVariable("tag") String tag) {
@PathVariable("version") String version) {
var productDetail = productService.fetchProductDetail(id);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, tag), HttpStatus.OK);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, version), HttpStatus.OK);
}

@Operation(summary = "increase installation count by 1", description = "update installation count when click download product files by users")
Expand All @@ -51,7 +46,7 @@ public ResponseEntity<Integer> syncInstallationCount(@PathVariable("key") String
@GetMapping("/{id}")
public ResponseEntity<ProductDetailModel> findProductDetails(@PathVariable("id") String id) {
var productDetail = productService.fetchProductDetail(id);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, null), HttpStatus.OK);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail), HttpStatus.OK);
}

@GetMapping("/{id}/versions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Setter;
import org.springframework.data.annotation.Transient;

import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;

Expand All @@ -14,6 +15,7 @@
@Setter
@Getter
public class MavenArtifactModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String name;
private String downloadUrl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -21,6 +22,7 @@
@NoArgsConstructor
@Document(MAVEN_ARTIFACT_VERSION)
public class MavenArtifactVersion implements Serializable {
@Serial
private static final long serialVersionUID = -6492612804634492078L;

@Id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
Expand All @@ -26,6 +27,7 @@
@Builder
@Document(PRODUCT)
public class Product implements Serializable {
@Serial
private static final long serialVersionUID = -8770801877877277258L;
@Id
private String id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serial;
import java.io.Serializable;
import java.util.Map;

Expand All @@ -13,6 +14,7 @@
@NoArgsConstructor
@AllArgsConstructor
public class ProductModuleContent implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String tag;
private Map<String, String> description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public enum FileStatus {
MODIFIED("modified"), ADDED("added"), REMOVED("removed");

private String code;
private final String code;

public static FileStatus of(String code) {
for (var status : values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public enum FileType {
META("meta.json"), LOGO("logo.png");

private String fileName;
private final String fileName;

public static FileType of(String name) {
for (var type : values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
public enum Language {
EN("en"), DE("de");

private String value;
private final String value;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.axonivy.market.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;

import static com.axonivy.market.constants.GitHubConstants.COMMON_IMAGES_FOLDER_NAME;

@Getter
@AllArgsConstructor
public enum NonStandardProduct {
PORTAL("portal", true, COMMON_IMAGES_FOLDER_NAME, "AxonIvyPortal/portal-product"),
MICROSOFT_REPO_NAME("msgraph-connector", false, COMMON_IMAGES_FOLDER_NAME, ""),
MICROSOFT_365("msgraph", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-connector"), // No meta.json
MICROSOFT_CALENDAR("msgraph-calendar", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-calendar"), // no fix product json
MICROSOFT_MAIL("msgraph-mail", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-mail"),// no fix product json
MICROSOFT_TEAMS("msgraph-chat", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-chat"),// no fix product json
MICROSOFT_TODO("msgraph-todo", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-todo"),// no fix product json
CONNECTIVITY_FEATURE("connectivity-demo", false, COMMON_IMAGES_FOLDER_NAME, "connectivity/connectivity-demos-product"),
EMPLOYEE_ONBOARDING("employee-onboarding", false, COMMON_IMAGES_FOLDER_NAME, ""), // Invalid meta.json
ERROR_HANDLING("error-handling-demo", false, COMMON_IMAGES_FOLDER_NAME, "error-handling/error-handling-demos-product"),
RULE_ENGINE_DEMOS("rule-engine-demo", false, COMMON_IMAGES_FOLDER_NAME, "rule-engine/rule-engine-demos-product"),
WORKFLOW_DEMO("workflow-demo", false, COMMON_IMAGES_FOLDER_NAME, "workflow/workflow-demos-product"),
HTML_DIALOG_DEMO("html-dialog-demo", false, COMMON_IMAGES_FOLDER_NAME, "html-dialog/html-dialog-demos-product"),
PROCESSING_VALVE_DEMO("processing-valve-demo", false, COMMON_IMAGES_FOLDER_NAME, ""),// no product json
OPENAI_CONNECTOR("openai-connector", false, COMMON_IMAGES_FOLDER_NAME, "openai-connector-product"),
OPENAI_ASSISTANT("openai-assistant", false, "docs", "openai-assistant-product"),
// Non standard image folder name
EXCEL_IMPORTER("excel-importer", false, "doc", ""),
EXPRESS_IMPORTER("express-importer", false, "img", ""),
GRAPHQL_DEMO("graphql-demo", false, "assets", ""),
DEEPL_CONNECTOR("deepl-connector", false, "img", ""),
DEFAULT("", false, COMMON_IMAGES_FOLDER_NAME, "");

private final String id;
private final boolean isVersionTagNumberOnly;
private final String pathToImageFolder;
private final String pathToProductFolder;

public static NonStandardProduct findById(String id) {

return Arrays.stream(NonStandardProduct.values()).filter(product -> id.equalsIgnoreCase(product.getId())).findAny().orElse(DEFAULT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public enum SortOption {
POPULARITY("popularity", "installationCount"), ALPHABETICALLY("alphabetically", "names"),
RECENT("recent", "newestPublishedDate");

private String option;
private String code;
private final String option;
private final String code;

public static SortOption of(String option) {
option = StringUtils.isBlank(option) ? option : option.trim();
Expand Down
Loading

0 comments on commit 44fa6aa

Please sign in to comment.