From 89b9c6ae279341b3e3b8a7debfa2d86db1cede2a Mon Sep 17 00:00:00 2001 From: zjp Date: Fri, 30 Jan 2026 05:06:51 +0000 Subject: [PATCH 1/6] feat(ui): open adt popup panel when adt or field node is clicked --- ui/app/components/Flow.vue | 23 +++++++++++++++++------ ui/app/components/UPG.vue | 22 +++++++++++++++++++--- ui/app/lib/graph.ts | 4 ++++ ui/app/lib/output/adt.ts | 6 ++---- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/ui/app/components/Flow.vue b/ui/app/components/Flow.vue index 72716b5..5dc9b3e 100644 --- a/ui/app/components/Flow.vue +++ b/ui/app/components/Flow.vue @@ -21,10 +21,12 @@ import { adtURL, type FlowOpts } from '~/lib/topbar'; import type { PanelContent } from '~/lib/panel'; import ELK from 'elkjs/lib/elk.bundled.js' import { NodeKind, Plot, PlotConfig, type IdToItem } from '~/utils/graph'; -import type { AdtOpts } from '~/lib/output/adt'; +import type { AdtClicked, AdtOpts } from '~/lib/output/adt'; +import { extractAdtFromIdField } from '~/lib/graph'; const flowOpts = defineModel('flowOpts', { required: true }); const adtOpts = defineModel('adtOpts', { required: true }); +const adtClicked = defineModel('adtClicked', { required: true }); const panelContent = defineModel('panelContent', { required: true }); const elk = new ELK() @@ -57,17 +59,26 @@ const data = ref(EMPTY_DATA); // Respond to node click. onNodeClick(event => { - const selected = data.value.id_to_item[event.node.id] - if (selected && selected.kind === NodeKind.Adt) { + const id = event.node.id + const selected = data.value.id_to_item[id] + const selectAdt = selected?.kind === NodeKind.Adt + const selectField = selected?.kind === NodeKind.Field + + if (selectAdt || selectField) { const name = selected.name + const adt = selectField ? extractAdtFromIdField(id) : name // Update adt data. - const url = adtURL(name) + const url = adtURL(adt) $fetch(url) .then(text => { // Update nodeItem here because panel reacts to the two values. - panelContent.value.nodeItem = name - adtOpts.value = { name, data: JSON.parse(text as string) } + panelContent.value.nodeItem = adt + // Update adt data. + adtOpts.value = { name: adt, data: JSON.parse(text as string) } + // Update adt clicked. + const click = { clickedAdt: adt, clickedField: selectField ? name : undefined } + Object.assign(adtClicked.value, click) }) .catch(err => console.log("Failed to fetch adt.json", err)) return diff --git a/ui/app/components/UPG.vue b/ui/app/components/UPG.vue index 9c6889d..37f0718 100644 --- a/ui/app/components/UPG.vue +++ b/ui/app/components/UPG.vue @@ -2,8 +2,8 @@
- +
@@ -15,6 +15,11 @@ :unsafeFns="unsafeFns" />
+ + + diff --git a/ui/nuxt.config.ts b/ui/nuxt.config.ts index 685b4e0..83627fa 100644 --- a/ui/nuxt.config.ts +++ b/ui/nuxt.config.ts @@ -31,6 +31,10 @@ export default defineNuxtConfig({ 'tabler:search', // search 'tabler:sitemap', // sidebar 'tabler:browser-share', // share + 'tabler:hexagon-letter-c-filled', // constructor + 'tabler:hexagon-letter-f-filled', // field + 'tabler:hexagon-letter-a-filled', // argument + 'tabler:hexagon-letter-l-filled', // locals ], } }, From feca5905b836c6c64d92c3ca225281605eb611a0 Mon Sep 17 00:00:00 2001 From: zjp Date: Fri, 30 Jan 2026 12:21:05 +0000 Subject: [PATCH 4/6] feat(ui): set default subpanel and selected node in adt popup --- ui/app/components/UPG.vue | 12 ++-- ui/app/components/code/AdtPopup.vue | 94 +++++++++++++++++++++++++---- ui/app/lib/output/adt.ts | 5 +- 3 files changed, 93 insertions(+), 18 deletions(-) diff --git a/ui/app/components/UPG.vue b/ui/app/components/UPG.vue index c81042f..fcfc425 100644 --- a/ui/app/components/UPG.vue +++ b/ui/app/components/UPG.vue @@ -6,7 +6,7 @@ v-model:panelContent="panelContent" v-model:adtOpts="adtOpts" /> @@ -93,11 +93,13 @@ const adtOpts = ref({}); const adtClicked = ref({ open: false }) watch(() => ({ isAdtPanel: upPanel.value === Panel.Adt || downPanel.value === Panel.Adt, - adt: adtClicked.value.clickedAdt || adtClicked.value.clickedField -}), ({ isAdtPanel, adt }) => { + isClicked: adtClicked.value.clickedAdt || adtClicked.value.clickedField, + adt: adtClicked.value +}), ({ isAdtPanel, isClicked, adt }) => { // Auto open adt panel when side panels doesn't show adt panel, and user clicked adt or field. - if (!isAdtPanel && adt) - adtClicked.value = { open: true } + if (!isAdtPanel && isClicked) { + adtClicked.value = { open: true, lastClickedAdt: adt.clickedAdt, lastClickedField: adt.clickedField } + } }) const share = ref(false) diff --git a/ui/app/components/code/AdtPopup.vue b/ui/app/components/code/AdtPopup.vue index acefba6..6cd5016 100644 --- a/ui/app/components/code/AdtPopup.vue +++ b/ui/app/components/code/AdtPopup.vue @@ -1,6 +1,7 @@