@enigmax/dashboard 0.1.27 → 0.1.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/assets/index.html +25 -8
- package/package.json +1 -1
package/assets/index.html
CHANGED
|
@@ -159,8 +159,15 @@
|
|
|
159
159
|
.toggle {
|
|
160
160
|
background: var(--surface2); color: var(--muted); border: 1px solid var(--border);
|
|
161
161
|
border-radius: var(--radius-sm); padding: 6px 16px; font-size: 12px; cursor: pointer; font-family: var(--mono); min-width: 56px; text-decoration: none;
|
|
162
|
-
transition: color .15s, background .15s, border-color .15s;
|
|
163
|
-
}
|
|
162
|
+
transition: color .15s, background .15s, border-color .15s, transform .1s;
|
|
163
|
+
}
|
|
164
|
+
/* Click feedback so every button visibly reacts: a quick press, plus a spin while
|
|
165
|
+
an icon action (Refresh) is actually running, and icon+label for import/export. */
|
|
166
|
+
.toggle:active, .iconbtn:active, .btn-danger:active, .achip:active { transform: scale(0.93); }
|
|
167
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
168
|
+
.iconbtn.spinning svg { animation: spin .7s linear infinite; }
|
|
169
|
+
.toggle.with-icon { display: inline-flex; align-items: center; gap: 6px; }
|
|
170
|
+
.toggle.with-icon svg { width: 14px; height: 14px; display: block; }
|
|
164
171
|
.toggle:hover { color: var(--text); border-color: #2f3744; }
|
|
165
172
|
.toggle.on { background: var(--good); color: #06210f; border-color: var(--good); font-weight: 600; }
|
|
166
173
|
/* Boolean settings render as a sliding switch. Only the bool controls carry
|
|
@@ -182,7 +189,7 @@
|
|
|
182
189
|
.toggle[data-kind="bool"].on { background: var(--good); border-color: var(--good); }
|
|
183
190
|
.toggle[data-kind="bool"].on::after { left: 23px; background: #06210f; }
|
|
184
191
|
/* Compact icon-only button (e.g. Edit), instead of a text button. */
|
|
185
|
-
.iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 30px; padding: 0; background: var(--surface2); color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: color .15s, border-color .15s; }
|
|
192
|
+
.iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 30px; padding: 0; background: var(--surface2); color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: color .15s, border-color .15s, transform .1s; }
|
|
186
193
|
.iconbtn:hover { color: var(--accent); border-color: #2f3744; }
|
|
187
194
|
.iconbtn svg { width: 15px; height: 15px; display: block; }
|
|
188
195
|
select.choice {
|
|
@@ -537,8 +544,8 @@
|
|
|
537
544
|
<p>Everything you can configure with <code>enigma config</code> or the terminal UI, editable here. Changes apply at global scope and take effect immediately; toggles that change agent memory need an agent restart.</p>
|
|
538
545
|
</div>
|
|
539
546
|
<div style="display:flex;gap:8px;white-space:nowrap">
|
|
540
|
-
<button id="cfgExport" type="button" class="toggle">Export config</button>
|
|
541
|
-
<button id="cfgImport" type="button" class="toggle">Import config</button>
|
|
547
|
+
<button id="cfgExport" type="button" class="toggle with-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>Export config</button>
|
|
548
|
+
<button id="cfgImport" type="button" class="toggle with-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>Import config</button>
|
|
542
549
|
</div>
|
|
543
550
|
</div>
|
|
544
551
|
<div id="settingsNote" class="set-note"></div>
|
|
@@ -2331,7 +2338,7 @@ export {
|
|
|
2331
2338
|
|
|
2332
2339
|
function onSavings() { const h = (location.hash || "").replace(/^#\/?/, ""); return h !== "settings" && h !== "skills"; }
|
|
2333
2340
|
// One refresh of everything visible on the Savings view; `force` ignores auto-refresh-off.
|
|
2334
|
-
function refreshAll(force) { poll(force)
|
|
2341
|
+
function refreshAll(force) { return Promise.all([poll(force), onSavings() ? loadSystems(force) : null]); }
|
|
2335
2342
|
|
|
2336
2343
|
// --- skills subpage (lists enigma + external skills over /api/skills) ---
|
|
2337
2344
|
// App logos (Claude, OpenAI/Codex, OpenCode), recoloured to currentColor so a chip's
|
|
@@ -2347,6 +2354,9 @@ export {
|
|
|
2347
2354
|
|
|
2348
2355
|
function skillRow(s) {
|
|
2349
2356
|
const ver = s.version ? '<span class="tag">v' + esc(s.version) + "</span>" : "";
|
|
2357
|
+
// Last-edited date (from skill.json), shown relative via the vendored <relative-time>.
|
|
2358
|
+
const edited = s.updated ? '<span class="tag" title="Last edited ' + esc(new Date(s.updated).toLocaleString()) + '">edited '
|
|
2359
|
+
+ rtime(new Date(s.updated).getTime(), 'format="relative"', new Date(s.updated).toLocaleDateString()) + "</span>" : "";
|
|
2350
2360
|
// Show one app icon per agent that holds the skill (name in the tooltip), not the names.
|
|
2351
2361
|
const where = s.agents && s.agents.length
|
|
2352
2362
|
? '<span class="aicons">' + s.agents.map((l) => {
|
|
@@ -2376,7 +2386,7 @@ export {
|
|
|
2376
2386
|
+ (a.deployed ? esc(a.label) + " - on, click to disable" : esc(a.label) + " - off, click to enable")
|
|
2377
2387
|
+ '">' + (agentSvg(a.name) || esc(a.label)) + "</button>").join("") + "</div>"
|
|
2378
2388
|
: "";
|
|
2379
|
-
return '<div class="set-row"><div class="set-meta"><div class="set-name">' + esc(s.name) + ext + ver + upd + where + "</div>"
|
|
2389
|
+
return '<div class="set-row"><div class="set-meta"><div class="set-name">' + esc(s.name) + ext + ver + edited + upd + where + "</div>"
|
|
2380
2390
|
+ '<div class="set-hint">' + esc(s.description || "") + "</div>" + agentChips + '</div><div class="set-ctl" style="display:flex;gap:8px">' + edit + main + "</div></div>";
|
|
2381
2391
|
}
|
|
2382
2392
|
|
|
@@ -2613,7 +2623,14 @@ export {
|
|
|
2613
2623
|
$("cfgImport").addEventListener("click", importConfig);
|
|
2614
2624
|
$("updateBtn").addEventListener("click", runUpdate);
|
|
2615
2625
|
$("fixPathBtn").addEventListener("click", runFixPath);
|
|
2616
|
-
$("refreshBtn").addEventListener("click", () =>
|
|
2626
|
+
$("refreshBtn").addEventListener("click", async () => {
|
|
2627
|
+
const b = $("refreshBtn");
|
|
2628
|
+
if (b.classList.contains("spinning")) return; // already refreshing
|
|
2629
|
+
b.classList.add("spinning");
|
|
2630
|
+
// Spin until the refresh settles, but at least one full turn so a fast refresh still reads.
|
|
2631
|
+
try { await Promise.all([refreshAll(true), new Promise((r) => setTimeout(r, 700))]); }
|
|
2632
|
+
finally { b.classList.remove("spinning"); }
|
|
2633
|
+
});
|
|
2617
2634
|
window.addEventListener("hashchange", route);
|
|
2618
2635
|
route();
|
|
2619
2636
|
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enigmax/dashboard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Local browser dashboard UI for enigma: the static page and chart assets enigma serves on its loopback dashboard (savings, real tool usage, in-browser settings). Installed on demand by enigma-cli; not a runtime dependency.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|