@keenthemes/ktui 1.0.27 → 1.0.29
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.
- package/dist/ktui.js +13 -1
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +5 -0
- package/lib/cjs/components/datatable/datatable.js +13 -1
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +13 -1
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/package.json +23 -5
- package/src/components/datatable/datatable.ts +13 -3
- package/src/components/table/table.css +7 -0
- package/CONTRIBUTING.md +0 -88
- package/examples/datatable/checkbox-events-test.html +0 -400
- package/examples/datatable/credentials-test.html +0 -423
- package/examples/datatable/remote-checkbox-test.html +0 -365
- package/examples/datatable/sorting-test.html +0 -258
- package/examples/image-input/file-upload-example.html +0 -189
- package/examples/modal/persistent.html +0 -205
- package/examples/modal/remote-select-dropdown.html +0 -166
- package/examples/modal/select-dropdown-container.html +0 -129
- package/examples/select/avatar.html +0 -47
- package/examples/select/basic-usage.html +0 -39
- package/examples/select/country.html +0 -43
- package/examples/select/dark-mode.html +0 -93
- package/examples/select/description.html +0 -53
- package/examples/select/disable-option.html +0 -37
- package/examples/select/disable-select.html +0 -35
- package/examples/select/dropdowncontainer.html +0 -111
- package/examples/select/dynamic-methods.html +0 -273
- package/examples/select/formdata-remote.html +0 -161
- package/examples/select/global-config.html +0 -81
- package/examples/select/icon-multiple.html +0 -50
- package/examples/select/icon.html +0 -48
- package/examples/select/max-selection.html +0 -38
- package/examples/select/modal-container.html +0 -128
- package/examples/select/modal-positioning-test.html +0 -338
- package/examples/select/modal.html +0 -80
- package/examples/select/multiple.html +0 -40
- package/examples/select/native-selected.html +0 -64
- package/examples/select/placeholder.html +0 -40
- package/examples/select/remote-data-preselected.html +0 -283
- package/examples/select/remote-data.html +0 -38
- package/examples/select/search.html +0 -57
- package/examples/select/sizes.html +0 -94
- package/examples/select/tags-enhanced.html +0 -86
- package/examples/select/tags-icons.html +0 -57
- package/examples/select/template-customization.html +0 -61
- package/examples/sticky/README.md +0 -158
- package/examples/sticky/debug-sticky.html +0 -144
- package/examples/sticky/test-runner.html +0 -175
- package/examples/sticky/test-sticky-logic.js +0 -369
- package/examples/sticky/test-sticky-positioning.html +0 -386
- package/examples/toast/example.html +0 -479
- package/prettier.config.js +0 -9
- package/tsconfig.json +0 -17
- package/webpack.config.js +0 -118
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>DataTable Request Credentials Test</title>
|
|
8
|
-
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
-
</head>
|
|
10
|
-
|
|
11
|
-
<body class="bg-gray-50 min-h-screen p-4">
|
|
12
|
-
<div class="container mx-auto max-w-6xl">
|
|
13
|
-
<!-- Header -->
|
|
14
|
-
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
15
|
-
<h1 class="text-2xl font-bold text-gray-900 mb-2">DataTable Request Credentials Test</h1>
|
|
16
|
-
<p class="text-sm text-gray-600 mb-4">
|
|
17
|
-
Test the <code class="bg-gray-100 px-1 rounded">requestCredentials</code> option for controlling cookie and credential inclusion in fetch requests.
|
|
18
|
-
</p>
|
|
19
|
-
|
|
20
|
-
<!-- Instructions -->
|
|
21
|
-
<div class="bg-gray-50 border border-gray-200 rounded-md p-4 mb-4">
|
|
22
|
-
<h2 class="text-sm font-semibold text-gray-900 mb-2">Testing Instructions</h2>
|
|
23
|
-
<ol class="text-sm text-gray-700 list-decimal list-inside space-y-1.5">
|
|
24
|
-
<li>Open Browser DevTools (F12) → Network tab</li>
|
|
25
|
-
<li>Select a credential mode above and click "Reload"</li>
|
|
26
|
-
<li>Inspect the request → Headers → Request Headers</li>
|
|
27
|
-
<li>Check the <code class="bg-white px-1.5 py-0.5 rounded border border-gray-300 text-xs font-mono">Cookie</code> header to verify credentials</li>
|
|
28
|
-
<li>For cross-origin: Check <code class="bg-white px-1.5 py-0.5 rounded border border-gray-300 text-xs font-mono">Access-Control-Allow-Credentials</code> in Response Headers</li>
|
|
29
|
-
</ol>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
<!-- Credential Mode Selector -->
|
|
33
|
-
<div class="mb-6">
|
|
34
|
-
<label class="block text-sm font-medium text-gray-700 mb-3">
|
|
35
|
-
Credential Mode:
|
|
36
|
-
</label>
|
|
37
|
-
<div class="flex gap-2 flex-wrap items-center">
|
|
38
|
-
<button
|
|
39
|
-
onclick="changeCredentialsMode('omit')"
|
|
40
|
-
data-mode="omit"
|
|
41
|
-
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
42
|
-
Omit
|
|
43
|
-
</button>
|
|
44
|
-
<button
|
|
45
|
-
onclick="changeCredentialsMode('same-origin')"
|
|
46
|
-
data-mode="same-origin"
|
|
47
|
-
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
48
|
-
Same-Origin
|
|
49
|
-
</button>
|
|
50
|
-
<button
|
|
51
|
-
onclick="changeCredentialsMode('include')"
|
|
52
|
-
data-mode="include"
|
|
53
|
-
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
54
|
-
Include
|
|
55
|
-
</button>
|
|
56
|
-
<span class="text-gray-400 mx-2">|</span>
|
|
57
|
-
<button
|
|
58
|
-
onclick="reloadDataTable()"
|
|
59
|
-
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
60
|
-
Reload
|
|
61
|
-
</button>
|
|
62
|
-
</div>
|
|
63
|
-
<div class="mt-3 flex items-center gap-2">
|
|
64
|
-
<span class="text-sm text-gray-500">Active:</span>
|
|
65
|
-
<code id="currentMode" class="bg-gray-100 px-2 py-1 rounded text-xs font-mono text-gray-800 border border-gray-200">same-origin</code>
|
|
66
|
-
</div>
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<!-- Current Configuration Display -->
|
|
70
|
-
<div class="bg-gray-50 border border-gray-200 rounded-md p-4 mb-4">
|
|
71
|
-
<h3 class="text-sm font-semibold text-gray-800 mb-2">Current Configuration:</h3>
|
|
72
|
-
<pre id="configDisplay" class="text-xs bg-white p-3 rounded border border-gray-300 overflow-x-auto"><code>{
|
|
73
|
-
"apiEndpoint": "https://jsonplaceholder.typicode.com/users",
|
|
74
|
-
"requestMethod": "GET",
|
|
75
|
-
"requestCredentials": "same-origin"
|
|
76
|
-
}</code></pre>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<!-- DataTable Container -->
|
|
81
|
-
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
82
|
-
<div class="kt-card">
|
|
83
|
-
<div class="kt-card-table" id="credentials-datatable-container">
|
|
84
|
-
<div class="kt-table-wrapper kt-scrollable">
|
|
85
|
-
<table id="credentials-table" class="kt-table" data-kt-datatable-table="true">
|
|
86
|
-
<thead>
|
|
87
|
-
<tr>
|
|
88
|
-
<th scope="col" class="w-20" data-kt-datatable-column="id">
|
|
89
|
-
<span class="kt-table-col">
|
|
90
|
-
<span class="kt-table-col-label">ID</span>
|
|
91
|
-
<span class="kt-table-col-sort"></span>
|
|
92
|
-
</span>
|
|
93
|
-
</th>
|
|
94
|
-
<th scope="col" class="w-48" data-kt-datatable-column="name">
|
|
95
|
-
<span class="kt-table-col">
|
|
96
|
-
<span class="kt-table-col-label">Name</span>
|
|
97
|
-
<span class="kt-table-col-sort"></span>
|
|
98
|
-
</span>
|
|
99
|
-
</th>
|
|
100
|
-
<th scope="col" class="w-64" data-kt-datatable-column="email">
|
|
101
|
-
<span class="kt-table-col">
|
|
102
|
-
<span class="kt-table-col-label">Email</span>
|
|
103
|
-
<span class="kt-table-col-sort"></span>
|
|
104
|
-
</span>
|
|
105
|
-
</th>
|
|
106
|
-
<th scope="col" class="w-48" data-kt-datatable-column="username">
|
|
107
|
-
<span class="kt-table-col">
|
|
108
|
-
<span class="kt-table-col-label">Username</span>
|
|
109
|
-
<span class="kt-table-col-sort"></span>
|
|
110
|
-
</span>
|
|
111
|
-
</th>
|
|
112
|
-
<th scope="col" class="w-64" data-kt-datatable-column="phone">
|
|
113
|
-
<span class="kt-table-col">
|
|
114
|
-
<span class="kt-table-col-label">Phone</span>
|
|
115
|
-
<span class="kt-table-col-sort"></span>
|
|
116
|
-
</span>
|
|
117
|
-
</th>
|
|
118
|
-
</tr>
|
|
119
|
-
</thead>
|
|
120
|
-
<tbody>
|
|
121
|
-
<!-- Data will be loaded from API -->
|
|
122
|
-
</tbody>
|
|
123
|
-
</table>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<!-- Pagination Info -->
|
|
127
|
-
<div class="flex items-center justify-between mt-4">
|
|
128
|
-
<div class="flex items-center space-x-2">
|
|
129
|
-
<span class="text-sm text-gray-700">Show</span>
|
|
130
|
-
<select data-kt-datatable-size="true" class="border border-gray-300 rounded px-2 py-1 bg-white text-gray-900">
|
|
131
|
-
<option value="5" selected>5</option>
|
|
132
|
-
<option value="10">10</option>
|
|
133
|
-
<option value="20">20</option>
|
|
134
|
-
</select>
|
|
135
|
-
<span class="text-sm text-gray-700">entries</span>
|
|
136
|
-
</div>
|
|
137
|
-
<div data-kt-datatable-info="true" class="text-sm text-gray-700"></div>
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
<!-- Pagination Controls -->
|
|
141
|
-
<div class="flex justify-center mt-4">
|
|
142
|
-
<div data-kt-datatable-pagination="true" class="flex space-x-1"></div>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
</div>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<!-- Network Request Monitor -->
|
|
149
|
-
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
150
|
-
<div class="flex items-center justify-between mb-3">
|
|
151
|
-
<h2 class="text-lg font-semibold text-gray-800">Network Request Monitor</h2>
|
|
152
|
-
<button
|
|
153
|
-
onclick="clearRequestLog()"
|
|
154
|
-
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
155
|
-
Clear
|
|
156
|
-
</button>
|
|
157
|
-
</div>
|
|
158
|
-
<div class="bg-gray-50 border border-gray-200 rounded-md p-4 mb-4">
|
|
159
|
-
<p class="text-sm text-gray-600 mb-2">
|
|
160
|
-
<strong>Note:</strong> This log shows fetch events. For detailed request headers including cookies, check Browser DevTools → Network tab.
|
|
161
|
-
</p>
|
|
162
|
-
</div>
|
|
163
|
-
<div id="requestLog" class="bg-gray-50 border border-gray-200 rounded-md p-4 h-64 overflow-y-auto font-mono text-sm">
|
|
164
|
-
<div class="text-gray-500">No requests yet. Reload the DataTable to see fetch events...</div>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
|
|
168
|
-
<!-- Testing Guide -->
|
|
169
|
-
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
170
|
-
<h2 class="text-lg font-semibold text-gray-800 mb-4">Testing Guide</h2>
|
|
171
|
-
|
|
172
|
-
<div class="space-y-4">
|
|
173
|
-
<div>
|
|
174
|
-
<h3 class="text-sm font-semibold text-gray-700 mb-2">1. Testing with Browser DevTools</h3>
|
|
175
|
-
<ol class="text-sm text-gray-600 list-decimal list-inside space-y-1 ml-2">
|
|
176
|
-
<li>Open DevTools (F12 or Right-click → Inspect)</li>
|
|
177
|
-
<li>Go to the <strong>Network</strong> tab</li>
|
|
178
|
-
<li>Select a credential mode and reload the DataTable</li>
|
|
179
|
-
<li>Click on the request to <code>jsonplaceholder.typicode.com</code></li>
|
|
180
|
-
<li>Check the <strong>Headers</strong> tab:
|
|
181
|
-
<ul class="list-disc list-inside ml-4 mt-1">
|
|
182
|
-
<li><strong>Request Headers:</strong> Look for <code>Cookie</code> header (should appear with 'include' mode)</li>
|
|
183
|
-
<li><strong>Response Headers:</strong> Check for <code>Access-Control-Allow-Credentials</code> (for cross-origin)</li>
|
|
184
|
-
</ul>
|
|
185
|
-
</li>
|
|
186
|
-
</ol>
|
|
187
|
-
</div>
|
|
188
|
-
|
|
189
|
-
<div>
|
|
190
|
-
<h3 class="text-sm font-semibold text-gray-700 mb-2">2. Credential Modes Explained</h3>
|
|
191
|
-
<ul class="text-sm text-gray-600 space-y-2">
|
|
192
|
-
<li>
|
|
193
|
-
<strong class="text-gray-800">omit:</strong> Never sends cookies or credentials, even for same-origin requests.
|
|
194
|
-
Useful for APIs that don't require authentication.
|
|
195
|
-
</li>
|
|
196
|
-
<li>
|
|
197
|
-
<strong class="text-gray-800">same-origin:</strong> Sends credentials only when the API endpoint is on the same origin
|
|
198
|
-
as the page. This is the browser default behavior.
|
|
199
|
-
</li>
|
|
200
|
-
<li>
|
|
201
|
-
<strong class="text-gray-800">include:</strong> Always sends credentials, including cookies, for both same-origin and
|
|
202
|
-
cross-origin requests. Requires proper CORS configuration on the server.
|
|
203
|
-
</li>
|
|
204
|
-
</ul>
|
|
205
|
-
</div>
|
|
206
|
-
|
|
207
|
-
<div>
|
|
208
|
-
<h3 class="text-sm font-semibold text-gray-700 mb-2">3. Testing with Real Session Cookies</h3>
|
|
209
|
-
<p class="text-sm text-gray-600 mb-2">
|
|
210
|
-
To test with actual session cookies:
|
|
211
|
-
</p>
|
|
212
|
-
<ol class="text-sm text-gray-600 list-decimal list-inside space-y-1 ml-2">
|
|
213
|
-
<li>Set up a local API server or use a test endpoint that accepts cookies</li>
|
|
214
|
-
<li>Set a cookie via JavaScript: <code class="bg-gray-100 px-1 rounded">document.cookie = "session=test123; path=/"</code></li>
|
|
215
|
-
<li>Change the <code class="bg-gray-100 px-1 rounded">apiEndpoint</code> to your test endpoint</li>
|
|
216
|
-
<li>Select <code class="bg-gray-100 px-1 rounded">include</code> mode and reload</li>
|
|
217
|
-
<li>Verify the cookie appears in the request headers in DevTools</li>
|
|
218
|
-
</ol>
|
|
219
|
-
</div>
|
|
220
|
-
|
|
221
|
-
<div>
|
|
222
|
-
<h3 class="text-sm font-semibold text-gray-700 mb-2">4. Expected Behavior</h3>
|
|
223
|
-
<ul class="text-sm text-gray-600 space-y-1">
|
|
224
|
-
<li>✓ <strong>omit:</strong> No <code>Cookie</code> header in request</li>
|
|
225
|
-
<li>✓ <strong>same-origin:</strong> <code>Cookie</code> header only if API is same origin</li>
|
|
226
|
-
<li>✓ <strong>include:</strong> <code>Cookie</code> header always present (if cookies exist)</li>
|
|
227
|
-
<li>✓ Backward compatibility: Works without <code>requestCredentials</code> (uses browser default)</li>
|
|
228
|
-
</ul>
|
|
229
|
-
</div>
|
|
230
|
-
</div>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
|
|
234
|
-
<script src="../../dist/ktui.js"></script>
|
|
235
|
-
<script>
|
|
236
|
-
let datatableInstance = null;
|
|
237
|
-
let currentCredentialsMode = 'same-origin';
|
|
238
|
-
|
|
239
|
-
// Update configuration display
|
|
240
|
-
function updateConfigDisplay() {
|
|
241
|
-
const config = {
|
|
242
|
-
apiEndpoint: 'https://jsonplaceholder.typicode.com/users',
|
|
243
|
-
requestMethod: 'GET',
|
|
244
|
-
requestCredentials: currentCredentialsMode
|
|
245
|
-
};
|
|
246
|
-
document.getElementById('configDisplay').textContent = JSON.stringify(config, null, 2);
|
|
247
|
-
document.getElementById('currentMode').textContent = currentCredentialsMode;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Change credentials mode
|
|
251
|
-
function changeCredentialsMode(mode) {
|
|
252
|
-
currentCredentialsMode = mode;
|
|
253
|
-
updateConfigDisplay();
|
|
254
|
-
|
|
255
|
-
// Update button active state - keep dark style but adjust opacity
|
|
256
|
-
document.querySelectorAll('[data-mode]').forEach(btn => {
|
|
257
|
-
if (btn.getAttribute('data-mode') === mode) {
|
|
258
|
-
btn.classList.remove('opacity-75');
|
|
259
|
-
btn.classList.add('opacity-100', 'ring-2', 'ring-gray-400');
|
|
260
|
-
} else {
|
|
261
|
-
btn.classList.remove('opacity-100', 'ring-2', 'ring-gray-400');
|
|
262
|
-
btn.classList.add('opacity-75');
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
addRequestLog('info', `Credential mode changed to: ${mode}`);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Reload DataTable with current configuration
|
|
270
|
-
function reloadDataTable() {
|
|
271
|
-
if (datatableInstance && typeof datatableInstance.reload === 'function') {
|
|
272
|
-
addRequestLog('fetch', 'Reloading DataTable...');
|
|
273
|
-
datatableInstance.reload();
|
|
274
|
-
} else {
|
|
275
|
-
addRequestLog('error', 'DataTable instance not found');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Initialize DataTable
|
|
280
|
-
function initDataTable() {
|
|
281
|
-
const container = document.getElementById('credentials-datatable-container');
|
|
282
|
-
if (!container) {
|
|
283
|
-
console.error('Container not found');
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Force clean slate - remove all data attributes and instance
|
|
288
|
-
container.removeAttribute('data-kt-datatable');
|
|
289
|
-
if (container.instance) {
|
|
290
|
-
delete container.instance;
|
|
291
|
-
}
|
|
292
|
-
datatableInstance = null;
|
|
293
|
-
|
|
294
|
-
try {
|
|
295
|
-
// Add cache-busting parameter to ensure fresh requests
|
|
296
|
-
const cacheBuster = Date.now();
|
|
297
|
-
|
|
298
|
-
datatableInstance = new KTDataTable(container, {
|
|
299
|
-
apiEndpoint: `https://jsonplaceholder.typicode.com/users?_=${cacheBuster}`,
|
|
300
|
-
requestMethod: 'GET',
|
|
301
|
-
requestHeaders: {
|
|
302
|
-
'Content-Type': 'application/json',
|
|
303
|
-
'Accept': 'application/json',
|
|
304
|
-
'Cache-Control': 'no-cache'
|
|
305
|
-
},
|
|
306
|
-
requestCredentials: currentCredentialsMode,
|
|
307
|
-
stateSave: false, // Disable state saving to force fresh fetches
|
|
308
|
-
pageSize: 5,
|
|
309
|
-
columns: {
|
|
310
|
-
id: {
|
|
311
|
-
title: 'ID'
|
|
312
|
-
},
|
|
313
|
-
name: {
|
|
314
|
-
title: 'Name'
|
|
315
|
-
},
|
|
316
|
-
email: {
|
|
317
|
-
title: 'Email'
|
|
318
|
-
},
|
|
319
|
-
username: {
|
|
320
|
-
title: 'Username'
|
|
321
|
-
},
|
|
322
|
-
phone: {
|
|
323
|
-
title: 'Phone'
|
|
324
|
-
}
|
|
325
|
-
},
|
|
326
|
-
mapResponse: function(response) {
|
|
327
|
-
if (Array.isArray(response)) {
|
|
328
|
-
return {
|
|
329
|
-
data: response,
|
|
330
|
-
totalCount: response.length
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
return {
|
|
334
|
-
data: response.data || [],
|
|
335
|
-
totalCount: response.totalCount || 0
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Listen to fetch events
|
|
341
|
-
container.addEventListener('kt.datatable.fetch', function() {
|
|
342
|
-
addRequestLog('fetch', `Fetching data with credentials: ${currentCredentialsMode}`);
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
container.addEventListener('kt.datatable.fetched', function(event) {
|
|
346
|
-
addRequestLog('fetched', 'Data fetched successfully');
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
container.addEventListener('kt.datatable.error', function(event) {
|
|
350
|
-
addRequestLog('error', `Error: ${event.detail?.error?.message || 'Unknown error'}`);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
addRequestLog('info', `DataTable initialized with credentials mode: ${currentCredentialsMode}`);
|
|
354
|
-
updateConfigDisplay();
|
|
355
|
-
} catch (error) {
|
|
356
|
-
console.error('Error initializing DataTable:', error);
|
|
357
|
-
addRequestLog('error', `Initialization error: ${error.message}`);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// Request log helper
|
|
362
|
-
function addRequestLog(type, message) {
|
|
363
|
-
const logElement = document.getElementById('requestLog');
|
|
364
|
-
const timestamp = new Date().toLocaleTimeString();
|
|
365
|
-
const logEntry = document.createElement('div');
|
|
366
|
-
logEntry.className = 'mb-2 pb-2 border-b border-gray-200';
|
|
367
|
-
|
|
368
|
-
let typeColor = 'text-gray-700';
|
|
369
|
-
let typeBg = 'bg-gray-50';
|
|
370
|
-
if (type === 'fetch') {
|
|
371
|
-
typeColor = 'text-gray-800';
|
|
372
|
-
typeBg = 'bg-gray-100';
|
|
373
|
-
} else if (type === 'fetched') {
|
|
374
|
-
typeColor = 'text-gray-700';
|
|
375
|
-
typeBg = 'bg-gray-50';
|
|
376
|
-
} else if (type === 'error') {
|
|
377
|
-
typeColor = 'text-red-700';
|
|
378
|
-
typeBg = 'bg-red-50';
|
|
379
|
-
} else if (type === 'info') {
|
|
380
|
-
typeColor = 'text-gray-600';
|
|
381
|
-
typeBg = 'bg-gray-50';
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
logEntry.innerHTML = `
|
|
385
|
-
<div class="flex items-start gap-2">
|
|
386
|
-
<span class="text-gray-400 text-xs font-mono">[${timestamp}]</span>
|
|
387
|
-
<span class="font-medium ${typeColor} text-xs px-1.5 py-0.5 rounded ${typeBg}">${type.toUpperCase()}</span>
|
|
388
|
-
<span class="text-gray-700 text-sm">${message}</span>
|
|
389
|
-
</div>
|
|
390
|
-
`;
|
|
391
|
-
|
|
392
|
-
// Remove "No requests yet" message if it exists
|
|
393
|
-
const firstChild = logElement.firstChild;
|
|
394
|
-
if (firstChild && firstChild.textContent.includes('No requests yet')) {
|
|
395
|
-
logElement.removeChild(firstChild);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
logElement.insertBefore(logEntry, logElement.firstChild);
|
|
399
|
-
|
|
400
|
-
// Keep only last 50 entries
|
|
401
|
-
while (logElement.children.length > 50) {
|
|
402
|
-
logElement.removeChild(logElement.lastChild);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
function clearRequestLog() {
|
|
407
|
-
const logElement = document.getElementById('requestLog');
|
|
408
|
-
logElement.innerHTML = '<div class="text-gray-500">No requests yet. Reload the DataTable to see fetch events...</div>';
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Initialize on page load
|
|
412
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
413
|
-
setTimeout(() => {
|
|
414
|
-
initDataTable();
|
|
415
|
-
// Set initial active button
|
|
416
|
-
changeCredentialsMode('same-origin');
|
|
417
|
-
}, 100);
|
|
418
|
-
});
|
|
419
|
-
</script>
|
|
420
|
-
</body>
|
|
421
|
-
|
|
422
|
-
</html>
|
|
423
|
-
|