33
44import { ref , computed , onMounted } from ' vue'
55import { useI18n } from ' vue-i18n'
6+ import { toast } from ' vue-sonner'
67import { Settings , Eye , EyeOff , AlertTriangle , Monitor } from ' lucide-vue-next'
78import { McpCatalogService } from ' @/services/mcpCatalogService'
89import { McpInstallationService } from ' @/services/mcpInstallationService'
@@ -167,10 +168,9 @@ const currentUserEnv = computed(() => {
167168
168169// Prepare user arguments with current values
169170const userArgsWithData = computed (() => {
170- return userArgsSchema .value .map ((argSchema : any , index : number ) => ({
171+ return userArgsSchema .value .map ((argSchema : any ) => ({
171172 ... argSchema ,
172- index ,
173- currentValue: currentUserArgs .value [index ] || ' '
173+ currentValue: currentUserEnv .value [argSchema .name ] || ' '
174174 }))
175175})
176176
@@ -202,11 +202,8 @@ const getDeviceValue = (item: any, deviceId: string, type: 'arg' | 'env') => {
202202 const userConfig = userConfigurations .value .find (config => config .device_id === deviceId )
203203 if (! userConfig ) return ' '
204204
205- if (type === ' arg' ) {
206- return userConfig .user_args ?.[item .index ] || ' '
207- } else {
208- return userConfig .user_env ?.[item .name ] || ' '
209- }
205+ // Both args and env are stored in user_env (args are named env vars)
206+ return userConfig .user_env ?.[item .name ] || ' '
210207}
211208
212209// Modal functions
@@ -264,64 +261,88 @@ const handleEdit = async () => {
264261 isSubmitting .value = true
265262
266263 try {
267- // Find existing user config for this device or create new one
264+ // Find existing user config for this device
268265 let userConfig = userConfigurations .value .find (config => config .device_id === editingDevice .value .id )
269266
270267 if (! userConfig ) {
271- // Create new user configuration for this device
272- const initialArgs = new Array (userArgsSchema .value .length ).fill (' ' )
273- const initialEnv: Record <string , string > = {}
268+ // Create new user configuration for this device with only the specific field
269+ const createData: any = {
270+ device_id: editingDevice .value .id
271+ }
272+
273+ if (editingType .value === ' arg' ) {
274+ // Create env object with the named argument (args are actually env vars)
275+ createData .user_env = {
276+ [editingItem .value .name ]: editingValue .value
277+ }
278+ } else {
279+ // Create env object with only the specific variable set
280+ createData .user_env = {
281+ [editingItem .value .name ]: editingValue .value
282+ }
283+ }
274284
275285 userConfig = await McpInstallationService .createUserConfiguration (
276286 props .teamId ,
277287 props .installation .id ,
278- {
279- device_id: editingDevice .value .id ,
280- user_args: initialArgs ,
281- user_env: initialEnv
282- }
288+ createData
283289 )
284290
285291 userConfigurations .value .push (userConfig )
286- }
287-
288- // Update the specific field
289- let updatedArgs = [... (userConfig .user_args || [])]
290- let updatedEnv = { ... (userConfig .user_env || {}) }
291-
292- if (editingType .value === ' arg' ) {
293- // Ensure array is large enough
294- while (updatedArgs .length <= editingItem .value .index ) {
295- updatedArgs .push (' ' )
296- }
297- updatedArgs [editingItem .value .index ] = editingValue .value
298292 } else {
299- updatedEnv [editingItem .value .name ] = editingValue .value
300- }
301-
302- // Update the configuration
303- const updatedConfig = await McpInstallationService .updateUserConfiguration (
304- props .teamId ,
305- props .installation .id ,
306- userConfig .id ,
307- {
308- device_id: editingDevice .value .id ,
309- user_args: updatedArgs ,
310- user_env: updatedEnv
293+ // Update existing configuration with only the specific field
294+ const updateData: any = {
295+ device_id: editingDevice .value .id
311296 }
312- )
313-
314- // Update local state
315- const configIndex = userConfigurations .value .findIndex (c => c .id === userConfig ! .id )
316- if (configIndex >= 0 ) {
317- userConfigurations .value [configIndex ] = updatedConfig
297+
298+ if (editingType .value === ' arg' ) {
299+ // Update only the env vars object (args are actually env vars)
300+ const updatedEnv = { ... (userConfig .user_env || {}) }
301+ updatedEnv [editingItem .value .name ] = editingValue .value
302+ updateData .user_env = updatedEnv
303+ } else {
304+ // Update only the env vars object
305+ const updatedEnv = { ... (userConfig .user_env || {}) }
306+ updatedEnv [editingItem .value .name ] = editingValue .value
307+ updateData .user_env = updatedEnv
308+ }
309+
310+ // Update the configuration
311+ const updatedConfig = await McpInstallationService .updateUserConfiguration (
312+ props .teamId ,
313+ props .installation .id ,
314+ userConfig .id ,
315+ updateData
316+ )
317+
318+ // Update local state
319+ const configIndex = userConfigurations .value .findIndex (c => c .id === userConfig ! .id )
320+ if (configIndex >= 0 ) {
321+ userConfigurations .value [configIndex ] = updatedConfig
322+ }
323+
324+ userConfig = updatedConfig
318325 }
319326
320- emit (' configuration-updated' , updatedConfig )
327+ emit (' configuration-updated' , userConfig )
328+
329+ // Show success toast
330+ toast .success (t (' mcpInstallations.userConfiguration.editModal.messages.saveSuccess' ), {
331+ description: t (' mcpInstallations.userConfiguration.editModal.messages.saveSuccessDescription' , {
332+ item: editingItem .value .name ,
333+ device: editingDevice .value .device_name
334+ })
335+ })
321336
322337 closeEditModal ()
323338 } catch (error ) {
324339 console .error (' Error updating user configuration:' , error )
340+
341+ // Show error toast
342+ toast .error (t (' mcpInstallations.userConfiguration.editModal.messages.saveError' ), {
343+ description: error instanceof Error ? error .message : t (' mcpInstallations.userConfiguration.editModal.messages.saveErrorDescription' )
344+ })
345+
325346 formErrors .value .general = error instanceof Error ? error .message : ' Failed to update configuration'
326347 } finally {
327348 isSubmitting .value = false
@@ -331,9 +352,7 @@ const handleEdit = async () => {
331352const modalTitle = computed (() => {
332353 if (! editingItem .value || ! editingDevice .value ) return ' '
333354
334- const itemName = editingType .value === ' arg'
335- ? t (' mcpInstallations.userConfiguration.table.values.argumentNumber' , { number: editingItem .value .index + 1 })
336- : editingItem .value .name
355+ const itemName = editingItem .value .name
337356
338357 return t (' mcpInstallations.userConfiguration.editModal.title' , {
339358 item: itemName ,
@@ -380,12 +399,12 @@ const modalTitle = computed(() => {
380399 </div >
381400
382401 <ul role =" list" class =" space-y-3" >
383- <li v-for =" arg in userArgsWithData" :key =" arg.index " class =" bg-muted/50 rounded-lg px-4 py-5" >
402+ <li v-for =" arg in userArgsWithData" :key =" arg.name " class =" bg-muted/50 rounded-lg px-4 py-5" >
384403 <div class =" flex items-center justify-between gap-x-6 mb-4" >
385404 <div class =" min-w-0 flex-1" >
386405 <div class =" flex items-start gap-x-3" >
387406 <p class =" text-sm/6 font-semibold text-gray-900 font-mono" >
388- {{ t('mcpInstallations.userConfiguration.table.values.argumentNumber', { number: arg.index + 1 }) }}
407+ {{ arg.name }}
389408 </p >
390409 </div >
391410 <div class =" mt-1 text-xs/5 text-gray-700" >
@@ -579,7 +598,7 @@ const modalTitle = computed(() => {
579598 {{ editingType === 'arg' ? t('mcpInstallations.userConfiguration.editModal.form.labels.argument') : t('mcpInstallations.userConfiguration.editModal.form.labels.variable') }}
580599 </span >
581600 <code class =" bg-gray-200 text-gray-800 px-2 py-1 rounded font-mono text-xs font-semibold" >
582- {{ editingType === 'arg' ? t('mcpInstallations.userConfiguration.table.values.argumentNumber', { number: editingItem.index + 1 }) : editingItem.name }}
601+ {{ editingItem.name }}
583602 </code >
584603 <Badge v-if =" editingItem.required" variant =" default" class =" text-xs" >
585604 {{ t('mcpInstallations.userConfiguration.table.values.required') }}
@@ -652,8 +671,12 @@ const modalTitle = computed(() => {
652671 <Button type =" button" variant =" outline" @click =" closeEditModal" >
653672 {{ t('mcpInstallations.userConfiguration.editModal.form.buttons.cancel') }}
654673 </Button >
655- <Button type =" submit" :disabled =" isSubmitting" >
656- {{ isSubmitting ? t('mcpInstallations.userConfiguration.editModal.form.buttons.saving') : t('mcpInstallations.userConfiguration.editModal.form.buttons.save') }}
674+ <Button
675+ type =" submit"
676+ :loading =" isSubmitting"
677+ :loadingText =" t('mcpInstallations.userConfiguration.editModal.form.buttons.saving')"
678+ >
679+ {{ t('mcpInstallations.userConfiguration.editModal.form.buttons.save') }}
657680 </Button >
658681 </AlertDialogFooter >
659682 </form >
0 commit comments