11<script setup lang="ts">
2- import { ref , computed , watch } from ' vue'
2+ import { ref , computed , watch , shallowRef } from ' vue'
33import { useApiStore } from ' @/stores/apiStore'
4+ import type * as monaco from ' monaco-editor'
45import { formatISO9075 } from ' date-fns'
56const apiStore = useApiStore ()
67apiStore .updateRequestList ()
@@ -10,6 +11,23 @@ apiStore.connectWS()
1011const headersOpen = ref (true )
1112const headerCount = computed (() => Object .keys (apiStore .selectedRequest ?.headers || {}).length )
1213
14+ const MONACO_EDITOR_OPTIONS = {
15+ automaticLayout: true ,
16+ }
17+ // watch(
18+ // () => apiStore.darkMode,
19+ // (newVal) => {
20+ // console.log('Theme changed:', newVal)
21+ // if (monacoIns.value) {
22+ // console.log(monacoIns.value)
23+ // ;(monacoIns.value as any).editor.setTheme(newVal ? 'vs-dark' : 'vs')
24+ // }
25+ // // if (editor.value) {
26+ // // editor.value.updateOptions({ theme: newVal ? 'vs-dark' : 'vs' })
27+ // // }
28+ // },
29+ // )
30+
1331// Authorization reveal toggle
1432const showAuth = ref (false )
1533watch (
@@ -59,6 +77,37 @@ function decodeBasicAuth(value: string): { isBasic: boolean; user?: string; pass
5977 return { isBasic: false }
6078 }
6179}
80+
81+ const editor = shallowRef <monaco .editor .IStandaloneCodeEditor >()
82+ const monacoIns = shallowRef <unknown >()
83+ function handleMount(monacoEditor : monaco .editor .IStandaloneCodeEditor , monacoInstance : unknown ) {
84+ editor .value = monacoEditor
85+ monacoIns .value = monacoInstance
86+ }
87+
88+ // Derive Monaco language from Content-Type header
89+ function detectLanguageFromContentType(ct ? : string | null ): string {
90+ if (! ct ) return ' plaintext'
91+ const base = ct .split (' ;' )[0 ]?.trim ().toLowerCase () || ' '
92+ // Broad matches first
93+ if (base .includes (' json' )) return ' json'
94+ if (base .includes (' xml' )) return ' xml'
95+ if (base .includes (' html' )) return ' html'
96+ if (base .includes (' markdown' )) return ' markdown'
97+ if (base .includes (' yaml' ) || base .endsWith (' /yml' )) return ' yaml'
98+ if (base .includes (' javascript' ) || base .endsWith (' /js' )) return ' javascript'
99+ if (base .includes (' typescript' ) || base .endsWith (' /ts' )) return ' typescript'
100+ if (base .includes (' css' )) return ' css'
101+ if (base .includes (' sql' )) return ' sql'
102+ if (base .includes (' form-urlencoded' )) return ' plaintext'
103+ if (base .startsWith (' text/' )) return ' plaintext'
104+ return ' plaintext'
105+ }
106+
107+ const monacoLanguage = computed (() => {
108+ const ct = apiStore .selectedRequest ?.headers ?.[' content-type' ]
109+ return detectLanguageFromContentType (ct )
110+ })
62111 </script >
63112
64113<template >
@@ -149,7 +198,7 @@ function decodeBasicAuth(value: string): { isBasic: boolean; user?: string; pass
149198 </v-card >
150199 </div >
151200 <!-- Main Content -->
152- <div class =" flex-1 p-4 pane-scroll " >
201+ <div class =" flex-1 p-4" style = " height : 100 % " >
153202 <v-fade-transition v-if =" apiStore.selectedRequest" mode =" out-in" >
154203 <v-card
155204 density =" compact"
@@ -426,25 +475,22 @@ function decodeBasicAuth(value: string): { isBasic: boolean; user?: string; pass
426475 >
427476 </template >
428477 </p >
478+
429479 <v-sheet
430480 :elevation =" 2"
431481 border
432482 rounded
433483 class =" font-mono pa-2 text-xs rounded mb-2"
434484 tag =" pre"
435- >{{ apiStore.selectedRequest.body_text }}</v-sheet
436485 >
437- <template v-if =" apiStore .selectedRequest .body_bytes_b64 " >
438- <p ><strong >Body (Base64):</strong ></p >
439- <v-sheet
440- :elevation =" 2"
441- border
442- rounded
443- class =" font-mono pa-2 text-xs rounded mb-2"
444- tag =" pre"
445- >{{ apiStore.selectedRequest.body_bytes_b64 }}</v-sheet
446- >
447- </template >
486+ <vue-monaco-editor
487+ v-model:value =" apiStore.selectedRequest.body_text"
488+ :theme =" apiStore.darkMode ? 'vs-dark' : 'vs'"
489+ :language =" monacoLanguage"
490+ :options =" MONACO_EDITOR_OPTIONS"
491+ style =" min-height : 300px "
492+ @mount =" handleMount"
493+ /></v-sheet >
448494 </template >
449495 </div >
450496 </v-card >
0 commit comments