Browse Source

Parent select dialog, uareferencetype

filter function/property for treeview
parse uareferencetype
fix treeview click bug
Martin Kunz 1 year ago
parent
commit
7483c21a35

+ 11 - 1
src/components/TheModeler.vue

@@ -7,6 +7,11 @@ const store = useStore()
 function selectNode(node: UABaseNode) {
   store.selectedNode=node;
 }
+
+function filter(node: UABaseNode) {
+  return false;
+}
+
 </script>
 
 <template>
@@ -15,7 +20,12 @@ function selectNode(node: UABaseNode) {
     <h5 class="card-title">Addressspace</h5>
     <p class="card-text">
       <ul>
-        <TreeItem class="item" :model="store.rootNode" v-if="store.rootNode!=null" @select-node="(node) => selectNode(node)"></TreeItem>
+        <TreeItem class="item" 
+          v-if="store.rootNode!=null" 
+          :model="store.rootNode" 
+          @select-node="(node) => selectNode(node)" 
+          :filter-func="(node:UABaseNode) => filter(node)">
+        </TreeItem>
       </ul>
     </p>
   </div>

+ 16 - 1
src/components/TheParent.vue

@@ -3,6 +3,7 @@ import { useStore } from '@/util/store'
 import { computed, ref } from 'vue';
 import TheTreeDialog from './TheTreeDialog.vue';
 import type { UABaseNode } from '@/ua/UABaseNode';
+import { ReferenceTypeIds } from '@/ua/opcua_node_ids';
 const store = useStore()
 
 const parentDialogOpen = ref(false);
@@ -13,9 +14,18 @@ const node = computed(() => {
 
 function clickNode(clickedNode: UABaseNode) {
   //TODO: replace parent references
+  node.value?.setParent(clickedNode, store.addressSpace?.findNode("ns=0;i="+ ReferenceTypeIds.HierarchicalReferences));
   parentDialogOpen.value=false;
 }
 
+function filter(fnode: UABaseNode) {
+  if(node.value?.nodeClass==="Variable") {
+    if(fnode.nodeClass!="Object")
+      return true;
+  }
+  return false;
+}
+
 </script>
 
 <template>
@@ -44,7 +54,12 @@ function clickNode(clickedNode: UABaseNode) {
       </div>
     </div>
   </div>
-  <TheTreeDialog :open="parentDialogOpen" @cancel="parentDialogOpen = false" @select-node="(node) => clickNode(node)"></TheTreeDialog>
+  <TheTreeDialog 
+    :open="parentDialogOpen" 
+    :filter-func="(node: UABaseNode) => filter(node)"
+    @cancel="parentDialogOpen = false" 
+    @select-node="(node) => clickNode(node)">
+  </TheTreeDialog>
 </template>
 
 

+ 8 - 1
src/components/TheTreeDialog.vue

@@ -6,6 +6,10 @@ import TreeItem from './TreeItem.vue'
 
 const store = useStore()
 const newDialogOpen = ref(false);
+
+defineProps({
+  filterFunc: Function
+})
 </script>
 
 <template>
@@ -18,8 +22,11 @@ const newDialogOpen = ref(false);
         <p class="card-text">
         <ul>
           <TreeItem class="item" 
+            v-if="store.rootNode != null"
+            :model="store.rootNode"
+            :filter-func = "$props.filterFunc"
             @select-node="(node) => $emit('selectNode', node)"
-            :model="store.rootNode" v-if="store.rootNode != null">
+             >
           </TreeItem>
         </ul>
         </p>

+ 12 - 4
src/components/TreeItem.vue

@@ -3,7 +3,8 @@ import { UABaseNode } from '@/ua/UABaseNode';
 import { ref, computed } from 'vue'
 
 const props = defineProps({
-  model: UABaseNode
+  model: UABaseNode,
+  filterFunc: Function
 })
 
 const isOpen = ref(false)
@@ -15,19 +16,21 @@ const isFolder = computed(() => {
 function toggle() {
   isOpen.value = !isOpen.value
 }
+
 </script>
 
 <template>
   <li>
-    <div v-if="model" :class="{ bold: isFolder }">
-      <span @click.stop="$emit('selectNode', model)">
+    <div v-if="model && filterFunc"  :class="{ bold: isFolder }">
+      <span v-if="isFolder" @click="toggle">[{{ isOpen ? '-' : '+' }}]</span>
+      <span @click.stop="$emit('selectNode', model)"  :class="{ disabled: filterFunc(model) }" >
         {{ model.displayName }}
       </span>
-      <span v-if="isFolder" @click="toggle">[{{ isOpen ? '-' : '+' }}]</span>
     </div>
     <ul v-show="isOpen" v-if="isFolder && model">
       <TreeItem
         class="item"
+        :filter-func = "$props.filterFunc"
         @select-node="(node: UABaseNode) => $emit('selectNode', node)"
         v-for="child in model.getChildren()"
         v-bind:key="child.nodeId.toString()"
@@ -48,6 +51,11 @@ function toggle() {
     text-align: left;
     list-style-type: none;
   }
+
+  .disabled {
+    cursor: not-allowed;
+    color: #aaa;
+  }
   .bold {
     font-weight: bold;
   }

+ 1 - 1
src/components/VDialog.vue

@@ -1,5 +1,5 @@
 <template>
-    <dialog ref="dialog" class="v-dialog" v-bind="attrs">
+    <dialog ref="dialog" class="v-dialog" v-bind="attrs" >
         <slot />
     </dialog>
 </template>

+ 5 - 1
src/ua/UABaseNode.ts

@@ -58,6 +58,10 @@ export class UABaseNode implements IToXML{
         return null;
     }
 
+    setParent(node: UABaseNode, refType: String) {
+        
+    }
+
     getParentRef(): UAReference|null{
         for(const ref of this.references) {
             switch(ref.referenceType) {
@@ -122,7 +126,7 @@ export class UABaseNode implements IToXML{
         const xmlReferences=xmlObject['References']||[];
         const references:UAReference[]=[];
         const nodeId=coerceNodeId(xmlObject['@_NodeId']);
-        for(const xmlref of xmlReferences.Reference) {
+        for(const xmlref of xmlReferences.Reference||[]) {
             references.push(UAReference.fromXML(xmlref, nodeId));
         }
         const ua=new UABaseNode({nodeId: nodeId,

+ 7 - 0
src/ua/UANodeSet.ts

@@ -6,6 +6,7 @@ import { UAMethod } from './UAMethod';
 import { NamespaceTable } from './NameSpaceTable';
 import { Model } from './Model';
 import { XMLElem, type IToXML } from '@/util/XmlElem';
+import { UAReferenceType } from './UAReferenceType';
 
 export class UANodeSet implements IToXML{
 
@@ -71,6 +72,8 @@ export class UANodeSet implements IToXML{
                     case 'UANodeSet.UAMethod.References.Reference':
                     case 'UANodeSet.UAVariable':
                     case 'UANodeSet.UAVariable.References.Reference':
+                    case 'UANodeSet.UAReferenceType':
+                    case 'UANodeSet.UAReferenceType.References.Reference':
                         return true;
                     default:
                         return false;
@@ -97,6 +100,10 @@ export class UANodeSet implements IToXML{
         for(const xmlMethod of xmlMethods) {
             nodes.push(UAMethod.fromXML(xmlMethod));
         }
+        const xmlReferenceTypes=xmlObj['UANodeSet']['UAReferenceType']||[];
+        for(const xmlReferenceType of xmlReferenceTypes) {
+            nodes.push(UAReferenceType.fromXML(xmlReferenceType));
+        }
         const uaNamespaceUris=xmlObj['UANodeSet']['NamespaceUris']||[];
         const nst=new NamespaceTable();
         for(const nsUri of uaNamespaceUris['Uri']||[]) {

+ 36 - 0
src/ua/UAReferenceType.ts

@@ -0,0 +1,36 @@
+import { XMLElem } from "@/util/XmlElem";
+import type { NamespaceTable } from "./NameSpaceTable";
+import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+
+export class UAReferenceType extends UABaseNode{
+
+    constructor(options: UAReferenceTypeOptions) {
+        super(options)
+    }
+
+    static  fromXML(uaMethod: any): UAReferenceType{
+        const bn=super.fromXML(uaMethod)
+        return new UAReferenceType({nodeId: bn.nodeId, 
+                            browseName: bn.browseName, 
+                            displayName: bn.displayName,
+                            references: bn.references});
+    }
+
+    toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {
+        const nid=UABaseNode.localNodeId(this.nodeId, lnst, gnst);
+        const elem =new XMLElem('UAReferenceType');
+        elem.attr('NodeId', nid.toString())
+            .attr('BrowseName', this.browseName)
+            .elem('DisplayName', this.displayName);
+        const refs=elem.add(new XMLElem('References'))
+        for(const ref of this.references) {
+            if(ref.fromNode.nodeId.toString()==this.nodeId.toString()) //on load resolveReferences() duplicates references to both sides. skip them for export
+                refs.add(ref.toXML(lnst, gnst));
+        }
+        return elem;
+    }
+}
+
+export interface UAReferenceTypeOptions extends UABaseNodeOptions{
+   
+}