11<script setup lang="ts">
2- import type { RpcFunctionInfo , InvokeResult } from ' @devframes/plugin-inspect/client'
3- import { getHashColorFromString } from ' ../utils/color'
2+ import type { RpcFunctionInfo } from ' @devframes/plugin-inspect/client'
43import { ref } from ' vue'
4+ import { getHashColorFromString } from ' ../utils/color'
55import JsonView from ' ./JsonView.vue'
66
7- export type TreeNode = {
7+ export interface TreeNode {
88 name: string
99 fullPath: string
1010 isLeaf: boolean
@@ -23,6 +23,7 @@ const props = defineProps<{
2323
2424const emit = defineEmits <{
2525 (e : ' invoke' , fn : RpcFunctionInfo ): void
26+ (e : ' updateArgs' , name : string , value : string ): void
2627}>()
2728
2829const expandedNode = ref (props .depth < 1 )
@@ -33,24 +34,30 @@ function toggle() {
3334 expandedFn .value = ! expandedFn .value
3435 if (props .node .fn && props .argsInput [props .node .fn .name ] === undefined ) {
3536 // Initialize if empty
36- // Emitting an event just to set default isn't necessary because we mutate props.argsInput
37+ // Emitting an event just to set default isn't necessary because it's v-model bound
3738 }
38- } else {
39+ }
40+ else {
3941 expandedNode .value = ! expandedNode .value
4042 }
4143}
4244
4345const color = getHashColorFromString (props .node .fullPath )
46+ </script >
4447
48+ <script lang="ts">
49+ export default {
50+ name: ' FunctionsTreeNode' ,
51+ }
4552 </script >
4653
4754<template >
4855 <div class =" tree-node" >
49- <div v-if =" !node.isLeaf" class =" group-head" @click = " toggle " style =" cursor : pointer ; user-select : none ;" >
56+ <div v-if =" !node.isLeaf" class =" group-head" style =" cursor : pointer ; user-select : none ;" @click = " toggle " >
5057 <div class =" chev i-ph-caret-right" :class =" { open: expandedNode }" />
5158 <span class =" ns" :style =" { color }" >{{ node.name }}</span >
5259 </div >
53-
60+
5461 <div v-if =" node.isLeaf && node.fn" class =" fn-row" >
5562 <div class =" fn-head" :class =" { clickable: node.fn.invokable || !!node.fn.agent || node.fn.hasArgs || node.fn.hasReturns }" @click =" toggle" >
5663 <div class =" chev i-ph-caret-right" :class =" { open: expandedFn }" />
@@ -67,20 +74,28 @@ const color = getHashColorFromString(props.node.fullPath)
6774 </div >
6875
6976 <div v-if =" expandedFn" class =" fn-detail" >
70- <p v-if =" node.fn.agent" class =" desc" >{{ node.fn.agent.description }}</p >
77+ <p v-if =" node.fn.agent" class =" desc" >
78+ {{ node.fn.agent.description }}
79+ </p >
7180
7281 <template v-if =" node .fn .argsSchema " >
73- <div class =" label" >Args schema</div >
82+ <div class =" label" >
83+ Args schema
84+ </div >
7485 <JsonView :value =" node .fn .argsSchema " :expand-depth =" 0 " />
7586 </template >
7687 <template v-if =" node .fn .returnsSchema " >
77- <div class =" label" >Returns schema</div >
88+ <div class =" label" >
89+ Returns schema
90+ </div >
7891 <JsonView :value =" node .fn .returnsSchema " :expand-depth =" 0 " />
7992 </template >
8093
8194 <template v-if =" node .fn .invokable " >
82- <div class =" label" >Invoke — positional args as a JSON array</div >
83- <textarea v-model =" argsInput[node.fn.name]" class =" args" spellcheck =" false" placeholder =" []" />
95+ <div class =" label" >
96+ Invoke — positional args as a JSON array
97+ </div >
98+ <textarea :value =" argsInput[node.fn.name]" class =" args" spellcheck =" false" placeholder =" []" @input =" emit('updateArgs', node.fn.name, ($event.target as HTMLTextAreaElement).value)" />
8499 <div style =" margin-top : 8px ; display : flex ; gap : 8px ; align-items : center ;" >
85100 <button class =" btn" :disabled =" pending[node.fn.name] || isStatic()" @click.stop =" emit('invoke', node.fn!)" >
86101 {{ pending[node.fn.name] ? 'Invoking…' : 'Invoke' }}
@@ -109,7 +124,7 @@ const color = getHashColorFromString(props.node.fullPath)
109124
110125 <div v-if =" !node.isLeaf && expandedNode" class =" children" style =" padding-left : 14px ; border-left : 1px solid var (--df-border-soft ); margin-left : 6px ;" >
111126 <FunctionsTreeNode
112- v-for =" child in Object .values (node .children || {}).sort ((a ,b ) => { if (a .isLeaf !== b .isLeaf ) return a .isLeaf ? 1 : - 1 ; return a .name .localeCompare (b .name ) })"
127+ v-for =" child in Object .values (node .children || {}).sort ((a , b ) => { if (a .isLeaf !== b .isLeaf ) return a .isLeaf ? 1 : - 1 ; return a .name .localeCompare (b .name ) })"
113128 :key =" child .name "
114129 :node =" child "
115130 :depth =" depth + 1 "
@@ -118,13 +133,8 @@ const color = getHashColorFromString(props.node.fullPath)
118133 :pending =" pending "
119134 :is-static =" isStatic "
120135 @invoke =" emit (' invoke' , $event )"
136+ @update-args =" (n , v ) => emit (' updateArgs' , n , v ) "
121137 />
122138 </div >
123139 </div >
124140</template >
125-
126- <script lang="ts">
127- export default {
128- name: ' FunctionsTreeNode'
129- }
130- </script >
0 commit comments