This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch fix-opcua-abstract-types in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit c46cb7337f76f762b8d8e3b50d796d9e3dbc2739 Author: Dominik Riemer <[email protected]> AuthorDate: Mon Feb 16 16:48:17 2026 +0100 fix: Support abstract data types in OPC-UA adapter --- .../connectors/opcua/adapter/OpcUaAdapter.java | 2 +- .../connectors/opcua/adapter/OpcUaNodeBrowser.java | 10 +-- .../opcua/adapter/OpcUaNodeMetadataExtractor.java | 27 ++++++- .../opcua/adapter/OpcUaSchemaProvider.java | 21 +----- .../connectors/opcua/model/OpcUaNodeFactory.java | 86 ++++++++++++++++++++-- .../opcua/model/node/ExtensionObjectOpcUaNode.java | 34 +-------- .../connectors/opcua/model/node/OpcUaNode.java | 5 -- .../opcua/model/node/PrimitiveOpcUaNode.java | 22 +----- .../adapter-event-preview.component.html | 2 +- .../adapter-event-preview.component.scss | 3 - .../adapter-sample-preview.component.html | 20 ++--- .../show-field-status-infos.component.html | 53 +++++-------- .../show-field-status-infos.component.scss | 63 ---------------- .../show-field-status-infos.component.ts | 17 +++-- ...ic-runtime-resolvable-tree-input.component.scss | 1 - .../static-tree-input-node-details.component.html | 9 ++- .../static-tree-input-node-details.component.ts | 4 +- 17 files changed, 165 insertions(+), 214 deletions(-) diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java index 79a76aee34..c3969a4063 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaAdapter.java @@ -99,7 +99,7 @@ public class OpcUaAdapter implements StreamPipesAdapter, IPullAdapter, SupportsR this.connectedClient = clientProvider.getClient(this.opcUaAdapterConfig); OpcUaNodeBrowser browserClient = new OpcUaNodeBrowser(this.connectedClient.getClient(), this.opcUaAdapterConfig); - this.nodeProvider = browserClient.makeNodeProvider(List.of()); + this.nodeProvider = browserClient.makeNodeProvider(); this.allNodes = nodeProvider.getNodes(); if (opcUaAdapterConfig.inPullMode()) { diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java index df520031e6..c1432809ce 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeBrowser.java @@ -60,10 +60,10 @@ public class OpcUaNodeBrowser { this.spOpcConfig = spOpcUaClientConfig; } - public OpcUaNodeProvider makeNodeProvider(List<String> runtimeNameFilters) throws UaException { + public OpcUaNodeProvider makeNodeProvider() throws UaException { var opcNodes = new ArrayList<OpcUaNode>(); for (String selectedNodeName : this.spOpcConfig.getSelectedNodeNames()) { - opcNodes.add(toOpcNode(selectedNodeName, runtimeNameFilters)); + opcNodes.add(toOpcNode(selectedNodeName)); } return new OpcUaNodeProvider(opcNodes); @@ -79,8 +79,7 @@ public class OpcUaNodeBrowser { return findChildren(client, currentNodeId); } - private OpcUaNode toOpcNode(String nodeName, - List<String> runtimeNamesToDelete) throws UaException { + private OpcUaNode toOpcNode(String nodeName) throws UaException { AddressSpace addressSpace = getAddressSpace(); NodeId nodeId; @@ -109,8 +108,9 @@ public class OpcUaNodeBrowser { ); if (node instanceof VariableNode) { + var dv = ((VariableNode) node).getValue(); var nodeInfo = new BasicVariableNodeInfo((VariableNode) node, spOpcConfig.getNamingStrategy()); - return OpcUaNodeFactory.createOpcUaNode(nodeInfo, runtimeNamesToDelete); + return OpcUaNodeFactory.createOpcUaNode(nodeInfo, dv); } LOG.warn("Node {} not of type VariableNode", node.getDisplayName()); diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeMetadataExtractor.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeMetadataExtractor.java index bcaf11a476..7ade7783b0 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeMetadataExtractor.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaNodeMetadataExtractor.java @@ -25,6 +25,7 @@ import org.eclipse.milo.opcua.stack.core.StatusCodes; import org.eclipse.milo.opcua.stack.core.UaException; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; import java.util.HashMap; @@ -57,10 +58,12 @@ public class OpcUaNodeMetadataExtractor { var dataTypeNode = client.getAddressSpace().getNode(dataTypeNodeId); var value = client.readValue(0, TimestampsToReturn.Both, node.getNodeId()).get(); + extractNodeId((UaVariableNode) node); extractSourceTime(value); extractServerTime(value); extractStatusCode(value); extractDataType(dataTypeNode); + extractDataTypeNodeId(dataTypeNodeId); } catch (UaException | ExecutionException | InterruptedException e) { throw new RuntimeException(e); } @@ -69,12 +72,28 @@ public class OpcUaNodeMetadataExtractor { return metadata; } + public void extractNodeId(UaVariableNode node) { + if (node != null && node.getNodeId() != null) { + add("Node ID", node.getNodeId().toParseableString()); + } else { + add("Node ID", "N/A"); + } + } + + public void extractDataTypeNodeId(NodeId dataTypeNodeId) { + if (dataTypeNodeId != null) { + add("Data Type Node ID", dataTypeNodeId.toParseableString()); + } else { + add("Data Type Node ID", "N/A"); + } + } + public void extractDescription() { if (node.getDescription() != null) { add("Description", node.getDescription().getText()); } else { - add("Description", ""); + add("Description", "N/A"); } } @@ -82,7 +101,7 @@ public class OpcUaNodeMetadataExtractor { if (node.getNodeId() != null) { add("NamespaceIndex", node.getNodeId().getNamespaceIndex().toString()); } else { - add("NamespaceIndex", ""); + add("NamespaceIndex", "N/A"); } } @@ -98,7 +117,7 @@ public class OpcUaNodeMetadataExtractor { if (node.getBrowseName() != null) { add("BrowseName", node.getBrowseName().getName()); } else { - add("BrowseName", ""); + add("BrowseName", "N/A"); } } @@ -106,7 +125,7 @@ public class OpcUaNodeMetadataExtractor { if (node.getDisplayName() != null) { add("DisplayName", node.getDisplayName().getText()); } else { - add("DisplayName", ""); + add("DisplayName", "N/A"); } } diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaSchemaProvider.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaSchemaProvider.java index 049951e4ab..57a245eca7 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaSchemaProvider.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/adapter/OpcUaSchemaProvider.java @@ -27,9 +27,6 @@ import org.apache.streampipes.extensions.connectors.opcua.config.SpOpcUaConfigEx import org.apache.streampipes.extensions.connectors.opcua.model.node.OpcUaNode; import org.apache.streampipes.model.connect.guess.FieldStatusInfo; import org.apache.streampipes.model.connect.guess.SampleData; -import org.apache.streampipes.model.schema.EventProperty; -import org.apache.streampipes.model.schema.EventSchema; -import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder; import org.apache.streampipes.sdk.builder.adapter.SampleDataBuilder; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; @@ -37,7 +34,6 @@ import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -56,11 +52,8 @@ public class OpcUaSchemaProvider { IAdapterParameterExtractor extractor, IStreamPipesClient streamPipesClient) throws AdapterException, ParseException { - var builder = GuessSchemaBuilder.create(); - EventSchema eventSchema = new EventSchema(); Map<String, Object> eventPreview = new HashMap<>(); Map<String, FieldStatusInfo> fieldStatusInfos = new HashMap<>(); - List<EventProperty> allProperties = new ArrayList<>(); var opcUaConfig = SpOpcUaConfigExtractor.extractAdapterConfig( extractor.getStaticPropertyExtractor(), @@ -70,15 +63,9 @@ public class OpcUaSchemaProvider { var connectedClient = clientProvider.getClient(opcUaConfig); OpcUaNodeBrowser nodeBrowser = new OpcUaNodeBrowser(connectedClient.getClient(), opcUaConfig); - var nodeProvider = nodeBrowser.makeNodeProvider(List.of()); + var nodeProvider = nodeBrowser.makeNodeProvider(); var selectedNodes = nodeProvider.getNodes(); - if (!selectedNodes.isEmpty()) { - for (OpcUaNode opcNode : selectedNodes) { - opcNode.addToSchema(connectedClient.getClient(), allProperties); - } - } - var nodeIds = selectedNodes.stream() .map(node -> node.nodeInfo().getNodeId()) .collect(Collectors.toList()); @@ -96,12 +83,10 @@ public class OpcUaSchemaProvider { clientProvider.releaseClient(opcUaConfig); } - var sampleData = SampleDataBuilder.create() + return SampleDataBuilder.create() .sample(eventPreview) + .fieldStatusInfos(fieldStatusInfos) .build(); - - - return sampleData; } private static void makeEventPreview( diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcUaNodeFactory.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcUaNodeFactory.java index 812aa66b7e..d5f290ae97 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcUaNodeFactory.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/OpcUaNodeFactory.java @@ -22,18 +22,90 @@ import org.apache.streampipes.extensions.connectors.opcua.model.node.BasicVariab import org.apache.streampipes.extensions.connectors.opcua.model.node.ExtensionObjectOpcUaNode; import org.apache.streampipes.extensions.connectors.opcua.model.node.OpcUaNode; import org.apache.streampipes.extensions.connectors.opcua.model.node.PrimitiveOpcUaNode; -import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaTypes; +import org.eclipse.milo.opcua.stack.core.BuiltinDataType; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject; +import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; + +import java.lang.reflect.Array; import java.util.List; +import java.util.Objects; public class OpcUaNodeFactory { - public static OpcUaNode createOpcUaNode(BasicVariableNodeInfo nodeInfo, - List<String> runtimeNamesToDelete) { - if (OpcUaTypes.isExtensionOrCustom(nodeInfo.getNode())) { - return new ExtensionObjectOpcUaNode(nodeInfo, runtimeNamesToDelete); - } else { - return new PrimitiveOpcUaNode(nodeInfo, runtimeNamesToDelete); + public static OpcUaNode createOpcUaNode( + BasicVariableNodeInfo nodeInfo, + DataValue dataValue + ) { + Boolean byValue = isExtensionByValue(dataValue); + if (byValue != null) { + return byValue + ? new ExtensionObjectOpcUaNode(nodeInfo) + : new PrimitiveOpcUaNode(nodeInfo); } + + return isExtensionByDataType(nodeInfo) + ? new ExtensionObjectOpcUaNode(nodeInfo) + : new PrimitiveOpcUaNode(nodeInfo); + } + + /** + * @return TRUE -> value is (or contains) ExtensionObject + * FALSE -> value is present and not ExtensionObject + * NULL -> cannot decide from value (null DataValue, bad StatusCode, no Variant, etc.) + */ + public static Boolean isExtensionByValue(DataValue dv) { + if (dv == null) { + return null; + } + + StatusCode sc = dv.getStatusCode(); + if (sc == null || !sc.isGood()) { + return null; + } + + if (dv.getValue() == null) { + return null; + } + + Object v = dv.getValue().getValue(); + if (v == null) { + return Boolean.FALSE; + } + + if (v instanceof ExtensionObject) { + return Boolean.TRUE; + } + + // Handle arrays of any kind (Object[] or primitive arrays) + Class<?> c = v.getClass(); + if (c.isArray()) { + int len = Array.getLength(v); + for (int i = 0; i < len; i++) { + Object el = Array.get(v, i); // works for primitive arrays too (boxed) + if (el instanceof ExtensionObject) { + return Boolean.TRUE; + } + } + return Boolean.FALSE; + } + + return Boolean.FALSE; + } + + /** + * Conservative fallback based on declared DataType only. + * Treat only ExtensionObject itself as "extension" here. + * + * Why so conservative? Because abstract standard types like Integer/Number + * are NOT builtins but are still "primitive-ish" and should not be treated + * as custom/extension. + */ + private static boolean isExtensionByDataType(BasicVariableNodeInfo nodeInfo) { + NodeId dt = nodeInfo.getNode().getDataType(); + return Objects.equals(dt, BuiltinDataType.ExtensionObject.getNodeId()); } } + diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/ExtensionObjectOpcUaNode.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/ExtensionObjectOpcUaNode.java index b16cb4f434..0e8c428b09 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/ExtensionObjectOpcUaNode.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/ExtensionObjectOpcUaNode.java @@ -19,29 +19,22 @@ package org.apache.streampipes.extensions.connectors.opcua.model.node; import org.apache.streampipes.commons.exceptions.SpRuntimeException; -import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaTypes; import org.apache.streampipes.model.connect.guess.FieldStatus; import org.apache.streampipes.model.connect.guess.FieldStatusInfo; -import org.apache.streampipes.model.schema.EventProperty; -import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder; import org.eclipse.milo.opcua.binaryschema.Struct; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject; import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; -import java.util.List; import java.util.Map; public class ExtensionObjectOpcUaNode implements OpcUaNode { private final BasicVariableNodeInfo nodeInfo; - private final List<String> runtimeNamesToDelete; - public ExtensionObjectOpcUaNode(BasicVariableNodeInfo nodeInfo, - List<String> runtimeNamesToDelete) { + public ExtensionObjectOpcUaNode(BasicVariableNodeInfo nodeInfo) { this.nodeInfo = nodeInfo; - this.runtimeNamesToDelete = runtimeNamesToDelete; } @Override @@ -52,26 +45,7 @@ public class ExtensionObjectOpcUaNode implements OpcUaNode { @Override public int getNumberOfEventProperties(OpcUaClient client) { var struct = extractStruct(client, nodeInfo.getNode().getValue().getValue()); - return (int) struct.getMembers().entrySet().stream() - .filter(entry -> { - var nodeName = nodeInfo.getDesiredName(entry.getKey()); - return !runtimeNamesToDelete.contains(nodeName); - }) - .count(); - } - - @Override - public void addToSchema(OpcUaClient client, - List<EventProperty> eventProperties) { - var struct = extractStruct(client, nodeInfo.getNode().getValue().getValue()); - struct.getMembers().forEach((key, member) -> { - var nodeName = nodeInfo.getDesiredName(key); - eventProperties.add( - PrimitivePropertyBuilder.create(OpcUaTypes.getTypeFromValue(member.getValue()), nodeName) - .label(nodeName) - .build() - ); - }); + return struct.getMembers().size(); } @Override @@ -82,9 +56,7 @@ public class ExtensionObjectOpcUaNode implements OpcUaNode { struct.getMembers().forEach((key, member) -> { var nodeName = nodeInfo.getDesiredName(key); - if (!runtimeNamesToDelete.contains(nodeName)) { - event.put(nodeName, member.getValue()); - } + event.put(nodeName, member.getValue()); }); } diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/OpcUaNode.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/OpcUaNode.java index 6e2963904c..83b2073ed1 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/OpcUaNode.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/OpcUaNode.java @@ -19,12 +19,10 @@ package org.apache.streampipes.extensions.connectors.opcua.model.node; import org.apache.streampipes.model.connect.guess.FieldStatusInfo; -import org.apache.streampipes.model.schema.EventProperty; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; -import java.util.List; import java.util.Map; public interface OpcUaNode { @@ -33,9 +31,6 @@ public interface OpcUaNode { int getNumberOfEventProperties(OpcUaClient client); - void addToSchema(OpcUaClient client, - List<EventProperty> eventProperties); - void addToEvent(OpcUaClient client, Map<String, Object> event, Variant variant); diff --git a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/PrimitiveOpcUaNode.java b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/PrimitiveOpcUaNode.java index a05ab85185..ab86d8bd37 100644 --- a/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/PrimitiveOpcUaNode.java +++ b/streampipes-extensions/streampipes-connectors-opcua/src/main/java/org/apache/streampipes/extensions/connectors/opcua/model/node/PrimitiveOpcUaNode.java @@ -21,8 +21,6 @@ package org.apache.streampipes.extensions.connectors.opcua.model.node; import org.apache.streampipes.extensions.connectors.opcua.utils.OpcUaTypes; import org.apache.streampipes.model.connect.guess.FieldStatus; import org.apache.streampipes.model.connect.guess.FieldStatusInfo; -import org.apache.streampipes.model.schema.EventProperty; -import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder; import org.apache.streampipes.sdk.utils.Datatypes; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; @@ -32,18 +30,14 @@ import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; import java.util.Base64; -import java.util.List; import java.util.Map; public class PrimitiveOpcUaNode implements OpcUaNode { private final BasicVariableNodeInfo nodeInfo; - private final List<String> runtimeNamesToDelete; - public PrimitiveOpcUaNode(BasicVariableNodeInfo nodeInfo, - List<String> runtimeNamesToDelete) { + public PrimitiveOpcUaNode(BasicVariableNodeInfo nodeInfo) { this.nodeInfo = nodeInfo; - this.runtimeNamesToDelete = runtimeNamesToDelete; } @Override @@ -56,24 +50,12 @@ public class PrimitiveOpcUaNode implements OpcUaNode { return 1; } - @Override - public void addToSchema(OpcUaClient client, - List<EventProperty> eventProperties) { - var nodeName = nodeInfo().getBaseNodeName(); - eventProperties.add(PrimitivePropertyBuilder - .create(getType(), nodeName) - .label(nodeName) - .build()); - } - @Override public void addToEvent(OpcUaClient client, Map<String, Object> event, Variant variant) { var nodeName = nodeInfo.getDesiredName(""); - if (!runtimeNamesToDelete.contains(nodeName)) { - event.put(nodeName, extractValue(variant)); - } + event.put(nodeName, extractValue(variant)); } @Override diff --git a/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.html b/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.html index 18570f8d16..dc5ea2ad86 100644 --- a/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.html +++ b/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.html @@ -16,7 +16,7 @@ ~ --> -<section class="jv"> +<section class="jv p-sm"> <div class="jv__content" [class.is-empty]="!hasValue()"> @if (hasValue()) { <ng-container [ngSwitch]="mode"> diff --git a/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.scss b/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.scss index 8fb07d9f1a..4c290eba6b 100644 --- a/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.scss +++ b/ui/src/app/connect/components/adapter-configuration/adapter-event-preview/adapter-event-preview.component.scss @@ -25,13 +25,11 @@ } .jv__content { - padding: 10px 12px 14px 12px; background: var(--color-bg-0); } .raw { margin: 0; - padding: 12px; background: var(--color-bg-0); color: var(--text); overflow: auto; @@ -45,7 +43,6 @@ .tree { background: var(--color-bg-0); - padding: 10px; max-height: 520px; overflow: auto; } diff --git a/ui/src/app/connect/components/adapter-configuration/configure-schema/sample-preview/adapter-sample-preview.component.html b/ui/src/app/connect/components/adapter-configuration/configure-schema/sample-preview/adapter-sample-preview.component.html index d84955832c..e3945675cb 100644 --- a/ui/src/app/connect/components/adapter-configuration/configure-schema/sample-preview/adapter-sample-preview.component.html +++ b/ui/src/app/connect/components/adapter-configuration/configure-schema/sample-preview/adapter-sample-preview.component.html @@ -18,7 +18,7 @@ <sp-basic-inner-panel innerPadding="0" [showTitle]="true" - [panelTitle]="'Original (Parsed)' | translate" + [panelTitle]="'Source' | translate" > <div header fxLayoutAlign="end center" fxFlex="100"> <button @@ -69,14 +69,16 @@ [showDetails]="true" ></sp-exception-message> } @else { - <sp-show-field-status-infos - [fieldStatusInfos]="fieldStatusInfos()" - ></sp-show-field-status-infos> - <sp-adapter-event-preview - dataCy="configure-schema-event-preview-original" - [mode]="sourceViewMode()" - [value]="input()" - ></sp-adapter-event-preview> + <div fxLayout="column" class="w-100 p-sm"> + <sp-show-field-status-infos + [fieldStatusInfos]="fieldStatusInfos()" + ></sp-show-field-status-infos> + <sp-adapter-event-preview + dataCy="configure-schema-event-preview-original" + [mode]="sourceViewMode()" + [value]="input()" + ></sp-adapter-event-preview> + </div> } } </sp-basic-inner-panel> diff --git a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.html b/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.html index 9e9e2682df..acb2a3f389 100644 --- a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.html +++ b/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.html @@ -17,42 +17,29 @@ --> <div fxFlex="100" fxLayout="column"> @if (hasBadFieldStatusInfos()) { - <div class="fs-alert fs-alert-header"> - <div class="fs-alert-icon"> - <mat-icon>error</mat-icon> - </div> - <div class="fs-alert-content" fxLayout="column" fxFlex="100"> - <div class="fs-alert-title"> - Problems reading the following nodes - </div> - <div class="fs-alert-description"> - Please change the adapter configuration to fix them. - </div> - </div> - </div> - <div fxFlex="100" fxLayout="column" fxLayoutGap="8px"> - @for (entry of badFieldStatusInfos(); track entry[0]) { - @let runtimeName = entry[0]; - @let info = entry[1]; - - <div class="fs-alert"> - <div - class="fs-alert-content" - fxLayout="column" - fxFlex="100" - > - <div class="fs-alert-title">{{ runtimeName }}</div> + <sp-alert-banner + type="warning" + [title]="'Problems reading the following nodes' | translate" + [description]=" + 'Please change the adapter configuration to fix them.' + | translate + " + > + <div class="mt-md"> + @for (entry of badFieldStatusInfos(); track entry[0]) { + @let runtimeName = entry[0]; + @let info = entry[1]; + <div fxLayout="column"> + <div class="font-bold text-sm">{{ runtimeName }}</div> @if (info.additionalInfo) { - <div class="fs-alert-description"> - <span class="fs-additional">{{ - info.additionalInfo - }}</span> - </div> + <span class="text-sm">{{ + info.additionalInfo + }}</span> } </div> - </div> - } - </div> + } + </div> + </sp-alert-banner> } </div> diff --git a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.scss b/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.scss deleted file mode 100644 index 392bd952df..0000000000 --- a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.scss +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -.fs-alert { - padding: 0.75rem; - border-radius: 0.5rem; - display: flex; - align-items: flex-start; - gap: 0.75rem; - margin: 0.5rem 0; - background-color: var(--color-info-bg); - color: var(--color-info); -} - -.fs-alert-icon { - flex-shrink: 0; - width: 1.5rem; - height: 1.5rem; - display: flex; - align-items: center; - justify-content: center; -} - -.fs-alert-title { - font-weight: 700; - font-size: var(--font-size-sm); - line-height: 1.2; - word-break: break-word; -} - -.fs-alert-description { - margin-top: 0.25rem; - font-size: var(--font-size-sm); - line-height: 1.4; - opacity: 0.9; - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - align-items: center; -} - -.fs-status { - font-weight: 600; -} - -.fs-additional { - opacity: 0.9; -} diff --git a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.ts b/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.ts index f871d4219e..23fae3613f 100644 --- a/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.ts +++ b/ui/src/app/connect/components/adapter-configuration/configure-schema/show-field-status-infos/show-field-status-infos.component.ts @@ -18,18 +18,19 @@ import { Component, computed, input } from '@angular/core'; import { FieldStatusInfo } from '@streampipes/platform-services'; -import { - FlexDirective, - LayoutDirective, - LayoutGapDirective, -} from '@ngbracket/ngx-layout/flex'; -import { MatIcon } from '@angular/material/icon'; +import { FlexDirective, LayoutDirective } from '@ngbracket/ngx-layout/flex'; +import { SpAlertBannerComponent } from '@streampipes/shared-ui'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'sp-show-field-status-infos', templateUrl: './show-field-status-infos.component.html', - styleUrl: './show-field-status-infos.component.scss', - imports: [FlexDirective, LayoutDirective, MatIcon, LayoutGapDirective], + imports: [ + FlexDirective, + LayoutDirective, + SpAlertBannerComponent, + TranslatePipe, + ], }) export class ShowFieldStatusInfosComponent { fieldStatusInfos = input<{ [index: string]: FieldStatusInfo }>({}); diff --git a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-runtime-resolvable-tree-input.component.scss b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-runtime-resolvable-tree-input.component.scss index 2ca1376a8d..460ecc8c94 100644 --- a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-runtime-resolvable-tree-input.component.scss +++ b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-runtime-resolvable-tree-input.component.scss @@ -69,7 +69,6 @@ .node-metadata { border-bottom: 1px solid var(--color-bg-3); color: var(--color-default-text); - padding: 10px; } .node-name { diff --git a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.html b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.html index e5e97d892a..debf1a9698 100644 --- a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.html +++ b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.html @@ -20,11 +20,14 @@ </div> @for (metadata of nodeMetadata | keyvalue; track metadata) { <div - class="node-metadata" + class="node-metadata p-xs" fxLayout="row" + fxLayoutGap="5px" [attr.data-cy]="'node-details-metadata-row-' + metadata.key" > - <div fxFlex="30">{{ metadata.key }}</div> - <div fxFlex="70">{{ metadata.value }}</div> + <span class="text-sm" style="color: var(--fg-muted)">{{ + metadata.key + }}</span> + <span class="text-sm font-emphasized">{{ metadata.value }}</span> </div> } diff --git a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.ts b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.ts index 5a54071193..398fb874db 100644 --- a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.ts +++ b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-node-details/static-tree-input-node-details.component.ts @@ -18,12 +18,12 @@ import { Component, Input } from '@angular/core'; import { - FlexDirective, LayoutAlignDirective, LayoutDirective, } from '@ngbracket/ngx-layout/flex'; import { KeyValuePipe } from '@angular/common'; import { TranslatePipe } from '@ngx-translate/core'; +import { LayoutGapDirective } from '@ngbracket/ngx-layout'; @Component({ selector: 'sp-static-tree-input-node-details', @@ -32,9 +32,9 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ LayoutAlignDirective, LayoutDirective, - FlexDirective, KeyValuePipe, TranslatePipe, + LayoutGapDirective, ], }) export class StaticTreeInputNodeDetailsComponent {
