nowaikit-utils 1.1.0
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/LICENSE +21 -0
- package/README.md +152 -0
- package/ai-window.html +598 -0
- package/background/service-worker.js +398 -0
- package/cli.mjs +65 -0
- package/content/ai-sidebar.js +1198 -0
- package/content/code-templates.js +843 -0
- package/content/content.js +2527 -0
- package/content/integration-bridge.js +627 -0
- package/content/main-panel.js +592 -0
- package/content/styles.css +1609 -0
- package/icons/README.txt +1 -0
- package/icons/icon-128.png +0 -0
- package/icons/icon-16.png +0 -0
- package/icons/icon-48.png +0 -0
- package/icons/icon.svg +16 -0
- package/manifest.json +63 -0
- package/options/options.html +434 -0
- package/package.json +49 -0
- package/popup/popup.html +663 -0
- package/popup/popup.js +414 -0
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NowAIKit Utils — Main Panel
|
|
3
|
+
* Floating/dockable command panel with quick actions, feature toggles,
|
|
4
|
+
* page info, and connected services. Ctrl+Shift+P to toggle.
|
|
5
|
+
*/
|
|
6
|
+
(function() {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var panel = null;
|
|
10
|
+
var isOpen = false;
|
|
11
|
+
var isFloating = false;
|
|
12
|
+
var isDragging = false;
|
|
13
|
+
var dragOffsetX = 0;
|
|
14
|
+
var dragOffsetY = 0;
|
|
15
|
+
|
|
16
|
+
// ─── Helpers ─────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
function _escapeHtml(str) {
|
|
19
|
+
if (typeof window.escapeHtml === 'function') return window.escapeHtml(str);
|
|
20
|
+
var div = document.createElement('div');
|
|
21
|
+
div.textContent = str;
|
|
22
|
+
return div.innerHTML;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function _showToast(msg, type) {
|
|
26
|
+
if (typeof window.showToast === 'function') window.showToast(msg, type);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getModKey() {
|
|
30
|
+
return ((window.nowaikitState || {}).isMac) ? 'Cmd' : 'Ctrl';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ─── Create Panel ───────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
function createPanel() {
|
|
36
|
+
if (document.getElementById('nowaikit-main-panel')) return;
|
|
37
|
+
|
|
38
|
+
panel = document.createElement('div');
|
|
39
|
+
panel.id = 'nowaikit-main-panel';
|
|
40
|
+
panel.className = 'nk-mp';
|
|
41
|
+
panel.innerHTML = buildPanelHTML();
|
|
42
|
+
|
|
43
|
+
// Resize handle for sidebar mode
|
|
44
|
+
var resizeHandle = document.createElement('div');
|
|
45
|
+
resizeHandle.className = 'nk-mp-resize';
|
|
46
|
+
panel.appendChild(resizeHandle);
|
|
47
|
+
initResize(resizeHandle);
|
|
48
|
+
|
|
49
|
+
document.body.appendChild(panel);
|
|
50
|
+
injectStyles();
|
|
51
|
+
bindEvents();
|
|
52
|
+
initDrag();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ─── Panel HTML ─────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
function buildPanelHTML() {
|
|
58
|
+
var NS = window.nowaikitState || {};
|
|
59
|
+
var mod = getModKey();
|
|
60
|
+
var table = NS.currentTable || '';
|
|
61
|
+
var sysId = NS.currentSysId || '';
|
|
62
|
+
var instance = NS.instanceUrl ? new URL(NS.instanceUrl).hostname.split('.')[0] : '';
|
|
63
|
+
|
|
64
|
+
return '' +
|
|
65
|
+
// Header
|
|
66
|
+
'<div class="nk-mp-header">' +
|
|
67
|
+
'<div class="nk-mp-header-left">' +
|
|
68
|
+
'<svg width="22" height="22" viewBox="0 0 512 512" style="flex-shrink:0"><defs><linearGradient id="nkMpGrad" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#00F0C0"/><stop offset="50%" stop-color="#00D4AA"/><stop offset="100%" stop-color="#0F4C81"/></linearGradient></defs><rect width="512" height="512" rx="128" fill="url(#nkMpGrad)"/><g transform="translate(256,256) scale(9.13) translate(-22,-23)"><path d="M5 39V7l15 27V7" stroke="#fff" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M34 4l2 7 6 2-6 2-2 7-2-7-6-2 6-2z" fill="#fff" opacity="0.9"><animate attributeName="opacity" values="0.9;0.4;0.9" dur="2s" repeatCount="indefinite"/></path><circle cx="34" cy="34" r="4.5" fill="#fff" opacity="0.8"><animate attributeName="opacity" values="0.8;0.4;0.8" dur="2s" repeatCount="indefinite" begin="0.3s"/></circle></g></svg>' +
|
|
69
|
+
'<span class="nk-mp-title"><span class="nk-mp-logo-now">Now</span><span class="nk-mp-logo-ai">AI</span><span class="nk-mp-logo-kit">Kit</span><span class="nk-mp-logo-suffix"> Utils</span></span>' +
|
|
70
|
+
'</div>' +
|
|
71
|
+
'<div class="nk-mp-header-actions">' +
|
|
72
|
+
'<button class="nk-mp-hbtn" id="nk-mp-float" title="Float window">' +
|
|
73
|
+
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><rect x="7" y="7" width="10" height="10" rx="1" fill="currentColor" opacity="0.15"/></svg>' +
|
|
74
|
+
'</button>' +
|
|
75
|
+
'<button class="nk-mp-hbtn" id="nk-mp-close" title="Close (' + mod + '+Shift+P)">' +
|
|
76
|
+
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>' +
|
|
77
|
+
'</button>' +
|
|
78
|
+
'</div>' +
|
|
79
|
+
'</div>' +
|
|
80
|
+
|
|
81
|
+
// Scrollable body
|
|
82
|
+
'<div class="nk-mp-body">' +
|
|
83
|
+
|
|
84
|
+
// Instance status
|
|
85
|
+
'<div class="nk-mp-section">' +
|
|
86
|
+
'<div class="nk-mp-section-title">Instance</div>' +
|
|
87
|
+
'<div class="nk-mp-instance-row">' +
|
|
88
|
+
'<span class="nk-mp-dot' + (instance ? ' active' : '') + '"></span>' +
|
|
89
|
+
'<span class="nk-mp-instance-name">' + (instance ? _escapeHtml(instance) : 'Not detected') + '</span>' +
|
|
90
|
+
'</div>' +
|
|
91
|
+
'</div>' +
|
|
92
|
+
|
|
93
|
+
// Page info
|
|
94
|
+
(table ? (
|
|
95
|
+
'<div class="nk-mp-section">' +
|
|
96
|
+
'<div class="nk-mp-section-title">Page Info</div>' +
|
|
97
|
+
'<div class="nk-mp-info-grid">' +
|
|
98
|
+
'<div class="nk-mp-info-item">' +
|
|
99
|
+
'<span class="nk-mp-info-label">Table</span>' +
|
|
100
|
+
'<span class="nk-mp-info-value nk-mp-copyable" data-copy="' + _escapeHtml(table) + '">' + _escapeHtml(table) + '</span>' +
|
|
101
|
+
'</div>' +
|
|
102
|
+
(sysId ? (
|
|
103
|
+
'<div class="nk-mp-info-item">' +
|
|
104
|
+
'<span class="nk-mp-info-label">sys_id</span>' +
|
|
105
|
+
'<span class="nk-mp-info-value nk-mp-copyable" data-copy="' + _escapeHtml(sysId) + '">' + _escapeHtml(sysId.substring(0, 16)) + '...</span>' +
|
|
106
|
+
'</div>'
|
|
107
|
+
) : '') +
|
|
108
|
+
'</div>' +
|
|
109
|
+
'</div>'
|
|
110
|
+
) : '') +
|
|
111
|
+
|
|
112
|
+
// Quick actions
|
|
113
|
+
'<div class="nk-mp-section">' +
|
|
114
|
+
'<div class="nk-mp-section-title">Quick Actions</div>' +
|
|
115
|
+
'<div class="nk-mp-actions">' +
|
|
116
|
+
'<button class="nk-mp-action" data-action="copy-sysid"><span class="nk-mp-action-icon">📋</span>Copy sys_id</button>' +
|
|
117
|
+
'<button class="nk-mp-action" data-action="copy-url"><span class="nk-mp-action-icon">🔗</span>Copy URL</button>' +
|
|
118
|
+
'<button class="nk-mp-action" data-action="list-view"><span class="nk-mp-action-icon">📄</span>List View</button>' +
|
|
119
|
+
'<button class="nk-mp-action" data-action="xml-view"><span class="nk-mp-action-icon">📄</span>XML View</button>' +
|
|
120
|
+
'<button class="nk-mp-action" data-action="json-view"><span class="nk-mp-action-icon">{}</span>JSON View</button>' +
|
|
121
|
+
'<button class="nk-mp-action" data-action="schema"><span class="nk-mp-action-icon">📑</span>Schema</button>' +
|
|
122
|
+
'<button class="nk-mp-action" data-action="node-switch"><span class="nk-mp-action-icon">🌐</span>Switch Node</button>' +
|
|
123
|
+
'<button class="nk-mp-action" data-action="templates"><span class="nk-mp-action-icon">📝</span>Templates</button>' +
|
|
124
|
+
'<button class="nk-mp-action nk-mp-action-wide" data-action="ai-assistant"><span class="nk-mp-action-icon">🤖</span> AI Assistant</button>' +
|
|
125
|
+
'</div>' +
|
|
126
|
+
'</div>' +
|
|
127
|
+
|
|
128
|
+
// Feature toggles
|
|
129
|
+
'<div class="nk-mp-section">' +
|
|
130
|
+
'<div class="nk-mp-section-title">Features</div>' +
|
|
131
|
+
'<div class="nk-mp-toggles">' +
|
|
132
|
+
buildToggle('showTechnicalNames', 'Technical names') +
|
|
133
|
+
buildToggle('showUpdateSetBanner', 'Update set banner') +
|
|
134
|
+
buildToggle('enableFieldCopy', 'Field copy buttons') +
|
|
135
|
+
buildToggle('enableQuickNav', 'Quick navigation') +
|
|
136
|
+
'</div>' +
|
|
137
|
+
'</div>' +
|
|
138
|
+
|
|
139
|
+
// Connected services
|
|
140
|
+
'<div class="nk-mp-section">' +
|
|
141
|
+
'<div class="nk-mp-section-title">Connected Services</div>' +
|
|
142
|
+
'<div class="nk-mp-service-row">' +
|
|
143
|
+
'<span class="nk-mp-dot" id="nk-mp-builder-dot"></span>' +
|
|
144
|
+
'<span class="nk-mp-service-name">NowAIKit Builder</span>' +
|
|
145
|
+
'<span class="nk-mp-service-status" id="nk-mp-builder-status">Checking...</span>' +
|
|
146
|
+
'</div>' +
|
|
147
|
+
'<div class="nk-mp-service-row">' +
|
|
148
|
+
'<span class="nk-mp-dot" id="nk-mp-mcp-dot"></span>' +
|
|
149
|
+
'<span class="nk-mp-service-name">MCP Server</span>' +
|
|
150
|
+
'<span class="nk-mp-service-status" id="nk-mp-mcp-status">Via Builder</span>' +
|
|
151
|
+
'</div>' +
|
|
152
|
+
'</div>' +
|
|
153
|
+
|
|
154
|
+
// Keyboard shortcuts (collapsed)
|
|
155
|
+
'<div class="nk-mp-section">' +
|
|
156
|
+
'<div class="nk-mp-section-title nk-mp-collapsible" id="nk-mp-shortcuts-toggle">Keyboard Shortcuts <span class="nk-mp-chevron">▶</span></div>' +
|
|
157
|
+
'<div class="nk-mp-shortcuts collapsed" id="nk-mp-shortcuts">' +
|
|
158
|
+
buildShortcut('Main Panel', mod + '+Shift+P') +
|
|
159
|
+
buildShortcut('Quick Nav', mod + '+Shift+K') +
|
|
160
|
+
buildShortcut('Copy sys_id', mod + '+Shift+C') +
|
|
161
|
+
buildShortcut('Copy URL', mod + '+Shift+U') +
|
|
162
|
+
buildShortcut('List View', mod + '+Shift+L') +
|
|
163
|
+
buildShortcut('XML / JSON', mod + '+Shift+X / J') +
|
|
164
|
+
buildShortcut('Templates', mod + '+Shift+T') +
|
|
165
|
+
buildShortcut('AI Assistant', mod + '+Shift+A') +
|
|
166
|
+
buildShortcut('Switch Node', mod + '+Shift+N') +
|
|
167
|
+
'</div>' +
|
|
168
|
+
'</div>' +
|
|
169
|
+
|
|
170
|
+
'</div>' + // end body
|
|
171
|
+
|
|
172
|
+
// Footer
|
|
173
|
+
'<div class="nk-mp-footer">' +
|
|
174
|
+
'Part of <a href="https://nowaikit.com" target="_blank">NowAIKit</a>' +
|
|
175
|
+
'</div>';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function buildToggle(key, label) {
|
|
179
|
+
return '<div class="nk-mp-toggle-row">' +
|
|
180
|
+
'<span class="nk-mp-toggle-label">' + _escapeHtml(label) + '</span>' +
|
|
181
|
+
'<label class="nk-mp-toggle">' +
|
|
182
|
+
'<input type="checkbox" data-setting="' + key + '">' +
|
|
183
|
+
'<span class="nk-mp-toggle-slider"></span>' +
|
|
184
|
+
'</label>' +
|
|
185
|
+
'</div>';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function buildShortcut(label, keys) {
|
|
189
|
+
var kbds = keys.split('+').map(function(k) {
|
|
190
|
+
return '<kbd>' + k.trim() + '</kbd>';
|
|
191
|
+
}).join('');
|
|
192
|
+
return '<div class="nk-mp-shortcut-row">' +
|
|
193
|
+
'<span class="nk-mp-shortcut-label">' + _escapeHtml(label) + '</span>' +
|
|
194
|
+
'<div class="nk-mp-shortcut-keys">' + kbds + '</div>' +
|
|
195
|
+
'</div>';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ─── Events ─────────────────────────────────────────────────────
|
|
199
|
+
|
|
200
|
+
function bindEvents() {
|
|
201
|
+
// Close
|
|
202
|
+
document.getElementById('nk-mp-close').addEventListener('click', closePanel);
|
|
203
|
+
|
|
204
|
+
// Float toggle
|
|
205
|
+
document.getElementById('nk-mp-float').addEventListener('click', toggleFloat);
|
|
206
|
+
|
|
207
|
+
// Shortcuts collapsible
|
|
208
|
+
var shortcutsToggle = document.getElementById('nk-mp-shortcuts-toggle');
|
|
209
|
+
var shortcutsSection = document.getElementById('nk-mp-shortcuts');
|
|
210
|
+
if (shortcutsToggle && shortcutsSection) {
|
|
211
|
+
shortcutsToggle.addEventListener('click', function() {
|
|
212
|
+
var collapsed = shortcutsSection.classList.toggle('collapsed');
|
|
213
|
+
shortcutsToggle.classList.toggle('expanded', !collapsed);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Copyable values
|
|
218
|
+
panel.querySelectorAll('.nk-mp-copyable').forEach(function(el) {
|
|
219
|
+
el.addEventListener('click', function() {
|
|
220
|
+
var text = el.getAttribute('data-copy');
|
|
221
|
+
if (text) {
|
|
222
|
+
navigator.clipboard.writeText(text);
|
|
223
|
+
var orig = el.textContent;
|
|
224
|
+
el.textContent = 'Copied!';
|
|
225
|
+
setTimeout(function() { el.textContent = orig; }, 1000);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Quick actions
|
|
231
|
+
panel.querySelectorAll('.nk-mp-action').forEach(function(btn) {
|
|
232
|
+
btn.addEventListener('click', function() {
|
|
233
|
+
handleAction(btn.getAttribute('data-action'));
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Feature toggles — load state and bind
|
|
238
|
+
var toggleInputs = panel.querySelectorAll('input[data-setting]');
|
|
239
|
+
var settingKeys = {};
|
|
240
|
+
toggleInputs.forEach(function(inp) {
|
|
241
|
+
settingKeys[inp.getAttribute('data-setting')] = false;
|
|
242
|
+
});
|
|
243
|
+
chrome.storage.sync.get(settingKeys, function(stored) {
|
|
244
|
+
toggleInputs.forEach(function(inp) {
|
|
245
|
+
var key = inp.getAttribute('data-setting');
|
|
246
|
+
inp.checked = !!stored[key];
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
toggleInputs.forEach(function(inp) {
|
|
250
|
+
inp.addEventListener('change', function() {
|
|
251
|
+
var obj = {};
|
|
252
|
+
obj[inp.getAttribute('data-setting')] = inp.checked;
|
|
253
|
+
chrome.storage.sync.set(obj);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Escape key
|
|
258
|
+
document.addEventListener('keydown', function(e) {
|
|
259
|
+
if (e.key === 'Escape' && isOpen) {
|
|
260
|
+
closePanel();
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Bridge status
|
|
265
|
+
checkBridgeStatus();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function handleAction(action) {
|
|
269
|
+
var NS = window.nowaikitState || {};
|
|
270
|
+
var table = NS.currentTable || '';
|
|
271
|
+
var sysId = NS.currentSysId || '';
|
|
272
|
+
var instanceUrl = NS.instanceUrl || '';
|
|
273
|
+
|
|
274
|
+
switch (action) {
|
|
275
|
+
case 'copy-sysid':
|
|
276
|
+
if (sysId) {
|
|
277
|
+
navigator.clipboard.writeText(sysId);
|
|
278
|
+
_showToast('sys_id copied!');
|
|
279
|
+
} else {
|
|
280
|
+
_showToast('No sys_id found', 'warn');
|
|
281
|
+
}
|
|
282
|
+
break;
|
|
283
|
+
case 'copy-url':
|
|
284
|
+
navigator.clipboard.writeText(window.location.href);
|
|
285
|
+
_showToast('URL copied!');
|
|
286
|
+
break;
|
|
287
|
+
case 'list-view':
|
|
288
|
+
if (table) window.open(instanceUrl + '/' + table + '_list.do', '_blank');
|
|
289
|
+
break;
|
|
290
|
+
case 'xml-view':
|
|
291
|
+
if (table && sysId) window.open(instanceUrl + '/' + table + '.do?XML&sys_id=' + sysId, '_blank');
|
|
292
|
+
else if (table) window.open(instanceUrl + '/' + table + '.do?XML', '_blank');
|
|
293
|
+
break;
|
|
294
|
+
case 'json-view':
|
|
295
|
+
if (table && sysId) window.open(instanceUrl + '/' + table + '.do?JSONv2&sysparm_action=get&sysparm_sys_id=' + sysId, '_blank');
|
|
296
|
+
else if (table) window.open(instanceUrl + '/' + table + '.do?JSONv2&sysparm_action=getRecords&sysparm_limit=20', '_blank');
|
|
297
|
+
break;
|
|
298
|
+
case 'schema':
|
|
299
|
+
if (table) window.open(instanceUrl + '/sys_dictionary_list.do?sysparm_query=name=' + table, '_blank');
|
|
300
|
+
break;
|
|
301
|
+
case 'node-switch':
|
|
302
|
+
if (typeof window.openNodeSwitcher === 'function') window.openNodeSwitcher();
|
|
303
|
+
break;
|
|
304
|
+
case 'templates':
|
|
305
|
+
if (typeof window.toggleCodeTemplates === 'function') window.toggleCodeTemplates();
|
|
306
|
+
break;
|
|
307
|
+
case 'ai-assistant':
|
|
308
|
+
if (typeof window.ensureAISidebar === 'function') window.ensureAISidebar();
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function checkBridgeStatus() {
|
|
314
|
+
if (typeof getBridgeStatus !== 'function') return;
|
|
315
|
+
try {
|
|
316
|
+
var status = getBridgeStatus();
|
|
317
|
+
var builderDot = document.getElementById('nk-mp-builder-dot');
|
|
318
|
+
var builderStatus = document.getElementById('nk-mp-builder-status');
|
|
319
|
+
var mcpDot = document.getElementById('nk-mp-mcp-dot');
|
|
320
|
+
var mcpStatus = document.getElementById('nk-mp-mcp-status');
|
|
321
|
+
|
|
322
|
+
if (status && status.connected) {
|
|
323
|
+
if (builderDot) { builderDot.classList.add('active'); }
|
|
324
|
+
if (builderStatus) { builderStatus.textContent = status.instanceName || 'Connected'; builderStatus.style.color = 'var(--nk-teal)'; }
|
|
325
|
+
if (mcpDot) { mcpDot.classList.add('active'); }
|
|
326
|
+
if (mcpStatus) { mcpStatus.textContent = 'Available'; mcpStatus.style.color = 'var(--nk-teal)'; }
|
|
327
|
+
} else {
|
|
328
|
+
if (builderStatus) builderStatus.textContent = 'Not running';
|
|
329
|
+
if (mcpStatus) mcpStatus.textContent = 'Not available';
|
|
330
|
+
}
|
|
331
|
+
} catch(e) {
|
|
332
|
+
// bridge not available
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// ─── Toggle / Float / Drag / Resize ─────────────────────────────
|
|
337
|
+
|
|
338
|
+
function togglePanel() {
|
|
339
|
+
if (!panel) createPanel();
|
|
340
|
+
isOpen = !isOpen;
|
|
341
|
+
panel.classList.toggle('nk-mp-open', isOpen);
|
|
342
|
+
if (isOpen) {
|
|
343
|
+
// Close other panels
|
|
344
|
+
if (typeof window.closeAISidebar === 'function') window.closeAISidebar();
|
|
345
|
+
if (typeof window.closeCodeTemplates === 'function') window.closeCodeTemplates();
|
|
346
|
+
refreshPageInfo();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function closePanel() {
|
|
351
|
+
isOpen = false;
|
|
352
|
+
if (panel) panel.classList.remove('nk-mp-open');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function toggleFloat() {
|
|
356
|
+
if (!panel) return;
|
|
357
|
+
isFloating = !isFloating;
|
|
358
|
+
panel.classList.toggle('nk-mp-floating', isFloating);
|
|
359
|
+
|
|
360
|
+
var floatBtn = document.getElementById('nk-mp-float');
|
|
361
|
+
if (floatBtn) {
|
|
362
|
+
floatBtn.title = isFloating ? 'Dock to side' : 'Float window';
|
|
363
|
+
floatBtn.innerHTML = isFloating
|
|
364
|
+
? '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="18" rx="2"/><line x1="15" y1="3" x2="15" y2="21"/></svg>'
|
|
365
|
+
: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><rect x="7" y="7" width="10" height="10" rx="1" fill="currentColor" opacity="0.15"/></svg>';
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (!isFloating) {
|
|
369
|
+
panel.style.left = '';
|
|
370
|
+
panel.style.top = '';
|
|
371
|
+
panel.style.right = '';
|
|
372
|
+
panel.style.width = '';
|
|
373
|
+
panel.style.height = '';
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function initDrag() {
|
|
378
|
+
document.addEventListener('mousedown', function(e) {
|
|
379
|
+
if (!isFloating || !panel) return;
|
|
380
|
+
var header = panel.querySelector('.nk-mp-header');
|
|
381
|
+
if (!header || !header.contains(e.target)) return;
|
|
382
|
+
if (e.target.closest('.nk-mp-hbtn')) return;
|
|
383
|
+
isDragging = true;
|
|
384
|
+
var rect = panel.getBoundingClientRect();
|
|
385
|
+
dragOffsetX = e.clientX - rect.left;
|
|
386
|
+
dragOffsetY = e.clientY - rect.top;
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
document.addEventListener('mousemove', function(e) {
|
|
391
|
+
if (!isDragging) return;
|
|
392
|
+
var x = Math.max(0, Math.min(e.clientX - dragOffsetX, window.innerWidth - 100));
|
|
393
|
+
var y = Math.max(0, Math.min(e.clientY - dragOffsetY, window.innerHeight - 100));
|
|
394
|
+
panel.style.left = x + 'px';
|
|
395
|
+
panel.style.top = y + 'px';
|
|
396
|
+
panel.style.right = 'auto';
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
document.addEventListener('mouseup', function() {
|
|
400
|
+
isDragging = false;
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function initResize(handle) {
|
|
405
|
+
var isResizing = false;
|
|
406
|
+
var startX = 0;
|
|
407
|
+
var startWidth = 0;
|
|
408
|
+
|
|
409
|
+
handle.addEventListener('mousedown', function(e) {
|
|
410
|
+
if (isFloating) return;
|
|
411
|
+
isResizing = true;
|
|
412
|
+
startX = e.clientX;
|
|
413
|
+
startWidth = panel.offsetWidth;
|
|
414
|
+
handle.classList.add('active');
|
|
415
|
+
e.preventDefault();
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
document.addEventListener('mousemove', function(e) {
|
|
419
|
+
if (!isResizing) return;
|
|
420
|
+
var diff = startX - e.clientX;
|
|
421
|
+
var newWidth = Math.max(340, Math.min(startWidth + diff, window.innerWidth * 0.7));
|
|
422
|
+
panel.style.width = newWidth + 'px';
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
document.addEventListener('mouseup', function() {
|
|
426
|
+
if (isResizing) {
|
|
427
|
+
isResizing = false;
|
|
428
|
+
handle.classList.remove('active');
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function refreshPageInfo() {
|
|
434
|
+
// Re-read state from nowaikitState since it may have changed
|
|
435
|
+
var NS = window.nowaikitState || {};
|
|
436
|
+
var table = NS.currentTable || '';
|
|
437
|
+
var sysId = NS.currentSysId || '';
|
|
438
|
+
var instance = NS.instanceUrl ? new URL(NS.instanceUrl).hostname.split('.')[0] : '';
|
|
439
|
+
|
|
440
|
+
// Update instance
|
|
441
|
+
var instEl = panel.querySelector('.nk-mp-instance-name');
|
|
442
|
+
var dotEl = panel.querySelector('.nk-mp-instance-row .nk-mp-dot');
|
|
443
|
+
if (instEl) instEl.textContent = instance || 'Not detected';
|
|
444
|
+
if (dotEl) dotEl.classList.toggle('active', !!instance);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// ─── Styles ─────────────────────────────────────────────────────
|
|
448
|
+
|
|
449
|
+
function injectStyles() {
|
|
450
|
+
if (document.getElementById('nk-mp-styles')) return;
|
|
451
|
+
var s = document.createElement('style');
|
|
452
|
+
s.id = 'nk-mp-styles';
|
|
453
|
+
s.textContent =
|
|
454
|
+
':root{--nk-teal:#00D4AA;--nk-navy:#0F4C81;--nk-bg:#0B1020;--nk-card:#111828;--nk-border:#1e2a3e;--nk-text:#e0e5ec;--nk-text-dim:#6b7a90;}' +
|
|
455
|
+
|
|
456
|
+
/* Reset */
|
|
457
|
+
'.nk-mp,.nk-mp *{box-sizing:border-box;margin:0;padding:0;line-height:normal;}' +
|
|
458
|
+
|
|
459
|
+
/* Panel — sidebar mode */
|
|
460
|
+
'.nk-mp{position:fixed;top:0;right:-420px;width:420px;max-width:100vw;height:100vh;' +
|
|
461
|
+
'background:var(--nk-bg);border-left:1px solid var(--nk-border);z-index:2147483645;' +
|
|
462
|
+
'display:flex;flex-direction:column;overflow:hidden;' +
|
|
463
|
+
'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;' +
|
|
464
|
+
'font-size:13px;color:var(--nk-text);box-shadow:-4px 0 20px rgba(0,0,0,.4);' +
|
|
465
|
+
'transition:right .3s cubic-bezier(.4,0,.2,1);}' +
|
|
466
|
+
'.nk-mp.nk-mp-open{right:0;}' +
|
|
467
|
+
|
|
468
|
+
/* Floating */
|
|
469
|
+
'.nk-mp.nk-mp-floating{top:40px;right:40px;width:480px;height:70vh;' +
|
|
470
|
+
'border-radius:12px;border:1px solid var(--nk-border);box-shadow:0 12px 40px rgba(0,0,0,.6);' +
|
|
471
|
+
'resize:both;overflow:hidden;min-width:340px;min-height:300px;}' +
|
|
472
|
+
'.nk-mp.nk-mp-floating .nk-mp-header{cursor:grab;border-radius:12px 12px 0 0;}' +
|
|
473
|
+
'.nk-mp.nk-mp-floating .nk-mp-header:active{cursor:grabbing;}' +
|
|
474
|
+
'.nk-mp.nk-mp-floating .nk-mp-resize{display:none;}' +
|
|
475
|
+
|
|
476
|
+
/* Resize handle */
|
|
477
|
+
'.nk-mp-resize{position:absolute;top:0;left:-3px;width:6px;height:100%;cursor:ew-resize;z-index:10;}' +
|
|
478
|
+
'.nk-mp-resize:hover,.nk-mp-resize.active{background:rgba(0,212,170,.3);}' +
|
|
479
|
+
|
|
480
|
+
/* Header */
|
|
481
|
+
'.nk-mp-header{display:flex;align-items:center;justify-content:space-between;' +
|
|
482
|
+
'padding:14px 16px;background:linear-gradient(135deg,#0a2e5c 0%,#065f50 100%);flex-shrink:0;}' +
|
|
483
|
+
'.nk-mp-header-left{display:flex;align-items:center;gap:8px;color:#fff;}' +
|
|
484
|
+
'.nk-mp-title{font-size:16px;font-weight:800;color:#fff;letter-spacing:-0.02em;}' +
|
|
485
|
+
'.nk-mp-logo-now{background:linear-gradient(135deg,#fff 0%,#B8C4D4 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;}' +
|
|
486
|
+
'.nk-mp-logo-ai{background:linear-gradient(90deg,#00F0C0,#00D4AA,#0F4C81,#00D4AA,#00F0C0);background-size:300% 100%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;animation:nkMpShimmer 4s ease-in-out infinite;}' +
|
|
487
|
+
'.nk-mp-logo-kit{background:linear-gradient(135deg,#A0AEBE 0%,#6B7A8E 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;}' +
|
|
488
|
+
'.nk-mp-logo-suffix{font-weight:400;font-size:0.75em;-webkit-text-fill-color:rgba(255,255,255,0.5);letter-spacing:0.04em;}' +
|
|
489
|
+
'@keyframes nkMpShimmer{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}' +
|
|
490
|
+
'.nk-mp-header-actions{display:flex;gap:4px;}' +
|
|
491
|
+
'.nk-mp-hbtn{width:28px;height:28px;border:none;background:rgba(255,255,255,.12);' +
|
|
492
|
+
'color:#fff;border-radius:5px;cursor:pointer;display:inline-flex;align-items:center;' +
|
|
493
|
+
'justify-content:center;transition:background .2s;flex-shrink:0;}' +
|
|
494
|
+
'.nk-mp-hbtn:hover{background:rgba(255,255,255,.25);}' +
|
|
495
|
+
|
|
496
|
+
/* Body — scrollable */
|
|
497
|
+
'.nk-mp-body{flex:1;overflow-y:auto;overflow-x:hidden;}' +
|
|
498
|
+
'.nk-mp-body::-webkit-scrollbar{width:5px;}' +
|
|
499
|
+
'.nk-mp-body::-webkit-scrollbar-thumb{background:var(--nk-border);border-radius:3px;}' +
|
|
500
|
+
|
|
501
|
+
/* Section */
|
|
502
|
+
'.nk-mp-section{padding:12px 16px;border-bottom:1px solid var(--nk-border);}' +
|
|
503
|
+
'.nk-mp-section-title{font-size:10px;font-weight:600;color:var(--nk-text-dim);' +
|
|
504
|
+
'text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;}' +
|
|
505
|
+
|
|
506
|
+
/* Instance row */
|
|
507
|
+
'.nk-mp-instance-row{display:flex;align-items:center;gap:8px;}' +
|
|
508
|
+
'.nk-mp-dot{width:8px;height:8px;border-radius:50%;background:#555;flex-shrink:0;}' +
|
|
509
|
+
'.nk-mp-dot.active{background:var(--nk-teal);box-shadow:0 0 6px rgba(0,212,170,.4);}' +
|
|
510
|
+
'.nk-mp-instance-name{font-size:13px;font-weight:600;color:var(--nk-text);}' +
|
|
511
|
+
|
|
512
|
+
/* Page info */
|
|
513
|
+
'.nk-mp-info-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;}' +
|
|
514
|
+
'.nk-mp-info-item{display:flex;flex-direction:column;gap:2px;}' +
|
|
515
|
+
'.nk-mp-info-label{font-size:10px;color:var(--nk-text-dim);text-transform:uppercase;}' +
|
|
516
|
+
'.nk-mp-info-value{font-size:12px;color:var(--nk-teal);font-family:"JetBrains Mono",monospace;}' +
|
|
517
|
+
'.nk-mp-copyable{cursor:pointer;transition:color .15s;}' +
|
|
518
|
+
'.nk-mp-copyable:hover{color:#00F0C0;}' +
|
|
519
|
+
|
|
520
|
+
/* Quick actions */
|
|
521
|
+
'.nk-mp-actions{display:grid;grid-template-columns:1fr 1fr 1fr;gap:5px;}' +
|
|
522
|
+
'.nk-mp-action{background:var(--nk-card);border:1px solid var(--nk-border);border-radius:6px;' +
|
|
523
|
+
'padding:8px 6px;color:var(--nk-text);font-size:11px;cursor:pointer;text-align:center;' +
|
|
524
|
+
'transition:border-color .2s,background .2s;font-family:inherit;white-space:nowrap;}' +
|
|
525
|
+
'.nk-mp-action:hover{border-color:var(--nk-teal);background:rgba(0,212,170,.05);}' +
|
|
526
|
+
'.nk-mp-action-icon{font-size:13px;display:block;margin-bottom:2px;}' +
|
|
527
|
+
'.nk-mp-action-wide{grid-column:1/-1;background:linear-gradient(135deg,var(--nk-navy),rgba(0,212,170,.15));border-color:var(--nk-teal);}' +
|
|
528
|
+
|
|
529
|
+
/* Toggles */
|
|
530
|
+
'.nk-mp-toggles{display:flex;flex-direction:column;gap:2px;}' +
|
|
531
|
+
'.nk-mp-toggle-row{display:flex;justify-content:space-between;align-items:center;padding:5px 0;}' +
|
|
532
|
+
'.nk-mp-toggle-label{font-size:12px;color:var(--nk-text);}' +
|
|
533
|
+
'.nk-mp-toggle{position:relative;width:36px;height:20px;display:inline-block;}' +
|
|
534
|
+
'.nk-mp-toggle input{opacity:0;width:0;height:0;}' +
|
|
535
|
+
'.nk-mp-toggle-slider{position:absolute;inset:0;background:#2a3548;border-radius:10px;cursor:pointer;transition:background .2s;}' +
|
|
536
|
+
'.nk-mp-toggle-slider::before{content:"";position:absolute;width:16px;height:16px;left:2px;top:2px;background:#fff;border-radius:50%;transition:transform .2s;}' +
|
|
537
|
+
'.nk-mp-toggle input:checked+.nk-mp-toggle-slider{background:var(--nk-teal);}' +
|
|
538
|
+
'.nk-mp-toggle input:checked+.nk-mp-toggle-slider::before{transform:translateX(16px);}' +
|
|
539
|
+
|
|
540
|
+
/* Services */
|
|
541
|
+
'.nk-mp-service-row{display:flex;align-items:center;gap:8px;padding:4px 0;}' +
|
|
542
|
+
'.nk-mp-service-name{font-size:12px;color:var(--nk-text-dim);flex:1;}' +
|
|
543
|
+
'.nk-mp-service-status{font-size:11px;color:var(--nk-text-dim);}' +
|
|
544
|
+
|
|
545
|
+
/* Shortcuts — collapsible */
|
|
546
|
+
'.nk-mp-collapsible{cursor:pointer;display:flex;justify-content:space-between;align-items:center;user-select:none;margin-bottom:0;}' +
|
|
547
|
+
'.nk-mp-collapsible:hover{color:var(--nk-teal);}' +
|
|
548
|
+
'.nk-mp-collapsible.expanded{margin-bottom:8px;}' +
|
|
549
|
+
'.nk-mp-chevron{font-size:10px;transition:transform .2s;display:inline-block;}' +
|
|
550
|
+
'.nk-mp-collapsible.expanded .nk-mp-chevron{transform:rotate(90deg);}' +
|
|
551
|
+
'.nk-mp-shortcuts{display:flex;flex-direction:column;gap:3px;}' +
|
|
552
|
+
'.nk-mp-shortcuts.collapsed{display:none;}' +
|
|
553
|
+
'.nk-mp-shortcut-row{display:flex;justify-content:space-between;align-items:center;padding:3px 0;}' +
|
|
554
|
+
'.nk-mp-shortcut-label{color:var(--nk-text-dim);font-size:11px;}' +
|
|
555
|
+
'.nk-mp-shortcut-keys{display:flex;gap:2px;}' +
|
|
556
|
+
'.nk-mp-shortcut-keys kbd{background:#1a2236;border:1px solid var(--nk-border);border-radius:3px;' +
|
|
557
|
+
'padding:1px 5px;font-size:10px;font-family:"JetBrains Mono",monospace;color:var(--nk-teal);}' +
|
|
558
|
+
|
|
559
|
+
/* Footer */
|
|
560
|
+
'.nk-mp-footer{padding:8px 16px;text-align:center;font-size:10px;color:var(--nk-text-dim);' +
|
|
561
|
+
'border-top:1px solid var(--nk-border);flex-shrink:0;}' +
|
|
562
|
+
'.nk-mp-footer a{color:var(--nk-teal);text-decoration:none;}' +
|
|
563
|
+
'.nk-mp-footer a:hover{text-decoration:underline;}' +
|
|
564
|
+
|
|
565
|
+
/* ── Light Theme ── */
|
|
566
|
+
'body.nowaikit-light .nk-mp{--nk-bg:#f8fafc;--nk-card:#ffffff;--nk-border:#e2e8f0;--nk-text:#1a202c;--nk-text-dim:#64748b;--nk-teal:#0D9488;--nk-navy:#0F4C81;' +
|
|
567
|
+
'box-shadow:-4px 0 20px rgba(0,0,0,.08);}' +
|
|
568
|
+
'body.nowaikit-light .nk-mp-action{background:#f8fafc;border-color:#e2e8f0;color:#1a202c;}' +
|
|
569
|
+
'body.nowaikit-light .nk-mp-action:hover{border-color:#0D9488;background:rgba(13,148,136,.05);}' +
|
|
570
|
+
'body.nowaikit-light .nk-mp-action-wide{background:linear-gradient(135deg,#0D9488,rgba(13,148,136,.12));color:#fff;border-color:#0D9488;}' +
|
|
571
|
+
'body.nowaikit-light .nk-mp-toggle-slider{background:#cbd5e1;}' +
|
|
572
|
+
'body.nowaikit-light .nk-mp-shortcut-keys kbd{background:#f1f5f9;border-color:#e2e8f0;color:#0D9488;}' +
|
|
573
|
+
'body.nowaikit-light .nk-mp-body::-webkit-scrollbar-thumb{background:#cbd5e1;}' +
|
|
574
|
+
'body.nowaikit-light .nk-mp-info-value{color:#0D9488;}' +
|
|
575
|
+
'body.nowaikit-light .nk-mp-dot.active{background:#0D9488;box-shadow:0 0 6px rgba(13,148,136,.4);}' +
|
|
576
|
+
|
|
577
|
+
/* Responsive */
|
|
578
|
+
'@media(max-width:520px){' +
|
|
579
|
+
'.nk-mp{width:100vw;right:-100vw;}' +
|
|
580
|
+
'.nk-mp.nk-mp-open{right:0;}' +
|
|
581
|
+
'.nk-mp.nk-mp-floating{top:0;right:0;width:100vw;height:100vh;border-radius:0;}' +
|
|
582
|
+
'}';
|
|
583
|
+
|
|
584
|
+
document.head.appendChild(s);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// ─── Expose Globals ─────────────────────────────────────────────
|
|
588
|
+
|
|
589
|
+
window.toggleMainPanel = togglePanel;
|
|
590
|
+
window.closeMainPanel = closePanel;
|
|
591
|
+
|
|
592
|
+
})();
|