@a83/orbiter-admin 0.3.44 → 0.3.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a83/orbiter-admin",
3
- "version": "0.3.44",
3
+ "version": "0.3.45",
4
4
  "description": "Standalone admin server for Orbiter CMS",
5
5
  "type": "module",
6
6
  "main": "./src/server.js",
package/public/style.css CHANGED
@@ -1158,8 +1158,8 @@ html[data-style="xfce"] .editor-shell {
1158
1158
  flex-direction: column;
1159
1159
  align-items: center;
1160
1160
  justify-content: flex-end;
1161
- width: var(--dock-item-base, 50px);
1162
- padding: 8px 7px 7px;
1161
+ min-width: var(--dock-item-base, 50px);
1162
+ padding: 10px 12px 9px;
1163
1163
  background: transparent;
1164
1164
  border: none;
1165
1165
  border-radius: 12px;
@@ -1196,21 +1196,25 @@ html[data-style="xfce"] .editor-shell {
1196
1196
  }
1197
1197
  .xfce-dock-item.active {
1198
1198
  color: var(--accent);
1199
- background: color-mix(in srgb, var(--accent) 9%, transparent);
1199
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
1200
+ box-shadow:
1201
+ 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
1202
+ 0 0 14px color-mix(in srgb, var(--accent) 22%, transparent),
1203
+ inset 0 1px 0 color-mix(in srgb, white 18%, transparent);
1200
1204
  }
1201
- .xfce-dock-item.active::before { opacity: .5; }
1202
- /* active indicator: glowing scan-line instead of dot */
1205
+ .xfce-dock-item.active::before { opacity: .65; }
1206
+ /* active indicator: glowing dot at bottom */
1203
1207
  .xfce-dock-item.active::after {
1204
1208
  content: '';
1205
1209
  position: absolute;
1206
- bottom: 0;
1210
+ bottom: 4px;
1207
1211
  left: 50%;
1208
1212
  transform: translateX(-50%);
1209
- width: 60%;
1210
- height: 2px;
1211
- border-radius: 1px;
1212
- background: linear-gradient(90deg, transparent, var(--accent) 30%, var(--accent) 70%, transparent);
1213
- box-shadow: 0 0 8px 1px color-mix(in srgb, var(--accent) 70%, transparent);
1213
+ width: 4px;
1214
+ height: 4px;
1215
+ border-radius: 50%;
1216
+ background: var(--accent);
1217
+ box-shadow: 0 0 6px 2px color-mix(in srgb, var(--accent) 80%, transparent);
1214
1218
  }
1215
1219
 
1216
1220
  .xfce-dock-icon {
@@ -1227,9 +1231,10 @@ html[data-style="xfce"] .editor-shell {
1227
1231
  transform: scale(1.14);
1228
1232
  }
1229
1233
  .xfce-dock-item.active .xfce-dock-icon {
1230
- opacity: .95;
1234
+ opacity: 1;
1231
1235
  color: var(--accent);
1232
- filter: drop-shadow(0 0 5px color-mix(in srgb, var(--accent) 65%, transparent));
1236
+ filter: drop-shadow(0 0 8px color-mix(in srgb, var(--accent) 80%, transparent));
1237
+ transform: scale(1.08);
1233
1238
  }
1234
1239
  .xfce-dock-lbl {
1235
1240
  font-family: var(--mono);
@@ -1246,8 +1251,10 @@ html[data-style="xfce"] .editor-shell {
1246
1251
  color: color-mix(in srgb, var(--accent) 80%, var(--heading));
1247
1252
  }
1248
1253
  .xfce-dock-item.active .xfce-dock-lbl {
1249
- opacity: .85;
1254
+ opacity: 1;
1250
1255
  color: var(--accent);
1256
+ font-weight: 700;
1257
+ letter-spacing: .08em;
1251
1258
  }
1252
1259
 
1253
1260
  /* ── HUD Panel ────────────────────────────────────────────── */
@@ -2150,6 +2157,20 @@ html[data-dock-pos="left"] .xfce-col-preview.visible {
2150
2157
  .xfce-pal-item-body { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
2151
2158
  .xfce-pal-snippet { font-size: 10px; color: var(--muted); font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2152
2159
 
2160
+ /* palette — recent entries */
2161
+ .xfce-pal-icon-sm { width: 20px; text-align: center; font-size: 10px; color: var(--muted); flex-shrink: 0; }
2162
+ .xfce-pal-group-sub {
2163
+ font-size: 8px; font-family: var(--mono); color: var(--line);
2164
+ letter-spacing: .08em; text-transform: uppercase;
2165
+ padding: 8px 14px 4px; border-top: 1px solid var(--line);
2166
+ }
2167
+ .xfce-pal-status {
2168
+ font-size: 9px; font-family: var(--mono); border-radius: 4px;
2169
+ padding: 1px 6px; border: 1px solid currentColor; white-space: nowrap;
2170
+ }
2171
+ .xfce-pal-status-published { color: var(--jade, #5dc97e); }
2172
+ .xfce-pal-status-draft { color: var(--muted); }
2173
+
2153
2174
  /* ── Status bar build indicator ──────────────────────────── */
2154
2175
  .xfce-sb-build { font-size: 9px; font-family: var(--mono); color: var(--muted); white-space: nowrap; }
2155
2176
  .xfce-sb-g-ind {
@@ -2196,6 +2217,71 @@ html[data-style="xfce"][data-dock-pos="left"] .xfce-ws-overlay {
2196
2217
  bottom: auto; left: 110px; top: 50%; transform: translateY(-50%);
2197
2218
  }
2198
2219
 
2220
+ /* ── Zen / Focus mode ────────────────────────────────────── */
2221
+ html[data-zen="1"] .xfce-sb {
2222
+ opacity: 0; pointer-events: none;
2223
+ transform: translateY(-100%);
2224
+ transition: opacity .3s, transform .3s;
2225
+ }
2226
+ html[data-zen="1"] .xfce-dock {
2227
+ opacity: 0; pointer-events: none;
2228
+ transform: translateY(30px);
2229
+ transition: opacity .3s, transform .3s;
2230
+ }
2231
+ html[data-zen="1"][data-dock-pos="left"] .xfce-dock {
2232
+ transform: translateX(-30px);
2233
+ }
2234
+ html[data-zen="1"] .main {
2235
+ padding-top: 8px !important;
2236
+ padding-bottom: 20px !important;
2237
+ }
2238
+
2239
+ /* ── Shortcut Cheatsheet ─────────────────────────────────── */
2240
+ .xfce-cheat-overlay {
2241
+ display: none; position: fixed; inset: 0;
2242
+ background: rgba(0,0,0,.55); backdrop-filter: blur(4px);
2243
+ z-index: 100001; align-items: center; justify-content: center;
2244
+ }
2245
+ .xfce-cheat-overlay.open { display: flex; }
2246
+ .xfce-cheat-panel {
2247
+ background: var(--bg1); border: 1px solid var(--line);
2248
+ border-radius: 14px; box-shadow: 0 16px 48px rgba(0,0,0,.55);
2249
+ width: 560px; max-width: calc(100vw - 40px); font-family: var(--mono);
2250
+ overflow: hidden;
2251
+ }
2252
+ .xfce-cheat-bar {
2253
+ display: flex; align-items: center; justify-content: space-between;
2254
+ padding: 12px 16px; border-bottom: 1px solid var(--line);
2255
+ background: var(--bg2);
2256
+ }
2257
+ .xfce-cheat-title { color: var(--accent); font-size: 11px; font-weight: 700; letter-spacing: .07em; }
2258
+ .xfce-cheat-close {
2259
+ background: none; border: none; color: var(--muted); cursor: pointer;
2260
+ font-size: 13px; line-height: 1; padding: 2px 4px;
2261
+ }
2262
+ .xfce-cheat-close:hover { color: var(--text); }
2263
+ .xfce-cheat-body {
2264
+ display: grid; grid-template-columns: 1fr 1fr; gap: 0;
2265
+ padding: 16px; gap: 0 24px; max-height: 70vh; overflow-y: auto;
2266
+ }
2267
+ .xfce-cheat-section {
2268
+ font-size: 9px; letter-spacing: .1em; color: var(--accent);
2269
+ text-transform: uppercase; font-weight: 700;
2270
+ margin-bottom: 8px; margin-top: 4px;
2271
+ }
2272
+ .xfce-cheat-row {
2273
+ display: flex; align-items: baseline; gap: 10px;
2274
+ padding: 3px 0; border-bottom: 1px solid rgba(255,255,255,.04);
2275
+ }
2276
+ .xfce-cheat-row:last-child { border-bottom: none; }
2277
+ .xfce-cheat-key {
2278
+ background: var(--bg2); border: 1px solid var(--line);
2279
+ border-radius: 4px; padding: 1px 6px; font-size: 10px;
2280
+ color: var(--accent); font-family: var(--mono); white-space: nowrap;
2281
+ flex-shrink: 0; min-width: 80px; text-align: center;
2282
+ }
2283
+ .xfce-cheat-desc { font-size: 10px; color: var(--text); }
2284
+
2199
2285
  /* ── Bell / Notification Center ─────────────────────────── */
2200
2286
  .xfce-sb-bell {
2201
2287
  background: none; border: none; cursor: pointer; padding: 0 2px;
package/public/xfce.js CHANGED
@@ -13,14 +13,14 @@
13
13
  var NAV = [
14
14
  { icon: '⬡', label: 'Dashboard', href: '/dashboard.html', key: 'dashboard' },
15
15
  { icon: '◫', label: 'Media', href: '/media.html', key: 'media' },
16
- { icon: '⚙', label: 'Settings', href: '/settings.html', key: 'settings' },
17
16
  { icon: '⊛', label: 'Users', href: '/users.html', key: 'users' },
18
17
  ];
19
18
 
20
19
  var TOOLS = [
21
- { icon: '▦', label: 'Schema', href: '/schema.html', key: 'schema' },
22
- { icon: '◉', label: 'Build', href: '/build.html', key: 'build' },
23
- { icon: '↓', label: 'Import', href: '/import.html', key: 'import' },
20
+ { icon: '▦', label: 'Schema', href: '/schema.html', key: 'schema' },
21
+ { icon: '◉', label: 'Build', href: '/build.html', key: 'build' },
22
+ { icon: '↓', label: 'Import', href: '/import.html', key: 'import' },
23
+ { icon: '⚙', label: 'Settings', href: '/settings.html', key: 'settings' },
24
24
  ];
25
25
 
26
26
  var WORKSPACE = [
@@ -30,9 +30,10 @@
30
30
 
31
31
  // palette items — nav + tools pre-seeded; collections appended after /api/info
32
32
  var _palItems = NAV.concat(TOOLS).map(function (n) {
33
- return { icon: n.icon, label: n.label, href: n.href, group: n.key in { schema:1, build:1, import:1 } ? 'Tools' : 'Nav' };
33
+ return { icon: n.icon, label: n.label, href: n.href, group: n.key in { schema:1, build:1, import:1, settings:1 } ? 'Tools' : 'Nav' };
34
34
  });
35
- var _termCols = []; // collection metadata for palette commands
35
+ var _termCols = []; // collection metadata for palette commands
36
+ var _palRecents = []; // prefetched recent entries for empty palette
36
37
 
37
38
  // ── Helpers ───────────────────────────────────────────────────────────
38
39
  function el(tag, cls, html) {
@@ -162,19 +163,12 @@
162
163
  function buildToolsPopup() {
163
164
  toolsPopup = el('div', 'xfce-tools-popup');
164
165
  toolsPopup.id = 'xfce-tools-popup';
165
- TOOLS.forEach(function (t) {
166
+ TOOLS.filter(function (t) { return t.key !== 'settings'; }).forEach(function (t) {
166
167
  var a = el('a', 'xfce-tools-item' + (page === t.key ? ' active' : ''));
167
168
  a.href = t.href;
168
169
  a.innerHTML = '<span class="xfce-tools-icon">' + t.icon + '</span><span>' + t.label + '</span>';
169
170
  toolsPopup.appendChild(a);
170
171
  });
171
- var settingsSep = document.createElement('div');
172
- settingsSep.className = 'xfce-tools-sep';
173
- toolsPopup.appendChild(settingsSep);
174
- var settingsLink = el('a', 'xfce-tools-item' + (page === 'settings' ? ' active' : ''));
175
- settingsLink.href = '/settings.html';
176
- settingsLink.innerHTML = '<span class="xfce-tools-icon">⚙</span><span>Settings</span>';
177
- toolsPopup.appendChild(settingsLink);
178
172
  var sep = document.createElement('div');
179
173
  sep.className = 'xfce-tools-sep';
180
174
  toolsPopup.appendChild(sep);
@@ -446,9 +440,55 @@
446
440
  }
447
441
 
448
442
  q = q.toLowerCase();
449
- var filtered = q
450
- ? _palItems.filter(function (it) { return it.label.toLowerCase().includes(q); })
451
- : _palItems;
443
+
444
+ // Empty input show recents + nav
445
+ if (!q) {
446
+ var html = '';
447
+ if (_palRecents.length) {
448
+ html += '<div class="xfce-pal-group">Recent</div>';
449
+ _palRecents.forEach(function (r) {
450
+ var href = '/collections/' + encodeURIComponent(r.collection) + '/entries/' + encodeURIComponent(r.slug);
451
+ html += '<div class="xfce-pal-item" data-href="' + href + '">'
452
+ + '<span class="xfce-pal-icon xfce-pal-icon-sm">◈</span>'
453
+ + '<div class="xfce-pal-item-body">'
454
+ + '<span class="xfce-pal-label">' + escHtml(r.title || r.slug) + '</span>'
455
+ + '<span class="xfce-pal-snippet">' + escHtml(r.label) + '</span>'
456
+ + '</div>'
457
+ + '<span class="xfce-pal-hint-r xfce-pal-status xfce-pal-status-' + r.status + '">' + r.status + '</span>'
458
+ + '</div>';
459
+ });
460
+ html += '<div class="xfce-pal-group">Navigation</div>';
461
+ }
462
+ var navGroups = {};
463
+ _palItems.forEach(function (it) {
464
+ var g = it.group || 'Nav';
465
+ if (!navGroups[g]) navGroups[g] = [];
466
+ navGroups[g].push(it);
467
+ });
468
+ Object.keys(navGroups).forEach(function (g) {
469
+ if (_palRecents.length) html += '<div class="xfce-pal-group-sub">' + g + '</div>';
470
+ else html += '<div class="xfce-pal-group">' + g + '</div>';
471
+ navGroups[g].forEach(function (it) {
472
+ html += '<div class="xfce-pal-item" data-href="' + it.href + '">'
473
+ + '<span class="xfce-pal-icon">' + it.icon + '</span>'
474
+ + '<span class="xfce-pal-label">' + escHtml(it.label) + '</span>'
475
+ + (it.meta ? '<span class="xfce-pal-hint-r">' + escHtml(it.meta) + '</span>' : '')
476
+ + '</div>';
477
+ });
478
+ });
479
+ paletteResults.innerHTML = html;
480
+ paletteResults.querySelectorAll('.xfce-pal-item[data-href]').forEach(function (item) {
481
+ item.addEventListener('click', function () { location.href = item.dataset.href; closePalette(); });
482
+ item.addEventListener('mouseenter', function () {
483
+ var items = paletteResults.querySelectorAll('.xfce-pal-item[data-href]');
484
+ palActive = Array.from(items).indexOf(item);
485
+ updatePalActive(items);
486
+ });
487
+ });
488
+ return;
489
+ }
490
+
491
+ var filtered = _palItems.filter(function (it) { return it.label.toLowerCase().includes(q); });
452
492
 
453
493
  if (!filtered.length) {
454
494
  paletteResults.innerHTML = '<div class="xfce-pal-empty">No results</div>';
@@ -1173,6 +1213,9 @@
1173
1213
  });
1174
1214
  dockInner.appendChild(toolsBtn);
1175
1215
 
1216
+ var settingsDockBtn = makeDockItem('⚙', 'Settings', '/settings.html', page === 'settings', false);
1217
+ dockInner.appendChild(settingsDockBtn);
1218
+
1176
1219
  dockInner.appendChild(el('div', 'xfce-dock-sep'));
1177
1220
 
1178
1221
  // HUD toggle
@@ -1336,12 +1379,98 @@
1336
1379
  if (sbUser) sbUser.textContent = d.user.username;
1337
1380
  })
1338
1381
  .catch(function () {});
1382
+
1383
+ // Prefetch recent entries for palette empty state
1384
+ fetch('/api/search/recent?limit=7', { credentials: 'include' })
1385
+ .then(function (r) { return r.ok ? r.json() : []; })
1386
+ .then(function (rows) { _palRecents = rows; })
1387
+ .catch(function () {});
1339
1388
  }
1340
1389
 
1341
1390
  function hudRow(label, value) {
1342
1391
  return '<div class="xfce-hud-row"><span>' + label + '</span><span>' + value + '</span></div>';
1343
1392
  }
1344
1393
 
1394
+ // ── Zen / Focus mode ─────────────────────────────────────────────────
1395
+ function toggleZen() {
1396
+ var html = document.documentElement;
1397
+ var on = html.dataset.zen !== '1';
1398
+ html.dataset.zen = on ? '1' : '';
1399
+ localStorage.setItem('orb_zen', on ? '1' : '');
1400
+ if (on) window.xfceToast('Focus mode on — ⌘⇧F to exit', 'info');
1401
+ }
1402
+
1403
+ // ── Shortcut cheatsheet ───────────────────────────────────────────────
1404
+ var _cheatEl = null;
1405
+
1406
+ function buildCheatsheet() {
1407
+ _cheatEl = el('div', 'xfce-cheat-overlay');
1408
+ _cheatEl.id = 'xfce-cheat';
1409
+ _cheatEl.innerHTML = [
1410
+ '<div class="xfce-cheat-panel">',
1411
+ '<div class="xfce-cheat-bar">',
1412
+ '<span class="xfce-cheat-title">⌨ Shortcuts</span>',
1413
+ '<button class="xfce-cheat-close" id="xfce-cheat-close">✕</button>',
1414
+ '</div>',
1415
+ '<div class="xfce-cheat-body">',
1416
+ '<div class="xfce-cheat-col">',
1417
+ '<div class="xfce-cheat-section">Navigation</div>',
1418
+ cheatRow('⌘K &nbsp;/&nbsp; /', 'Open command palette'),
1419
+ cheatRow('↑ ↓', 'Move selection in palette'),
1420
+ cheatRow('↵', 'Go to selected item'),
1421
+ cheatRow('Esc', 'Close overlay / panel'),
1422
+ cheatRow('g &nbsp;+&nbsp; d', 'Dashboard'),
1423
+ cheatRow('g &nbsp;+&nbsp; m', 'Media'),
1424
+ cheatRow('g &nbsp;+&nbsp; u', 'Users'),
1425
+ cheatRow('g &nbsp;+&nbsp; s', 'Settings'),
1426
+ cheatRow('g &nbsp;+&nbsp; b', 'Build'),
1427
+ cheatRow('g &nbsp;+&nbsp; i', 'Import'),
1428
+ cheatRow('g &nbsp;+&nbsp; h', 'Schema'),
1429
+ cheatRow('g &nbsp;+&nbsp; a', 'Account'),
1430
+ cheatRow('1 – 9', 'Jump to nth dock item'),
1431
+ '</div>',
1432
+ '<div class="xfce-cheat-col">',
1433
+ '<div class="xfce-cheat-section">Panels</div>',
1434
+ cheatRow('⌘⇧D', 'Toggle HUD'),
1435
+ cheatRow('⌘⇧F', 'Focus / Zen mode'),
1436
+ cheatRow('⌘⇧L', 'Switch to Glass mode'),
1437
+ cheatRow('?', 'This cheatsheet'),
1438
+ '<div class="xfce-cheat-section" style="margin-top:14px">Palette commands</div>',
1439
+ cheatRow('&gt; ls', 'List collections'),
1440
+ cheatRow('&gt; go &lt;page&gt;', 'Navigate to page'),
1441
+ cheatRow('&gt; new &lt;col&gt;', 'New entry in collection'),
1442
+ cheatRow('&gt; search &lt;q&gt;', 'Search entries'),
1443
+ cheatRow('&gt; build', 'Trigger site build'),
1444
+ cheatRow('&gt; export &lt;col&gt;', 'Export collection'),
1445
+ cheatRow('&gt; info', 'Show pod info'),
1446
+ cheatRow('&gt; help', 'Show command help'),
1447
+ '</div>',
1448
+ '</div>',
1449
+ '</div>',
1450
+ ].join('');
1451
+ document.body.appendChild(_cheatEl);
1452
+ document.getElementById('xfce-cheat-close').addEventListener('click', closeCheatsheet);
1453
+ _cheatEl.addEventListener('click', function (e) {
1454
+ if (e.target === _cheatEl) closeCheatsheet();
1455
+ });
1456
+ document.addEventListener('keydown', function (e) {
1457
+ if (e.key === 'Escape' && _cheatEl && _cheatEl.classList.contains('open')) closeCheatsheet();
1458
+ });
1459
+ }
1460
+
1461
+ function cheatRow(key, desc) {
1462
+ return '<div class="xfce-cheat-row"><kbd class="xfce-cheat-key">' + key + '</kbd><span class="xfce-cheat-desc">' + desc + '</span></div>';
1463
+ }
1464
+
1465
+ function toggleCheatsheet() {
1466
+ if (!_cheatEl) buildCheatsheet();
1467
+ _cheatEl.classList.toggle('open');
1468
+ }
1469
+
1470
+ function closeCheatsheet() {
1471
+ if (_cheatEl) _cheatEl.classList.remove('open');
1472
+ }
1473
+
1345
1474
  // ── Keyboard shortcuts ────────────────────────────────────────────────
1346
1475
  var _gPending = false, _gTimer = null;
1347
1476
  var G_MAP = { d: '/dashboard.html', m: '/media.html', s: '/settings.html',
@@ -1403,6 +1532,13 @@
1403
1532
  return;
1404
1533
  }
1405
1534
 
1535
+ // ⌘⇧F — zen / focus mode
1536
+ if (mod && e.shiftKey && (e.key === 'f' || e.key === 'F')) {
1537
+ e.preventDefault();
1538
+ toggleZen();
1539
+ return;
1540
+ }
1541
+
1406
1542
  // ⌘⇧L — switch back to glass mode
1407
1543
  if (mod && e.shiftKey && (e.key === 'l' || e.key === 'L')) {
1408
1544
  e.preventDefault();
@@ -1411,6 +1547,13 @@
1411
1547
  return;
1412
1548
  }
1413
1549
 
1550
+ // ? — shortcut cheatsheet
1551
+ if (!mod && !e.altKey && e.key === '?' && !isEditing(e.target)) {
1552
+ e.preventDefault();
1553
+ toggleCheatsheet();
1554
+ return;
1555
+ }
1556
+
1414
1557
  // 1–9 — jump to nth dock link (no modifier, not in input)
1415
1558
  if (!mod && !e.shiftKey && !e.altKey && !isEditing(e.target)) {
1416
1559
  var n = parseInt(e.key);
@@ -1463,6 +1606,9 @@
1463
1606
  bindKeys();
1464
1607
  initFocusMode();
1465
1608
  observeSavedFlash();
1609
+ if (localStorage.getItem('orb_zen') === '1') {
1610
+ document.documentElement.dataset.zen = '1';
1611
+ }
1466
1612
  }
1467
1613
 
1468
1614
  if (document.readyState === 'loading') {