|
@@ -0,0 +1,191 @@
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { useStore } from '@/util/store'
|
|
|
|
+import { computed, ref } from 'vue';
|
|
|
|
+import type { UABaseNode } from '@/ua/UABaseNode';
|
|
|
|
+import { ReferenceTypeIds } from '@/ua/opcua_node_ids';
|
|
|
|
+import type { UAReferenceType } from '@/ua/UAReferenceType';
|
|
|
|
+import { ObjectTypeIds } from '@/ua/opcua_node_ids';
|
|
|
|
+import type { UAObjectType } from '@/ua/UAObjectType';
|
|
|
|
+import { VariableTypeIds } from '@/ua/opcua_node_ids';
|
|
|
|
+import type { UAVariableType } from '@/ua/UAVariableType';
|
|
|
|
+import { UAReference } from '@/ua/UAReference';
|
|
|
|
+import { UAObject } from '@/ua/UAObject';
|
|
|
|
+import { UAVariable } from '@/ua/UAVariable';
|
|
|
|
+import {sconfig} from "@/util/ServerConfig"
|
|
|
|
+const store = useStore()
|
|
|
|
+
|
|
|
|
+const parentDialogOpen = ref(false);
|
|
|
|
+const node = computed(() => {
|
|
|
|
+ return store.selectedNode;
|
|
|
|
+
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getRefTypes():UABaseNode[] {
|
|
|
|
+ let list=(store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.HierarchicalReferences)||[]) as UAReferenceType[];
|
|
|
|
+ list=list.filter((node) => node.isAbstract==false)
|
|
|
|
+ return list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getObjTypes(flag:any):UABaseNode[] {
|
|
|
|
+ let list = [];
|
|
|
|
+ if(flag){
|
|
|
|
+ list=(store.addressSpace?.getSubTreeAsList("ns=0;i=89")||[]) as UAVariableType[];
|
|
|
|
+ }else{
|
|
|
|
+ list=(store.addressSpace?.getSubTreeAsList("ns=0;i=88")||[]) as UAObjectType[];
|
|
|
|
+ }
|
|
|
|
+ list=list.filter((node) => node.isAbstract==false)
|
|
|
|
+ return list;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function defType(flag:any ):String{
|
|
|
|
+ let lab = "ObjectType";
|
|
|
|
+ if(flag){
|
|
|
|
+ lab = "VariableType";
|
|
|
|
+ }
|
|
|
|
+ return lab;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function getInstanceDecl(nid="ns=0;i=58"){
|
|
|
|
+ if(nid == "") nid = "ns=0;i=58";
|
|
|
|
+ let component_refs:String[] = [];
|
|
|
|
+ let res_man:any[] = [];
|
|
|
|
+ let res_opt:any[] = [];
|
|
|
|
+ let res:any[] = [];
|
|
|
|
+ let node = (store.addressSpace?.findNode(nid)) as UABaseNode;
|
|
|
|
+ let refs = node.references;
|
|
|
|
+ let list = (store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.Aggregates)||[]) as UABaseNode[];
|
|
|
|
+ list.forEach((item) => {
|
|
|
|
+ component_refs.push(item.browseName);
|
|
|
|
+ })
|
|
|
|
+ refs.forEach((item) => {
|
|
|
|
+ if(component_refs.includes(item.referenceType) && item.isForward){
|
|
|
|
+ let mr = "";
|
|
|
|
+ if(item.toNode.nodeClass == "Object"){
|
|
|
|
+ let i = item.toNode as UAObject;
|
|
|
|
+ mr = i.getModellingRule();
|
|
|
|
+ }else if(item.toNode.nodeClass == "Variable"){
|
|
|
|
+ let i = item.toNode as UAVariable;
|
|
|
|
+ mr = i.getModellingRule();
|
|
|
|
+ }
|
|
|
|
+ if(mr == "Mandatory"){
|
|
|
|
+ const newItem = { ref: item, checked: true, modellingRule:mr };
|
|
|
|
+ res_man.push(newItem);
|
|
|
|
+ }else{
|
|
|
|
+ const newItem = { ref: item, checked: false, modellingRule:mr };
|
|
|
|
+ res_opt.push(newItem);
|
|
|
|
+ }
|
|
|
|
+ res.push(res_man);
|
|
|
|
+ res.push(res_opt);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ return res;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+async function createDynamic() {
|
|
|
|
+ const blob = await store.addressSpace?.exportProject();
|
|
|
|
+ if ('dynamics' in sconfig){
|
|
|
|
+ sconfig.dynamics.push("hello");
|
|
|
|
+ }else{
|
|
|
|
+ sconfig.dynamics = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+const type_def = ref("")
|
|
|
|
+const checked = ref("")
|
|
|
|
+const type = ref("")
|
|
|
|
+const components = ref("")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<template>
|
|
|
|
+ <div class="card">
|
|
|
|
+ <div class="card-body" v-if="node != null">
|
|
|
|
+ <h5 class="card-title">Dynamic Node</h5>
|
|
|
|
+ <div class="card-text">
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <div class="input-group-prepend">
|
|
|
|
+ <span class="input-group-text" id="inputGroup-sizing-default">Parent Node</span>
|
|
|
|
+ </div>
|
|
|
|
+ <input readonly type="text" class="form-control" aria-label="Default"
|
|
|
|
+ aria-describedby="inputGroup-sizing-default" :value="node?.nodeId">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <div class="input-group-prepend">
|
|
|
|
+ <span class="input-group-text" id="inputGroup-sizing-default">Reference</span>
|
|
|
|
+ </div>
|
|
|
|
+ <select class="form-select" aria-label="Default select example">
|
|
|
|
+ <option v-for="option in getRefTypes()" :value="option.nodeId.toString()" v-bind:key="option.nodeId.toString()">
|
|
|
|
+ {{ option.displayName }}
|
|
|
|
+ </option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <div class="input-group-prepend">
|
|
|
|
+ <input type="checkbox" id="checkbox" v-model="checked" />
|
|
|
|
+ <label for="checkbox">{{ defType(checked) }}</label>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <div class="input-group-prepend">
|
|
|
|
+ <span class="input-group-text" id="inputGroup-sizing-default">Type Definition</span>
|
|
|
|
+ </div>
|
|
|
|
+ <select v-model="type" class="form-select" aria-label="Default select example">
|
|
|
|
+ <option v-for="option1 in getObjTypes(checked)" :value="option1.nodeId.toString()" v-bind:key="option1.nodeId.toString()">
|
|
|
|
+ {{ option1.displayName }}
|
|
|
|
+ </option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <ul class="no-bullets">Mandatory Components
|
|
|
|
+ <li v-for="todo in getInstanceDecl(type)[0]">
|
|
|
|
+ <input type="checkbox" id="checkbox-{{ todo.ref.toNode.displayName }}" v-model="todo.checked" :disabled="true">
|
|
|
|
+ <label for="checkbox-{{ todo.ref.toNode.displayName }}">{{ todo.ref.toNode.displayName }}</label>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <ul class="no-bullets">Optional Components
|
|
|
|
+ <li v-for="todo1 in (getInstanceDecl(type)[1])">
|
|
|
|
+ <input type="checkbox" id="checkbox-digg" v-model="todo1.checked">
|
|
|
|
+ <label for="checkbox-digg">{{ todo1.ref.toNode.displayName }}</label>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <button class="btn btn-light" @click.prevent="createDynamic()">Create</button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+ ul.no-bullets {
|
|
|
|
+ list-style-type: none;
|
|
|
|
+ margin: 0;
|
|
|
|
+ padding: 0;
|
|
|
|
+}
|
|
|
|
+</style>
|