|
@@ -0,0 +1,66 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { NodeId, coerceNodeId } from '@/ua/NodeId';
|
|
|
+import { UABaseNode } from '@/ua/UABaseNode';
|
|
|
+import { useStore } from '@/util/store';
|
|
|
+import { storeToRefs } from 'pinia';
|
|
|
+import { ref, reactive, onMounted, onUnmounted, computed, type CSSProperties } from 'vue';
|
|
|
+
|
|
|
+const isVisible = ref(false);
|
|
|
+const menuPosition = reactive({ top: "0px", left: "0px" });
|
|
|
+const store = useStore();
|
|
|
+const { selectedNode } = storeToRefs(store);
|
|
|
+
|
|
|
+const openMenu = (event: any) => {
|
|
|
+ isVisible.value = true;
|
|
|
+ menuPosition.top = event.layerY + 'px';
|
|
|
+ menuPosition.left = event.layerX + 'px';
|
|
|
+};
|
|
|
+
|
|
|
+const closeMenu = () => {
|
|
|
+ isVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+const newInstance = () => {
|
|
|
+ store.selectedNode = new UABaseNode({browseName: "new node", nodeId: coerceNodeId("ns=0;i=999999")});
|
|
|
+ closeMenu();
|
|
|
+};
|
|
|
+
|
|
|
+const menuStyle = computed<CSSProperties>(() => ({
|
|
|
+ position: "absolute",
|
|
|
+ top: menuPosition.top,
|
|
|
+ left: menuPosition.left,
|
|
|
+ zIndex: 5,
|
|
|
+}));
|
|
|
+
|
|
|
+const handleClickOutside = (event: any) => {
|
|
|
+ if (!event.target.closest('.context-menu')) {
|
|
|
+ closeMenu();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ document.addEventListener('click', handleClickOutside);
|
|
|
+});
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ document.removeEventListener('click', handleClickOutside);
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.context-menu {
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ background-color: white;
|
|
|
+ padding: 10px;
|
|
|
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div @contextmenu.prevent="openMenu($event)" :style="{ position: 'absolute' }">
|
|
|
+ <slot></slot>
|
|
|
+ <div v-if="isVisible" :style="menuStyle" class="context-menu">
|
|
|
+ <button @click="newInstance">new instance</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|