-
Notifications
You must be signed in to change notification settings - Fork 2
feat: MCP tool for adding tree controls #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<template> | ||
<div class="ecs-container"> | ||
<tiny-tree | ||
:tiny_mcp_config="{ | ||
server, | ||
business: { | ||
id: 'cpu-tree', | ||
description: 'CPU规格的树' | ||
} | ||
}" | ||
node-key="id" | ||
:data="data" | ||
show-checkbox | ||
highlight-current | ||
:default-expanded-keys="['1']" | ||
:check-on-click-node="true" | ||
:expand-on-click-node="false" | ||
></tiny-tree> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="jsx"> | ||
import { ref } from 'vue' | ||
import { useNextServer } from '@opentiny/next-vue' | ||
const data = ref([ | ||
{ | ||
id: '1', | ||
label: '操作系统', | ||
children: [ | ||
{ id: '2', label: ' windows', | ||
children: [ | ||
{ id: '3', label: ' windows 10' }, | ||
{ id: '4', label: ' windows 11' }, | ||
{ id: '5', label: ' windows 12' }, | ||
{ id: '7', label: ' windows 13' } | ||
] | ||
}, | ||
{ id: '8', label: 'linux', | ||
children: [ | ||
{ id: '9', label: 'linux 10' }, | ||
{ id: '10', label: 'linux 11' }, | ||
{ id: '11', label: 'linux 12' }, | ||
{ id: '12', label: 'linux 13' } | ||
] | ||
}, | ||
{ id: '13', label: 'macos'}, | ||
{ id: '14', label: 'harmonyOS'}, | ||
] | ||
}, | ||
]) | ||
|
||
const { server } = useNextServer({ | ||
serverInfo: { name: 'ecs-console', version: '1.0.0' } | ||
}) | ||
</script> | ||
|
||
<style scoped> | ||
.checkbox-demo { | ||
display: flex; | ||
margin: 16px; | ||
} | ||
|
||
.checkbox-demo .tiny-tree { | ||
flex: 1; | ||
min-width: 300px; | ||
} | ||
|
||
.checkbox-demo div { | ||
margin-bottom: 8px; | ||
} | ||
|
||
.tip { | ||
font-weight: bold; | ||
} | ||
</style> |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -28,7 +28,16 @@ export default { | |||||
}, | ||||||
button: { | ||||||
description: 'Button component related tool set', | ||||||
triggerClick: 'Button click, click the button' | ||||||
triggerClick: 'trigger button click,click self' | ||||||
}, | ||||||
tree: { | ||||||
description: 'Collection of Tools Related to Tree Control Components', | ||||||
setCurrentKey: 'Please enter the ID value to set the current selected state of a node', | ||||||
expandHlNode: 'Please enter the ID value to set the current deployment status of a node', | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Fix terminology: "deployment" should be "expanded". The term "deployment status" is incorrect in the context of tree nodes. It should refer to the expanded/collapsed state. - expandHlNode: 'Please enter the ID value to set the current deployment status of a node',
+ expandHlNode: 'Please enter the ID value to set the expanded state of a node', 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||
collapseHlNode: 'Please enter the ID value to set the collapsed state of a node', | ||||||
removeNode: 'Please enter the ID value to delete a node', | ||||||
insertBefore: 'Add a node in front of a node', | ||||||
insertAfter: 'Add a node after a node', | ||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,70 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { z } from 'zod' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { defineComponentTool } from '../utils/defineComponentTool' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import resourcesZh from './resouces.zh.md?raw' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import resourcesEn from './resouces.en.md?raw' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { t } from '../utils/locale' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const resources = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zh: resourcesZh, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
en: resourcesEn | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const getTreeConfig = () => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defineComponentTool({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name: 'tree_component_tools', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
description: t('ai.tree.description'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tools: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setCurrentKey: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.tree.setCurrentKey')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if(instance.showCheckbox){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.setCheckedKeys([value]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}else{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.setCurrentKey(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+17
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for undefined values. The setCurrentKey: {
paramsSchema: z.string().optional().describe(t('ai.tree.setCurrentKey')),
cb: (instance, value) => {
+ if (!value) {
+ return { type: 'text', text: 'Error: ID value is required' }
+ }
if(instance.showCheckbox){
instance.setCheckedKeys([value])
}else{
instance.setCurrentKey(value)
}
return { type: 'text', text: 'success' }
}
}, 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expandHlNode: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.tree.expandHlNode')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const node = instance.getNode(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
node.expand() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
collapseHlNode: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.tree.collapseHlNode')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const node = instance.getNode(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
node.collapse() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+28
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for node operations. The expandHlNode: {
paramsSchema: z.string().optional().describe(t('ai.tree.expandHlNode')),
cb: (instance, value) => {
+ if (!value) {
+ return { type: 'text', text: 'Error: ID value is required' }
+ }
const node = instance.getNode(value)
+ if (!node) {
+ return { type: 'text', text: `Error: Node with ID ${value} not found` }
+ }
node.expand()
return { type: 'text', text: 'success' }
}
},
collapseHlNode: {
paramsSchema: z.string().optional().describe(t('ai.tree.collapseHlNode')),
cb: (instance, value) => {
+ if (!value) {
+ return { type: 'text', text: 'Error: ID value is required' }
+ }
const node = instance.getNode(value)
+ if (!node) {
+ return { type: 'text', text: `Error: Node with ID ${value} not found` }
+ }
node.collapse()
return { type: 'text', text: 'success' }
}
}, 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
removeNode: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.tree.removeNode')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.remove(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
insertBefore: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertBefore')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve validation schema for insert operations. The current schema - paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertBefore')),
+ paramsSchema: z.object({
+ id: z.string().describe('Target node ID'),
+ label: z.string().describe('New node label')
+ }).describe(t('ai.tree.insertBefore')), Apply the same change to - paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertAfter')),
+ paramsSchema: z.object({
+ id: z.string().describe('Target node ID'),
+ label: z.string().describe('New node label')
+ }).describe(t('ai.tree.insertAfter')), Also applies to: 61-61 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let id = 1000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.insertBefore({ id, label: value.label }, value.id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id++ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
insertAfter: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertAfter')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let id = 1000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.insertAfter({ id, label: value.label }, value.id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id++ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+51
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix ID generation logic causing duplicate IDs. The +let nextId = 1000 // Move outside the functions
insertBefore: {
paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertBefore')),
cb: (instance, value) => {
- let id = 1000
- instance.insertBefore({ id, label: value.label }, value.id)
- id++
+ if (!value || !value.id || !value.label) {
+ return { type: 'text', text: 'Error: Both id and label are required' }
+ }
+ instance.insertBefore({ id: nextId++, label: value.label }, value.id)
return { type: 'text', text: 'success' }
}
},
insertAfter: {
paramsSchema: z.record(z.any()).optional().describe(t('ai.tree.insertAfter')),
cb: (instance, value) => {
- let id = 1000
- instance.insertAfter({ id, label: value.label }, value.id)
- id++
+ if (!value || !value.id || !value.label) {
+ return { type: 'text', text: 'Error: Both id and label are required' }
+ }
+ instance.insertAfter({ id: nextId++, label: value.label }, value.id)
return { type: 'text', text: 'success' }
}
}, 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Tree Component | ||
|
||
It can display data with parent-child hierarchy, and supports functions such as selecting, dragging, and editing nodes. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Tree 树形控件 | ||
|
||
可进行展示有父子层级的数据,支持选择,拖拽和编辑节点等功能。 |
Uh oh!
There was an error while loading. Please reload this page.