@@ -29,46 +29,44 @@ document.addEventListener("DOMContentLoaded", function () {
29
29
showTab ( "version-info" ) ;
30
30
} ) ;
31
31
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 */
33
36
document . addEventListener ( "DOMContentLoaded" , ( ) => {
34
37
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
56
39
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
+ } ) ;
63
59
60
+ /* ------------------------------------------------------------------
61
+ * HTMX debug hooks
62
+ * ------------------------------------------------------------------ */
64
63
document . body . addEventListener ( "htmx:afterSwap" , ( event ) => {
65
64
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" ) ;
69
66
}
70
67
} ) ;
71
68
69
+
72
70
// HTMX event listeners for debugging
73
71
document . body . addEventListener ( "htmx:beforeRequest" , ( event ) => {
74
72
if ( event . detail . elt . id === "tab-version-info" ) {
@@ -145,8 +143,7 @@ document.addEventListener("DOMContentLoaded", function () {
145
143
} else {
146
144
basicFields . style . display = "none" ;
147
145
bearerFields . style . display = "none" ;
148
- heconsole . log ( response ) ;
149
- adersFields . style . display = "none" ;
146
+ headersFields . style . display = "none" ;
150
147
}
151
148
} ) ;
152
149
@@ -179,9 +176,7 @@ document.addEventListener("DOMContentLoaded", function () {
179
176
} ) ;
180
177
181
178
document
182
- . getElementBerroryId ( "a
183
- console . error ( "Error:" , error ) ;
184
- dd - resource - form ")
179
+ . getElementById ( "add-resource-form" )
185
180
. addEventListener ( "submit" , ( e ) => {
186
181
e . preventDefault ( ) ;
187
182
const form = e . target ;
@@ -324,11 +319,12 @@ document.addEventListener("DOMContentLoaded", function () {
324
319
"edit-tool-request-type" ,
325
320
) ;
326
321
327
- const requeM = { - ed mtho , if valid
322
+ const requestTypeMap = {
328
323
MCP : [ "SSE" , "STDIO" ] ,
329
324
REST : [ "GET" , "POST" , "PUT" , "DELETE" ] ,
330
325
} ;
331
326
327
+
332
328
// Optionally pass in a pre-selected method
333
329
function updateEditToolRequestTypes ( selectedMethod = null ) {
334
330
const selectedType = editToolTypeSelect . value ;
@@ -392,8 +388,7 @@ function showTab(tabName) {
392
388
. classList . add ( "border-indigo-500" , "text-indigo-600" ) ;
393
389
document
394
390
. 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" ) ;
397
392
398
393
if ( tabName === "metrics" ) {
399
394
loadAggregatedMetrics ( ) ;
@@ -491,12 +486,22 @@ function updateSchemaPreview() {
491
486
}
492
487
}
493
488
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
+ }
498
502
} ) ;
499
- }
503
+ } ) ; // closes addEventListener callback, forEach callback, and forEach call
504
+
500
505
501
506
// On form submission, update CodeMirror with UI builder schema if needed
502
507
// document.getElementById('add-tool-form').addEventListener('submit', (e) => {
@@ -1694,6 +1699,45 @@ async function runToolTest() {
1694
1699
} ) ;
1695
1700
}
1696
1701
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
+
1697
1741
// Utility functions to open and close modals
1698
1742
function openModal ( modalId ) {
1699
1743
document . getElementById ( modalId ) . classList . remove ( "hidden" ) ;
0 commit comments