Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(TCOMP-2100): backlog tasks #892

Merged
merged 3 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static javax.ws.rs.core.MediaType.APPLICATION_SVG_XML;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.PATH;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT;
Expand Down Expand Up @@ -55,6 +54,8 @@
@Tag(name = "Component", description = "Endpoints related to component metadata access.")
public interface ComponentResource {

String IMAGE_SVG_XML = "image/svg+xml";

@GET
@Path("dependencies")
@Operation(description = "Returns a list of dependencies for the given components. "
Expand Down Expand Up @@ -159,10 +160,10 @@ Response icon(

@GET
@Path("icon/index")
@Produces({ APPLICATION_JSON, APPLICATION_SVG_XML })
@Produces({ APPLICATION_JSON, IMAGE_SVG_XML })
@Operation(description = "Returns list of available svg icons.")
@APIResponse(responseCode = "200", description = "The icon list.",
content = @Content(mediaType = APPLICATION_SVG_XML))
content = @Content(mediaType = IMAGE_SVG_XML))
@APIResponse(responseCode = "404", description = "No icon found.", content = @Content(mediaType = APPLICATION_JSON))
Response getIconIndex(
@QueryParam("theme") @Parameter(name = "theme",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static javax.ws.rs.core.MediaType.APPLICATION_SVG_XML_TYPE;
import static javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION;
import static org.talend.sdk.component.server.front.model.ErrorDictionary.COMPONENT_MISSING;
import static org.talend.sdk.component.server.front.model.ErrorDictionary.DESIGN_MODEL_MISSING;
Expand Down Expand Up @@ -150,7 +149,7 @@ public class ComponentResourceImpl implements ComponentResource {

public static final String THEME_ALL = "all";

public static final String MEDIA_TYPE_SVG_XML = "image/svg+xml";
public static final String IMAGE_SVG_XML_TYPE = "image/svg+xml";

private final ConcurrentMap<RequestKey, ComponentIndices> indicesPerRequest = new ConcurrentHashMap<>();

Expand Down Expand Up @@ -511,15 +510,17 @@ public Response getIconIndex(final String theme) {
root.setAttribute("xmlns", "http://www.w3.org/2000/svg");
root.setAttribute("focusable", "false");
root.setAttribute("class", "sr-only");
root.setAttribute("theme", themedIcon);
root.setAttribute("data-theme", themedIcon);
doc.appendChild(root);
icons.values().forEach(icon -> {
final Element symbol = doc.createElement("symbol");
symbol.setAttribute("family", icon.getFamily());
symbol.setAttribute("id", icon.getIcon());
symbol.setAttribute("type", icon.getType());
symbol.setAttribute("connector", icon.getConnector());
symbol.setAttribute("theme", icon.getTheme());
symbol.setAttribute("id", String.format("%s-%s", icon.getIcon(), icon.getTheme()));
symbol.setAttribute("data-theme", icon.getTheme());
symbol.setAttribute("data-type", icon.getType());
symbol.setAttribute("data-family", icon.getFamily());
if ("connector".equals(icon.getType())) {
symbol.setAttribute("data-connector", icon.getConnector());
}
symbol.setTextContent(new String(icon.getContent()));
root.appendChild(symbol);
});
Expand All @@ -535,7 +536,7 @@ public Response getIconIndex(final String theme) {
.replace("&lt;", "<")
.replace("&gt;", ">");

return Response.ok(svgs).type(APPLICATION_SVG_XML_TYPE).build();
return Response.ok(svgs).type(IMAGE_SVG_XML_TYPE).build();
} catch (Exception e) {
log.error("[getIconIndex] {}", e.getMessage());
return Response
Expand Down Expand Up @@ -670,7 +671,7 @@ private Map<String, IconSymbol> getAllIconsForTheme(final String theme) {
Map<String, IconSymbol> icons = components
.stream()
.filter(c -> c.getIconFamily().getCustomIcon() != null)
.filter(c -> MEDIA_TYPE_SVG_XML.equals(c.getIconFamily().getCustomIconType()))
.filter(c -> IMAGE_SVG_XML_TYPE.equals(c.getIconFamily().getCustomIconType()))
.map(c -> new IconSymbol(c.getIconFamily().getIcon(),
c.getFamilyDisplayName(),
"family",
Expand All @@ -681,7 +682,7 @@ private Map<String, IconSymbol> getAllIconsForTheme(final String theme) {
icons.putAll(components
.stream()
.filter(c -> c.getIcon().getCustomIcon() != null)
.filter(c -> MEDIA_TYPE_SVG_XML.equals(c.getIcon().getCustomIconType()))
.filter(c -> IMAGE_SVG_XML_TYPE.equals(c.getIcon().getCustomIconType()))
.map(c -> new IconSymbol(c.getIcon().getIcon(),
c.getFamilyDisplayName(),
"connector",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import static org.talend.sdk.component.server.front.ComponentResourceImpl.COMPONENT_TYPE_INPUT;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.COMPONENT_TYPE_PROCESSOR;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.COMPONENT_TYPE_STANDALONE;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.MEDIA_TYPE_SVG_XML;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.IMAGE_SVG_XML_TYPE;

import java.io.File;
import java.io.FileOutputStream;
Expand Down Expand Up @@ -248,7 +248,7 @@ void themedIcon() {
.accept(APPLICATION_OCTET_STREAM_TYPE)
.get(Response.class);
assertNotNull(icon);
assertEquals(MEDIA_TYPE_SVG_XML, icon.getMediaType().toString());
assertEquals(IMAGE_SVG_XML_TYPE, icon.getMediaType().toString());
}

@Test
Expand All @@ -270,7 +270,7 @@ void themedFamilyIcon() {
.accept(APPLICATION_OCTET_STREAM_TYPE)
.get(Response.class);
assertNotNull(icon);
assertEquals(MEDIA_TYPE_SVG_XML, icon.getMediaType().toString());
assertEquals(IMAGE_SVG_XML_TYPE, icon.getMediaType().toString());

assertThrows(NotFoundException.class, () -> base.path("component/icon/family/{id}")
.resolveTemplate("id", family)
Expand Down Expand Up @@ -322,81 +322,90 @@ void customThemedIcon() {

@Test
void getIconIndex() {
// content type
// wrong content type
Response icons = base.path("component/icon/index")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.get();
assertNotNull(icons);
assertEquals(APPLICATION_SVG_XML_TYPE, icons.getMediaType());
assertEquals(406, icons.getStatus());
// inexistant theme (no fallback)
icons = base.path("component/icon/index")
.queryParam("theme", "dak")
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE)
.get();
assertEquals(404, icons.getStatus());
assertEquals(APPLICATION_JSON_TYPE, icons.getMediaType());

// content type
icons = base.path("component/icon/index")
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE, APPLICATION_JSON_TYPE.toString())
.get();
assertNotNull(icons);
assertEquals(IMAGE_SVG_XML_TYPE, icons.getMediaType().toString());
// default: light theme
String content = base.path("component/icon/index")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE)
.get(String.class);
assertNotNull(content);
assertTrue(
content.startsWith(
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" focusable=\"false\" theme=\"light\">"));
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" data-theme=\"light\" focusable=\"false\">"));
assertTrue(content.contains(
"connector=\"standalone\" family=\"chain\" id=\"myicon\" theme=\"light\" type=\"connector\""));
"data-connector=\"standalone\" data-family=\"chain\" data-theme=\"light\" data-type=\"connector\" id=\"myicon-light\""));
assertTrue(
content.contains("connector=\"\" family=\"file\" id=\"file-family\" theme=\"light\" type=\"family\""));
content.contains("data-family=\"file\" data-theme=\"light\" data-type=\"family\" id=\"file-family-light\""));
// light theme
content = base.path("component/icon/index")
.queryParam("theme", "light")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE)
.get(String.class);
assertNotNull(content);
assertTrue(
content.startsWith(
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" focusable=\"false\" theme=\"light\">"));
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" data-theme=\"light\" focusable=\"false\">"));
assertTrue(content.contains(
"connector=\"standalone\" family=\"chain\" id=\"myicon\" theme=\"light\" type=\"connector\""));
"data-connector=\"standalone\" data-family=\"chain\" data-theme=\"light\" data-type=\"connector\" id=\"myicon-light\""));
assertTrue(
content.contains("connector=\"\" family=\"file\" id=\"file-family\" theme=\"light\" type=\"family\""));
content.contains("data-family=\"file\" data-theme=\"light\" data-type=\"family\" id=\"file-family-light\""));

// dark theme
content = base.path("component/icon/index")
.queryParam("theme", "dark")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE)
.get(String.class);
assertNotNull(content);
assertTrue(
content.startsWith(
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" focusable=\"false\" theme=\"dark\">"));
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" data-theme=\"dark\" focusable=\"false\">"));
assertTrue(content
.contains("connector=\"input\" family=\"jdbc\" id=\"db-input\" theme=\"dark\" type=\"connector\""));
.contains("data-connector=\"input\" data-family=\"jdbc\" data-theme=\"dark\" data-type=\"connector\" id=\"db-input-dark\""));
assertTrue(content
.contains("connector=\"output\" family=\"jdbc\" id=\"db-input\" theme=\"dark\" type=\"connector\""));
.contains("data-connector=\"output\" data-family=\"jdbc\" data-theme=\"dark\" data-type=\"connector\" id=\"db-input-dark\""));
// theme = all
content = base.path("component/icon/index")
.queryParam("theme", "all")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.request(IMAGE_SVG_XML_TYPE)
.accept(IMAGE_SVG_XML_TYPE)
.get(String.class);
assertNotNull(content);
System.out.println(content);
assertTrue(
content.startsWith(
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" focusable=\"false\" theme=\"all\">"));
"<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"sr-only\" data-theme=\"all\" focusable=\"false\">"));
assertTrue(content
.contains("connector=\"input\" family=\"jdbc\" id=\"db-input\" theme=\"dark\" type=\"connector\""));
.contains("data-connector=\"input\" data-family=\"jdbc\" data-theme=\"dark\" data-type=\"connector\" id=\"db-input-dark\""));
assertTrue(content
.contains("connector=\"output\" family=\"jdbc\" id=\"db-input\" theme=\"dark\" type=\"connector\""));
.contains("data-connector=\"output\" data-family=\"jdbc\" data-theme=\"dark\" data-type=\"connector\" id=\"db-input-dark\""));
assertTrue(content.contains(
"connector=\"standalone\" family=\"chain\" id=\"myicon\" theme=\"light\" type=\"connector\""));
"data-connector=\"standalone\" data-family=\"chain\" data-theme=\"light\" data-type=\"connector\" id=\"myicon-light\""));
assertTrue(
content.contains("connector=\"\" family=\"file\" id=\"file-family\" theme=\"light\" type=\"family\""));
// inexistant theme (no fallback)
icons = base.path("component/icon/index")
.queryParam("theme", "dak")
.request(APPLICATION_SVG_XML_TYPE)
.accept(APPLICATION_SVG_XML_TYPE)
.get();
assertEquals(404, icons.getStatus());
assertEquals(APPLICATION_JSON_TYPE, icons.getMediaType());
content.contains("data-family=\"file\" data-theme=\"dark\" data-type=\"family\" id=\"file-family-dark\""));
}

@Test
Expand Down Expand Up @@ -691,7 +700,7 @@ private void assertComponent(final String plugin, final String family, final Str
assertEquals("light", data.getIcon().getTheme());
assertTrue(new String(data.getIcon().getCustomIcon(), StandardCharsets.UTF_8)
.startsWith("<svg xmlns=\"http://www.w3.org/2000/svg\""));
assertEquals(MEDIA_TYPE_SVG_XML, data.getIcon().getCustomIconType());
assertEquals(IMAGE_SVG_XML_TYPE, data.getIcon().getCustomIconType());
assertEquals(singletonList("Misc/" + data.getFamilyDisplayName()), data.getCategories());
} else {
assertEquals(singletonList("Misc/" + data.getFamilyDisplayName()), data.getCategories());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.MEDIA_TYPE_SVG_XML;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.IMAGE_SVG_XML_TYPE;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.THEME_DARK;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.THEME_LIGHT;

Expand Down Expand Up @@ -68,12 +68,12 @@ void studioThemedIconWithSvg() {
//
IconResolver.Icon icon = resolver.resolve(plugin, "logo", THEME_DARK);
assertNotNull(icon);
assertEquals(MEDIA_TYPE_SVG_XML, icon.getType());
assertEquals(IMAGE_SVG_XML_TYPE, icon.getType());
assertEquals(THEME_DARK, icon.getTheme());
//
icon = resolver.resolve(plugin, PLUGIN_DB_INPUT, THEME_DARK);
assertNotNull(icon);
assertEquals(MEDIA_TYPE_SVG_XML, icon.getType());
assertEquals(IMAGE_SVG_XML_TYPE, icon.getType());
assertEquals(THEME_DARK, icon.getTheme());
//
icon = resolver.resolve(plugin, PLUGIN_DB_INPUT, THEME_LIGHT);
Expand Down
Loading
Loading