123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- <script setup lang="ts">
- import { coerceNodeId } from '@/ua/NodeId';
- import { UABaseNode } from '@/ua/UABaseNode';
- import { assert } from '@/util/assert';
- import { useStore } from '@/store';
- 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 openMenu = (event: any) => {
- isVisible.value = true;
- menuPosition.top = event.layerY + 'px';
- menuPosition.left = event.layerX + 'px';
- };
- const closeMenu = () => {
- isVisible.value = false;
- };
- const newInstance = () => {
- assert(store.addressSpace!=null)
- store.selectedNode = new UABaseNode({browseName: "new node", addressSpace: store.addressSpace, 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)">
- <slot></slot>
- <div v-if="isVisible" :style="menuStyle" class="context-menu">
- <button @click="newInstance">new instance</button>
- </div>
- </div>
- </template>
|