McpEditPage.vue
1 <script setup lang="ts"> 2 import { ref, watch, onMounted } from 'vue' 3 import { getServers } from '@/renderer/store/mcp' 4 import { useStdioStore, CustomStdioServerParameters, StdioServerKey } from '@/renderer/store/stdio' 5 6 import ConfigJsonCard from '@/renderer/components/common/ConfigJsonCard.vue' 7 8 const stdioStore = useStdioStore() 9 10 const props = defineProps({ 11 modelValue: { 12 type: Boolean, 13 required: true 14 }, 15 name: { 16 type: String, 17 required: true 18 } 19 }) 20 21 const emit = defineEmits(['update:modelValue']) 22 23 const internalDialog = ref(props.modelValue) 24 25 watch( 26 () => props.modelValue, 27 (newVal) => { 28 internalDialog.value = newVal 29 } 30 ) 31 32 watch(internalDialog, (newVal) => { 33 emit('update:modelValue', newVal) 34 }) 35 36 const closeDialog = () => { 37 internalDialog.value = false 38 } 39 40 function findConfig( 41 jsonConfig: CustomStdioServerParameters | Record<string, CustomStdioServerParameters> 42 ): CustomStdioServerParameters { 43 if (!jsonConfig) return {} 44 if ('command' in jsonConfig) { 45 return jsonConfig 46 } else { 47 return findConfig(Object.values(jsonConfig)[0]) 48 } 49 } 50 51 const updateConfig = () => { 52 const jsonConfig = findConfig(jsonParams.value) 53 54 ;(['command', 'args', 'env'] as StdioServerKey[]).forEach((key) => { 55 const value = jsonConfig[key] 56 if (value) { 57 stdioStore.updateConfigAttribute(props.name, key, value) 58 } 59 }) 60 61 closeDialog() 62 } 63 64 const jsonError = ref<string | null>(null) 65 66 function handleError(errorMessage: string | null) { 67 jsonError.value = errorMessage 68 } 69 70 const jsonParams = ref<CustomStdioServerParameters>({}) 71 72 onMounted(() => { 73 const configs = getServers() 74 if (!configs) return 75 const config = configs[props.name] 76 if (!config) return 77 const stdioConfig = config.metadata?.config 78 if (stdioConfig) { 79 jsonParams.value = stdioConfig as CustomStdioServerParameters 80 } 81 }) 82 </script> 83 84 <template> 85 <v-dialog v-model="internalDialog" persistent max-width="80vw" max-height="80vh" scrollable> 86 <v-card> 87 <v-card-title> 88 {{ props.name }} 89 </v-card-title> 90 <v-divider></v-divider> 91 <v-card-text class="mt-2"> 92 <ConfigJsonCard v-model="jsonParams" @on-error="handleError"></ConfigJsonCard> 93 </v-card-text> 94 <v-card-actions> 95 <v-spacer></v-spacer> 96 <v-btn 97 variant="plain" 98 rounded="lg" 99 icon="mdi-close-box" 100 color="error" 101 @click="closeDialog" 102 ></v-btn> 103 <v-btn 104 variant="plain" 105 rounded="lg" 106 icon="mdi-content-save-plus" 107 :disabled="Boolean(jsonError ?? '')" 108 color="success" 109 @click="updateConfig()" 110 ></v-btn> 111 </v-card-actions> 112 </v-card> 113 </v-dialog> 114 </template>