drf-to-mkdoc 0.2.3__py3-none-any.whl → 0.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of drf-to-mkdoc might be problematic. Click here for more details.

Files changed (33) hide show
  1. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/field-sections-loader.js +29 -0
  2. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/query-parameters-loader.js +16 -0
  3. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/field-extractor.js +200 -0
  4. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/form-manager.js +307 -14
  5. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/main.js +39 -11
  6. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/modal.js +298 -18
  7. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/query-parameters-extractor.js +94 -0
  8. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/request-executor.js +278 -62
  9. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/response-modal.js +173 -0
  10. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/suggestions.js +59 -152
  11. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/tabs.js +52 -9
  12. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/badges.css +13 -5
  13. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/theme-toggle.css +297 -25
  14. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/try-out/fab.css +204 -0
  15. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/try-out/response.css +323 -0
  16. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/try-out/variables.css +139 -0
  17. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/field-sections.css +136 -0
  18. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/try-out/form.css +539 -0
  19. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/try-out/modal.css +239 -17
  20. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/try-out/response.css +503 -43
  21. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/try-out/tabs.css +71 -19
  22. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/try-out/variables.css +71 -15
  23. drf_to_mkdoc/templates/endpoints/detail/request_body.html +2 -0
  24. drf_to_mkdoc/templates/try-out/fab.html +67 -3
  25. drf_to_mkdoc/templates/try-out/form.html +221 -74
  26. drf_to_mkdoc/templates/try-out/modal.html +75 -7
  27. drf_to_mkdoc/templates/try-out/response-modal.html +138 -9
  28. drf_to_mkdoc/utils/endpoint_detail_generator.py +1 -0
  29. {drf_to_mkdoc-0.2.3.dist-info → drf_to_mkdoc-0.2.4.dist-info}/METADATA +68 -9
  30. {drf_to_mkdoc-0.2.3.dist-info → drf_to_mkdoc-0.2.4.dist-info}/RECORD +33 -24
  31. {drf_to_mkdoc-0.2.3.dist-info → drf_to_mkdoc-0.2.4.dist-info}/WHEEL +0 -0
  32. {drf_to_mkdoc-0.2.3.dist-info → drf_to_mkdoc-0.2.4.dist-info}/licenses/LICENSE +0 -0
  33. {drf_to_mkdoc-0.2.3.dist-info → drf_to_mkdoc-0.2.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,29 @@
1
+ // Loader script for field sections functionality
2
+ document.addEventListener('DOMContentLoaded', function() {
3
+ // Load CSS
4
+ function loadCSS(url) {
5
+ const link = document.createElement('link');
6
+ link.rel = 'stylesheet';
7
+ link.href = url;
8
+ document.head.appendChild(link);
9
+ }
10
+
11
+ // Load JavaScript
12
+ function loadScript(url, callback) {
13
+ const script = document.createElement('script');
14
+ script.src = url;
15
+ script.onload = callback || function() {};
16
+ document.body.appendChild(script);
17
+ }
18
+
19
+ // Base URL for static files
20
+ const baseUrl = document.querySelector('meta[name="static-url"]')?.getAttribute('content') || '';
21
+
22
+ // Load CSS file
23
+ loadCSS(baseUrl + '/static/drf-to-mkdoc/stylesheets/field-sections.css');
24
+
25
+ // Load field extractor script
26
+ loadScript(baseUrl + '/static/drf-to-mkdoc/javascripts/try-out/field-extractor.js');
27
+
28
+ console.log('Field sections functionality loaded');
29
+ });
@@ -0,0 +1,16 @@
1
+ // Query parameters loader script
2
+ document.addEventListener('DOMContentLoaded', function() {
3
+ // Load JavaScript
4
+ function loadScript(url, callback) {
5
+ const script = document.createElement('script');
6
+ script.src = url;
7
+ script.onload = callback || function() {};
8
+ document.body.appendChild(script);
9
+ }
10
+
11
+ // Base URL for static files
12
+ const baseUrl = document.querySelector('meta[name="static-url"]')?.getAttribute('content') || '';
13
+
14
+ // Load query parameters extractor script
15
+ loadScript(baseUrl + '/static/drf-to-mkdoc/javascripts/try-out/query-parameters-extractor.js');
16
+ });
@@ -0,0 +1,200 @@
1
+ // Field extractor for documentation content
2
+ document.addEventListener('DOMContentLoaded', function() {
3
+ // Extract filter fields and pagination fields from documentation
4
+ const FieldExtractor = {
5
+ init: function() {
6
+ // Extract fields from documentation
7
+ const fields = this.extractFieldsFromDocumentation();
8
+
9
+ // Make fields available for suggestions
10
+ if (fields && (fields.filter_fields.length > 0 || fields.pagination_fields.length > 0)) {
11
+ window.queryParametersData = window.queryParametersData || {};
12
+
13
+ // Add filter fields
14
+ if (fields.filter_fields.length > 0) {
15
+ window.queryParametersData.filter_fields = fields.filter_fields;
16
+ }
17
+
18
+ // Add pagination fields
19
+ if (fields.pagination_fields.length > 0) {
20
+ window.queryParametersData.pagination_fields = fields.pagination_fields;
21
+ }
22
+
23
+ // Initialize suggestions if TryOutSuggestions is available
24
+ if (window.TryOutSuggestions) {
25
+ window.TryOutSuggestions.init();
26
+ }
27
+ }
28
+ },
29
+
30
+ extractFieldsFromDocumentation: function() {
31
+ const result = {
32
+ filter_fields: [],
33
+ pagination_fields: []
34
+ };
35
+
36
+ // Look for filter fields section
37
+ const filterFieldsHeading = document.querySelector('h3#filter-fields');
38
+ if (filterFieldsHeading) {
39
+ const filterFieldsList = filterFieldsHeading.nextElementSibling;
40
+ if (filterFieldsList && filterFieldsList.tagName === 'UL') {
41
+ const filterFields = Array.from(filterFieldsList.querySelectorAll('li code'))
42
+ .map(code => code.textContent.trim());
43
+
44
+ if (filterFields.length > 0) {
45
+ result.filter_fields = filterFields;
46
+ }
47
+ }
48
+ }
49
+
50
+ // Look for pagination fields section
51
+ const paginationFieldsHeading = document.querySelector('h3#pagination-fields');
52
+ if (paginationFieldsHeading) {
53
+ const paginationFieldsList = paginationFieldsHeading.nextElementSibling;
54
+ if (paginationFieldsList && paginationFieldsList.tagName === 'UL') {
55
+ const paginationFields = Array.from(paginationFieldsList.querySelectorAll('li code'))
56
+ .map(code => code.textContent.trim());
57
+
58
+ if (paginationFields.length > 0) {
59
+ result.pagination_fields = paginationFields;
60
+ }
61
+ }
62
+ }
63
+
64
+ return result;
65
+ },
66
+
67
+ formatDocumentation: function() {
68
+ // Format filter fields section
69
+ this.formatSection('filter-fields', 'Filter Fields');
70
+
71
+ // Format pagination fields section
72
+ this.formatSection('pagination-fields', 'Pagination Fields');
73
+ },
74
+
75
+ formatSection: function(sectionId, title) {
76
+ const heading = document.querySelector(`h3#${sectionId}`);
77
+ if (!heading) return;
78
+
79
+ const list = heading.nextElementSibling;
80
+ if (!list || list.tagName !== 'UL') return;
81
+
82
+ // Create a new container div
83
+ const container = document.createElement('div');
84
+ container.className = 'api-parameters-section';
85
+ container.id = `${sectionId}-container`;
86
+
87
+ // Create a new heading
88
+ const newHeading = document.createElement('h3');
89
+ newHeading.id = sectionId;
90
+ newHeading.innerHTML = heading.innerHTML;
91
+
92
+ // Create a new list container
93
+ const listContainer = document.createElement('div');
94
+ listContainer.className = 'parameters-list';
95
+
96
+ // Create a description paragraph
97
+ const description = document.createElement('p');
98
+ description.className = 'parameters-description';
99
+
100
+ if (sectionId === 'filter-fields') {
101
+ description.textContent = 'These fields can be used to filter the API results. Add them as query parameters to your request.';
102
+ } else if (sectionId === 'pagination-fields') {
103
+ description.textContent = 'These fields control pagination of the API results.';
104
+ }
105
+
106
+ // Process the list items to enhance them
107
+ const enhancedList = this.enhanceParametersList(list);
108
+
109
+ // Move the list into the container
110
+ listContainer.appendChild(enhancedList);
111
+
112
+ // Add elements to the container
113
+ container.appendChild(newHeading);
114
+ container.appendChild(description);
115
+ container.appendChild(listContainer);
116
+
117
+ // Replace the old elements with the new container
118
+ heading.parentNode.insertBefore(container, heading);
119
+ list.parentNode.removeChild(list);
120
+ heading.parentNode.removeChild(heading);
121
+
122
+ // Add try-it buttons
123
+ this.addTryItButtons(container, sectionId);
124
+ },
125
+
126
+ enhanceParametersList: function(list) {
127
+ // Clone the list
128
+ const enhancedList = list.cloneNode(true);
129
+
130
+ // Process each list item
131
+ Array.from(enhancedList.querySelectorAll('li')).forEach(li => {
132
+ const code = li.querySelector('code');
133
+ if (code) {
134
+ // Create a button to try this parameter
135
+ const tryButton = document.createElement('button');
136
+ tryButton.className = 'try-param-btn';
137
+ tryButton.textContent = 'Try it';
138
+ tryButton.dataset.param = code.textContent.trim();
139
+ tryButton.addEventListener('click', (e) => {
140
+ e.preventDefault();
141
+ this.addParameterToTryOut(e.target.dataset.param);
142
+ });
143
+
144
+ li.appendChild(tryButton);
145
+ }
146
+ });
147
+
148
+ return enhancedList;
149
+ },
150
+
151
+ addTryItButtons: function(container, sectionId) {
152
+ // Create a button to try all parameters in this section
153
+ const tryAllButton = document.createElement('button');
154
+ tryAllButton.className = 'try-all-params-btn';
155
+ tryAllButton.textContent = 'Try All Parameters';
156
+
157
+ tryAllButton.addEventListener('click', (e) => {
158
+ e.preventDefault();
159
+
160
+ // Get all parameters in this section
161
+ const params = Array.from(container.querySelectorAll('code'))
162
+ .map(code => code.textContent.trim());
163
+
164
+ // Add all parameters to try-out form
165
+ params.forEach(param => this.addParameterToTryOut(param));
166
+ });
167
+
168
+ // Add the button to the container
169
+ container.appendChild(tryAllButton);
170
+ },
171
+
172
+ addParameterToTryOut: function(paramName) {
173
+ // Find the try-out modal or form
174
+ const tryOutModal = document.getElementById('tryOutModal');
175
+ if (!tryOutModal) return;
176
+
177
+ // Show the modal if it's not already visible
178
+ if (tryOutModal.style.display !== 'flex') {
179
+ if (window.ModalManager && window.ModalManager.openTryOut) {
180
+ window.ModalManager.openTryOut();
181
+ } else {
182
+ tryOutModal.style.display = 'flex';
183
+ }
184
+ }
185
+
186
+ // Add the parameter to the query parameters
187
+ if (window.TryOutSidebar && window.TryOutSidebar.addQueryParam) {
188
+ window.TryOutSidebar.addQueryParam(paramName);
189
+ } else if (window.FormManager && window.FormManager.addQueryParam) {
190
+ window.FormManager.addQueryParam(paramName);
191
+ }
192
+ }
193
+ };
194
+
195
+ // Initialize field extractor
196
+ FieldExtractor.init();
197
+
198
+ // Format documentation sections
199
+ FieldExtractor.formatDocumentation();
200
+ });
@@ -1,33 +1,231 @@
1
1
  // Form management functionality
2
2
  const FormManager = {
3
- addQueryParam: function() {
4
- const container = document.getElementById('queryParams');
3
+ // Initialize form functionality
4
+ init: function() {
5
+ this.setupEventListeners();
6
+ this.setupFormValidation();
7
+ this.initializeRequestBody();
8
+ },
9
+
10
+ initializeRequestBody: function() {
11
+ const requestExample = document.querySelector('.request-example');
12
+ const requestBody = document.getElementById('requestBody');
13
+ let example = null;
14
+ if (requestExample && requestBody) {
15
+ try {
16
+ example = requestExample.getAttribute('data-example');
17
+ if (example) {
18
+ // Remove markdown code block syntax if present
19
+ example = example.replace(/^```json\n/, '').replace(/```$/, '');
20
+ // Remove any leading/trailing whitespace
21
+ example = example.trim();
22
+
23
+ // Try to parse and format the JSON
24
+ const formattedJson = JSON.stringify(JSON.parse(example), null, 2);
25
+ requestBody.value = formattedJson;
26
+
27
+ // Validate the JSON after setting it
28
+ if (window.RequestExecutor) {
29
+ window.RequestExecutor.validateJson();
30
+ }
31
+ }
32
+ } catch (e) {
33
+ console.warn('Failed to parse request example:', e);
34
+ // If parsing fails, try to at least show the raw example
35
+ if (example) {
36
+ requestBody.value = example;
37
+ }
38
+ }
39
+ }
40
+ },
41
+
42
+ setupEventListeners: function() {
43
+ // Form reset functionality
44
+ const resetButtons = document.querySelectorAll('[data-action="reset"], .secondary-btn, .secondary-button');
45
+ resetButtons.forEach(btn => {
46
+ if (btn.textContent.toLowerCase().includes('reset')) {
47
+ btn.addEventListener('click', (e) => {
48
+ e.preventDefault();
49
+ this.resetForm();
50
+ });
51
+ }
52
+ });
53
+
54
+ // Parameter filtering
55
+ const searchInput = document.querySelector('.parameter-search');
56
+ if (searchInput) {
57
+ searchInput.addEventListener('input', this.debounce((e) => {
58
+ this.filterParameters(e.target.value);
59
+ }, 300));
60
+ }
61
+
62
+ // Copy URL functionality
63
+ const copyBtn = document.querySelector('.copy-btn');
64
+ if (copyBtn) {
65
+ copyBtn.addEventListener('click', () => this.copyToClipboard());
66
+ }
67
+
68
+ // JSON validation on input
69
+ const editor = document.getElementById('requestBody');
70
+ if (editor) {
71
+ editor.addEventListener('input', this.debounce(() => {
72
+ if (window.RequestExecutor) {
73
+ window.RequestExecutor.validateJson();
74
+ }
75
+ }, 500));
76
+ }
77
+
78
+ // Format and validate buttons
79
+ const formatBtn = document.querySelector('.format-btn');
80
+ const validateBtn = document.querySelector('.validate-btn');
81
+
82
+ if (formatBtn) {
83
+ formatBtn.addEventListener('click', () => {
84
+ if (window.RequestExecutor) {
85
+ window.RequestExecutor.formatJson();
86
+ }
87
+ });
88
+ }
89
+ if (validateBtn) {
90
+ validateBtn.addEventListener('click', () => {
91
+ if (window.RequestExecutor) {
92
+ window.RequestExecutor.validateJson();
93
+ }
94
+ });
95
+ }
96
+ },
97
+
98
+ setupFormValidation: function() {
99
+ // Add validation to required inputs
100
+ const requiredInputs = document.querySelectorAll('input[required]');
101
+ requiredInputs.forEach(input => {
102
+ input.addEventListener('blur', () => {
103
+ if (window.RequestExecutor) {
104
+ window.RequestExecutor.validateInput(input);
105
+ }
106
+ });
107
+ input.addEventListener('input', () => this.clearValidationError(input));
108
+ });
109
+ },
110
+
111
+ clearValidationError: function(input) {
112
+ input.classList.remove('error');
113
+ const validationMessage = input.parentElement.querySelector('.validation-message');
114
+ if (validationMessage) {
115
+ validationMessage.textContent = '';
116
+ validationMessage.style.display = 'none';
117
+ }
118
+ },
119
+
120
+ // Debounce utility function
121
+ debounce: function(func, wait) {
122
+ let timeout;
123
+ return function executedFunction(...args) {
124
+ const later = () => {
125
+ clearTimeout(timeout);
126
+ func(...args);
127
+ };
128
+ clearTimeout(timeout);
129
+ timeout = setTimeout(later, wait);
130
+ };
131
+ },
132
+ addQueryParam: function(paramName) {
133
+ const container = document.querySelector('#queryParams .parameter-list');
5
134
  if (!container) return;
6
135
 
7
- const kvItem = this.createKvItem('Parameter name', 'Parameter value', true);
8
- container.appendChild(kvItem);
136
+ const paramItem = this.createParameterItem();
137
+ container.appendChild(paramItem);
9
138
 
10
- // Focus on the first input
11
- const firstInput = kvItem.querySelector('input');
12
- if (firstInput) {
13
- firstInput.focus();
139
+ // If a parameter name was provided, set it
140
+ const nameInput = paramItem.querySelector('.name-input');
141
+ if (nameInput && paramName) {
142
+ nameInput.value = paramName;
143
+
144
+ // Focus on the value input instead
145
+ const valueInput = paramItem.querySelector('.value-input');
146
+ if (valueInput) {
147
+ valueInput.focus();
148
+ }
149
+ } else if (nameInput) {
150
+ // Otherwise focus on the name input
151
+ nameInput.focus();
152
+ }
153
+
154
+ // Setup suggestions for new input if available
155
+ if (window.TryOutSuggestions) {
156
+ setTimeout(() => {
157
+ window.TryOutSuggestions.setupExistingInputs();
158
+ }, 10);
14
159
  }
160
+
161
+ return paramItem;
162
+ },
163
+
164
+ createParameterItem: function() {
165
+ const paramItem = document.createElement('div');
166
+ paramItem.className = 'parameter-item';
167
+
168
+ paramItem.innerHTML = `
169
+ <div class="parameter-inputs">
170
+ <input type="text"
171
+ class="modern-input name-input"
172
+ placeholder="Parameter name"
173
+ list="paramSuggestions">
174
+ <input type="text"
175
+ class="modern-input value-input"
176
+ placeholder="Value">
177
+ <button class="remove-btn"
178
+ onclick="FormManager.removeKvItem(this)"
179
+ aria-label="Remove parameter">
180
+ <span class="icon">✕</span>
181
+ </button>
182
+ </div>
183
+ `;
184
+
185
+ return paramItem;
15
186
  },
16
187
 
17
188
  addHeader: function() {
18
- const container = document.getElementById('requestHeaders');
189
+ const container = document.querySelector('#requestHeaders .header-list');
19
190
  if (!container) return;
20
191
 
21
- const kvItem = this.createKvItem('Header name', 'Header value', true);
22
- container.appendChild(kvItem);
192
+ const headerItem = this.createHeaderItem();
193
+ container.appendChild(headerItem);
23
194
 
24
195
  // Focus on the first input
25
- const firstInput = kvItem.querySelector('input');
196
+ const firstInput = headerItem.querySelector('.name-input');
26
197
  if (firstInput) {
27
198
  firstInput.focus();
28
199
  }
29
200
  },
30
201
 
202
+ createHeaderItem: function() {
203
+ const headerItem = document.createElement('div');
204
+ headerItem.className = 'header-item';
205
+
206
+ headerItem.innerHTML = `
207
+ <div class="header-inputs">
208
+ <input type="text"
209
+ class="modern-input name-input"
210
+ placeholder="Header name"
211
+ list="headerSuggestions">
212
+ <input type="text"
213
+ class="modern-input value-input"
214
+ placeholder="Header value">
215
+ <button class="remove-btn"
216
+ aria-label="Remove header">
217
+ <span class="icon">✕</span>
218
+ </button>
219
+ </div>
220
+ `;
221
+
222
+ // Attach the removal handler programmatically
223
+ const removeBtn = headerItem.querySelector('.remove-btn');
224
+ removeBtn.addEventListener('click', (e) => FormManager.removeKvItem(e.currentTarget));
225
+
226
+ return headerItem;
227
+ },
228
+
31
229
  createKvItem: function(namePlaceholder, valuePlaceholder, removable = true) {
32
230
  const kvItem = document.createElement('div');
33
231
  kvItem.className = 'kv-item';
@@ -55,8 +253,8 @@ const FormManager = {
55
253
  },
56
254
 
57
255
  removeKvItem: function(button) {
58
- if (button && button.parentElement) {
59
- button.parentElement.remove();
256
+ if (button && button.closest('.parameter-item, .header-item')) {
257
+ button.closest('.parameter-item, .header-item').remove();
60
258
  }
61
259
  },
62
260
 
@@ -165,8 +363,103 @@ const FormManager = {
165
363
  }
166
364
  }
167
365
  return null;
366
+ },
367
+
368
+ // Form reset functionality
369
+ resetForm: function() {
370
+ const form = document.querySelector('.try-out-form');
371
+ if (form) {
372
+ // Reset text inputs except base URL
373
+ form.querySelectorAll('input[type="text"], textarea').forEach(input => {
374
+ if (!input.id || input.id !== 'baseUrl') {
375
+ input.value = '';
376
+ }
377
+ });
378
+
379
+ // Reset validation states
380
+ form.querySelectorAll('.error').forEach(el => {
381
+ el.classList.remove('error');
382
+ });
383
+
384
+ form.querySelectorAll('.validation-message').forEach(msg => {
385
+ msg.textContent = '';
386
+ msg.style.display = 'none';
387
+ });
388
+
389
+ // Reset JSON editor
390
+ const editor = document.getElementById('requestBody');
391
+ if (editor) {
392
+ editor.value = '';
393
+ }
394
+
395
+ // Reset validation status
396
+ const status = document.querySelector('.validation-status');
397
+ if (status) {
398
+ status.textContent = '';
399
+ status.className = 'validation-status';
400
+ }
401
+
402
+ // Reset to first tab
403
+ const firstTab = document.querySelector('.tab');
404
+ if (firstTab && window.TabManager) {
405
+ window.TabManager.switchTab(firstTab);
406
+ }
407
+
408
+ // Clear any error messages
409
+ if (window.RequestExecutor) {
410
+ window.RequestExecutor.clearValidationErrors();
411
+ }
412
+ }
413
+ },
414
+
415
+ // Parameter filtering
416
+ filterParameters: function(query) {
417
+ const items = document.querySelectorAll('.parameter-item');
418
+ query = query.toLowerCase();
419
+
420
+ items.forEach(item => {
421
+ const nameInput = item.querySelector('.name-input');
422
+ const name = nameInput?.value.toLowerCase() || '';
423
+
424
+ if (name.includes(query) || query === '') {
425
+ item.style.display = '';
426
+ } else {
427
+ item.style.display = 'none';
428
+ }
429
+ });
430
+ },
431
+
432
+ // Copy URL to clipboard
433
+ copyToClipboard: function() {
434
+ const baseUrl = document.getElementById('baseUrl')?.value || '';
435
+ const pathDisplay = document.querySelector('.path-display')?.textContent || '';
436
+ const url = baseUrl + pathDisplay;
437
+
438
+ navigator.clipboard.writeText(url).then(() => {
439
+ // Show copy success in the URL preview
440
+ const copyBtn = document.querySelector('.copy-btn');
441
+ if (copyBtn) {
442
+ const originalText = copyBtn.innerHTML;
443
+ copyBtn.innerHTML = '<span class="icon">✓</span>';
444
+ setTimeout(() => {
445
+ copyBtn.innerHTML = originalText;
446
+ }, 2000);
447
+ }
448
+ }).catch(() => {
449
+ console.error('Failed to copy URL');
450
+ });
168
451
  }
169
452
  };
170
453
 
454
+ // Initialize when DOM is loaded
455
+ document.addEventListener('DOMContentLoaded', function() {
456
+ FormManager.init();
457
+ });
458
+
459
+ // Global functions for backward compatibility
460
+ window.resetForm = () => FormManager.resetForm();
461
+ window.filterParameters = (query) => FormManager.filterParameters(query);
462
+ window.copyToClipboard = () => FormManager.copyToClipboard();
463
+
171
464
  // Export for global access
172
465
  window.FormManager = FormManager;
@@ -1,22 +1,50 @@
1
1
  // Main try-out functionality - combines all components
2
2
  document.addEventListener('DOMContentLoaded', function() {
3
- // Initialize tabs
4
- TabManager.init();
3
+ // Initialize all components
4
+ if (window.TabManager) {
5
+ TabManager.init();
6
+ }
7
+
8
+ if (window.FormManager) {
9
+ FormManager.init();
10
+ }
5
11
 
6
- // Initialize suggestions if available
7
12
  if (window.TryOutSuggestions) {
8
13
  TryOutSuggestions.init();
9
14
  }
15
+
16
+ // Initialize modal functionality
17
+ if (window.ModalManager) {
18
+ // Modal is already initialized through its own file
19
+ console.log('Try-out modal functionality loaded');
20
+ }
21
+
22
+ // Initialize request executor
23
+ if (window.RequestExecutor) {
24
+ console.log('Try-out request executor loaded');
25
+ }
26
+
27
+ console.log('Try-out functionality fully initialized');
10
28
  });
11
29
 
12
30
  // Legacy compatibility - maintain old interface
13
31
  window.TryOutSidebar = {
14
- openTryOut: () => ModalManager.openTryOut(),
15
- closeTryOut: () => ModalManager.closeTryOut(),
16
- closeResponseModal: () => ModalManager.closeResponseModal(),
17
- showResponseModal: (status, responseText, responseTime) => ModalManager.showResponseModal(status, responseText, responseTime),
18
- addQueryParam: () => FormManager.addQueryParam(),
19
- addHeader: () => FormManager.addHeader(),
20
- removeKvItem: (button) => FormManager.removeKvItem(button),
21
- validateRequiredParams: () => FormManager.validateRequiredParams()
32
+ openTryOut: () => window.ModalManager?.openTryOut(),
33
+ closeTryOut: () => window.ModalManager?.closeTryOut(),
34
+ closeResponseModal: () => window.ModalManager?.closeResponseModal(),
35
+ showResponseModal: (status, responseText, responseTime) => window.ModalManager?.showResponseModal(status, responseText, responseTime),
36
+ addQueryParam: () => window.FormManager?.addQueryParam(),
37
+ addHeader: () => window.FormManager?.addHeader(),
38
+ removeKvItem: (button) => window.FormManager?.removeKvItem(button),
39
+ validateRequiredParams: () => window.FormManager?.validateRequiredParams()
22
40
  };
41
+
42
+ // Additional global functions for HTML onclick handlers
43
+ window.TryOutForm = {
44
+ resetForm: () => window.FormManager?.resetForm(),
45
+ sendRequest: () => window.RequestExecutor?.executeRequest()
46
+ };
47
+
48
+ // Global proxy functions for template onclick handlers
49
+ window.resetForm = () => window.TryOutForm?.resetForm?.();
50
+ window.executeRequest = () => window.TryOutForm?.sendRequest?.();