@@ -29,46 +29,44 @@ document.addEventListener("DOMContentLoaded", function () {
2929 showTab ( "version-info" ) ;
3030 } ) ;
3131
32- // Preload version info on page load (optional)
32+ /* ------------------------------------------------------------------
33+ * Pre-load the "Version & Environment Info" partial once per page
34+ * ------------------------------------------------------------------ */
35+ /* Pre-load version-info once */
3336 document . addEventListener ( "DOMContentLoaded" , ( ) => {
3437 const panel = document . getElementById ( "version-info-panel" ) ;
35- if ( panel && panel . innerHTML . trim ( ) === "" ) {
36- const url = `${ window . ROOT_PATH } /version?partial=true` ;
37- fetch ( url )
38- . then ( ( response ) => {
39- if ( ! response . ok ) {
40- throw new Error ( "Network response was not ok" ) ;
41- }
42- return response . text ( ) ;
43- } )
44- . then ( ( html ) => {
45- panel . innerHTML = html ;
46- // Show the version-info panel and activate the tab on page load if hash is #version-info
47- if ( window . location . hash === "#version-info" ) {
48- showTab ( "version-info" ) ;
49- }
50- } )
51- . cconsole . error ( "Failed to preload version info:" , error ) ;
52- atch ( ( error ) => { ;
53- } ) ;
54- }
55- } )
38+ if ( ! panel || panel . innerHTML . trim ( ) !== "" ) return ; // already loaded
5639
57- // HTMX event listeners for debugging
58- document . body . addEventListener ( "htmx:beforeRequest" , ( event ) => {
59- if ( event . detail . elt . id === "tab-version-info" ) {
60- console . log ( "HTMX: Sending request for version info partial" ) ;
61- }
62- ) ;
40+ fetch ( `${ window . ROOT_PATH } /version?partial=true` )
41+ . then ( ( response ) => {
42+ if ( ! response . ok ) throw new Error ( "Network response was not ok" ) ;
43+ return response . text ( ) ;
44+ } )
45+ . then ( ( html ) => {
46+ panel . innerHTML = html ;
47+
48+ // If the page was opened at #version-info, show that tab now
49+ if ( window . location . hash === "#version-info" ) {
50+ showTab ( "version-info" ) ;
51+ }
52+ } )
53+ . catch ( ( error ) => {
54+ console . error ( "Failed to preload version info:" , error ) ;
55+ panel . innerHTML =
56+ "<p class='text-red-600'>Failed to load version info.</p>" ;
57+ } ) ;
58+ } ) ;
6359
60+ /* ------------------------------------------------------------------
61+ * HTMX debug hooks
62+ * ------------------------------------------------------------------ */
6463 document . body . addEventListener ( "htmx:afterSwap" , ( event ) => {
6564 if ( event . detail . target . id === "version-info-panel" ) {
66- console . log ( "HTMX: Content swapped into version-info-panel" console . error ( "Failed to preload version info:" , error ) ;
67- panel . innerHTML = "<p class='text-red-600'>Failed to load version info.</p>" ;
68- } ) ;
65+ console . log ( "HTMX: Content swapped into version-info-panel" ) ;
6966 }
7067 } ) ;
7168
69+
7270 // HTMX event listeners for debugging
7371 document . body . addEventListener ( "htmx:beforeRequest" , ( event ) => {
7472 if ( event . detail . elt . id === "tab-version-info" ) {
@@ -145,8 +143,7 @@ document.addEventListener("DOMContentLoaded", function () {
145143 } else {
146144 basicFields . style . display = "none" ;
147145 bearerFields . style . display = "none" ;
148- heconsole . log ( response ) ;
149- adersFields . style . display = "none" ;
146+ headersFields . style . display = "none" ;
150147 }
151148 } ) ;
152149
@@ -179,9 +176,7 @@ document.addEventListener("DOMContentLoaded", function () {
179176 } ) ;
180177
181178 document
182- . getElementBerroryId ( "a
183- console . error ( "Error:" , error ) ;
184- dd - resource - form ")
179+ . getElementById ( "add-resource-form" )
185180 . addEventListener ( "submit" , ( e ) => {
186181 e . preventDefault ( ) ;
187182 const form = e . target ;
@@ -324,11 +319,12 @@ document.addEventListener("DOMContentLoaded", function () {
324319 "edit-tool-request-type" ,
325320 ) ;
326321
327- const requeM = { - ed mtho , if valid
322+ const requestTypeMap = {
328323 MCP : [ "SSE" , "STDIO" ] ,
329324 REST : [ "GET" , "POST" , "PUT" , "DELETE" ] ,
330325 } ;
331326
327+
332328 // Optionally pass in a pre-selected method
333329 function updateEditToolRequestTypes ( selectedMethod = null ) {
334330 const selectedType = editToolTypeSelect . value ;
@@ -392,8 +388,7 @@ function showTab(tabName) {
392388 . classList . add ( "border-indigo-500" , "text-indigo-600" ) ;
393389 document
394390 . querySelector ( `[href="#${ tabName } "]` )
395- . classconsole . error ( "Failed to load version info:" , error ) ;
396- List . remove ( "border-transparent" , "text-gray-500" ) ;
391+ . classList . remove ( "border-transparent" , "text-gray-500" ) ;
397392
398393 if ( tabName === "metrics" ) {
399394 loadAggregatedMetrics ( ) ;
@@ -491,12 +486,22 @@ function updateSchemaPreview() {
491486 }
492487}
493488
494- // Refresh CodeMirror every time Direct JSON Input is selected
495- Array . from ( schemaModeant ) updateSchemaPreview ( ) ;
496- }
497- } ) ;
489+ /* ---------------------------------------------------------------
490+ * Switch between "UI-builder" and "JSON input" modes
491+ * ------------------------------------------------------------- */
492+ Array . from ( schemaModeRadios ) . forEach ( ( radio ) => {
493+ radio . addEventListener ( "change" , ( ) => {
494+ if ( radio . value === "ui" && radio . checked ) {
495+ uiBuilderDiv . style . display = "block" ;
496+ jsonInputContainer . style . display = "none" ;
497+ } else if ( radio . value === "json" && radio . checked ) {
498+ uiBuilderDiv . style . display = "none" ;
499+ jsonInputContainer . style . display = "block" ;
500+ updateSchemaPreview ( ) ; // keep preview in sync
501+ }
498502 } ) ;
499- }
503+ } ) ; // closes addEventListener callback, forEach callback, and forEach call
504+
500505
501506// On form submission, update CodeMirror with UI builder schema if needed
502507// document.getElementById('add-tool-form').addEventListener('submit', (e) => {
@@ -1694,6 +1699,45 @@ async function runToolTest() {
16941699 } ) ;
16951700}
16961701
1702+ /* ---------------------------------------------------------------
1703+ * Utility: copy a JSON string (or any text) to the system clipboard
1704+ * ------------------------------------------------------------- */
1705+ function copyJsonToClipboard ( sourceId ) {
1706+ // 1. Get the element that holds the JSON (can be a <pre>, <code>, <textarea>, etc.)
1707+ const el = document . getElementById ( sourceId ) ;
1708+ if ( ! el ) {
1709+ console . warn ( `[copyJsonToClipboard] Source element "${ sourceId } " not found.` ) ;
1710+ return ;
1711+ }
1712+
1713+ // 2. Extract the text; fall back to textContent if value is undefined
1714+ const text = "value" in el ? el . value : el . textContent ;
1715+
1716+ // 3. Copy to clipboard
1717+ navigator . clipboard . writeText ( text ) . then (
1718+ ( ) => {
1719+ console . info ( "JSON copied to clipboard ✔️" ) ;
1720+ // Optional: user feedback
1721+ if ( el . dataset . toast !== "off" ) {
1722+ const toast = document . createElement ( "div" ) ;
1723+ toast . textContent = "Copied!" ;
1724+ toast . className =
1725+ "fixed bottom-4 right-4 bg-green-600 text-white px-3 py-1 rounded shadow" ;
1726+ document . body . appendChild ( toast ) ;
1727+ setTimeout ( ( ) => toast . remove ( ) , 1500 ) ;
1728+ }
1729+ } ,
1730+ ( err ) => {
1731+ console . error ( "Clipboard write failed:" , err ) ;
1732+ alert ( "Unable to copy to clipboard - see console for details." ) ;
1733+ }
1734+ ) ;
1735+ }
1736+
1737+ // Make it available to inline onclick handlers
1738+ window . copyJsonToClipboard = copyJsonToClipboard ;
1739+
1740+
16971741// Utility functions to open and close modals
16981742function openModal ( modalId ) {
16991743 document . getElementById ( modalId ) . classList . remove ( "hidden" ) ;
0 commit comments