@lifeaitools/clauth 1.5.83 → 1.5.84
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/cli/commands/serve.js +57 -16
- package/package.json +1 -1
package/cli/commands/serve.js
CHANGED
|
@@ -607,9 +607,14 @@ function dashboardHtml(port, whitelist, isStaged = false) {
|
|
|
607
607
|
.project-tab{background:none;border:none;border-bottom:2px solid transparent;color:#64748b;padding:8px 16px;font-size:.82rem;font-weight:500;cursor:pointer;white-space:nowrap;transition:all .15s}
|
|
608
608
|
.project-tab:hover{color:#94a3b8;background:rgba(59,130,246,.05)}
|
|
609
609
|
.project-tab.active{color:#60a5fa;border-bottom-color:#3b82f6;background:rgba(59,130,246,.08)}
|
|
610
|
-
.project-tab .tab-count{font-size:.7rem;color:#475569;margin-left:4px;font-weight:400}
|
|
611
|
-
.project-tab.active .tab-count{color:#3b82f6}
|
|
612
|
-
.
|
|
610
|
+
.project-tab .tab-count{font-size:.7rem;color:#475569;margin-left:4px;font-weight:400}
|
|
611
|
+
.project-tab.active .tab-count{color:#3b82f6}
|
|
612
|
+
.service-search{display:flex;align-items:center;gap:10px;margin:-.35rem 0 1rem;background:#0f172a;border:1px solid #1e293b;border-radius:8px;padding:9px 12px}
|
|
613
|
+
.service-search-label{font-size:.76rem;color:#64748b;font-weight:600;letter-spacing:.02em;text-transform:uppercase;white-space:nowrap}
|
|
614
|
+
.service-search-input{flex:1;min-width:180px;background:#0a0f1a;border:1px solid #334155;border-radius:6px;color:#e2e8f0;font-family:'Courier New',monospace;font-size:.88rem;padding:8px 11px;outline:none;transition:border-color .15s}
|
|
615
|
+
.service-search-input:focus{border-color:#3b82f6}
|
|
616
|
+
.service-search-count{font-size:.78rem;color:#64748b;white-space:nowrap}
|
|
617
|
+
.project-edit{display:none;margin-top:8px;padding:8px 10px;background:#0f172a;border:1px solid #334155;border-radius:6px}
|
|
613
618
|
.project-edit.open{display:flex;gap:6px;align-items:center}
|
|
614
619
|
.project-edit input{background:#1e293b;border:1px solid #334155;border-radius:4px;color:#e2e8f0;font-size:.78rem;padding:4px 8px;outline:none;flex:1;font-family:'Courier New',monospace;transition:border-color .15s}
|
|
615
620
|
.project-edit input:focus{border-color:#3b82f6}
|
|
@@ -863,8 +868,13 @@ function dashboardHtml(port, whitelist, isStaged = false) {
|
|
|
863
868
|
<div class="wizard-foot" id="wizard-foot"></div>
|
|
864
869
|
</div>
|
|
865
870
|
|
|
866
|
-
<div id="project-tabs" class="project-tabs" style="display:none"></div>
|
|
867
|
-
<div id="
|
|
871
|
+
<div id="project-tabs" class="project-tabs" style="display:none"></div>
|
|
872
|
+
<div id="service-search" class="service-search">
|
|
873
|
+
<span class="service-search-label">Search</span>
|
|
874
|
+
<input id="service-search-input" class="service-search-input" type="search" placeholder="service name or display name" autocomplete="off" spellcheck="false" oninput="setServiceSearch(this.value)">
|
|
875
|
+
<span id="service-search-count" class="service-search-count"></span>
|
|
876
|
+
</div>
|
|
877
|
+
<div id="grid" class="grid"><p class="loading">Loading services…</p></div>
|
|
868
878
|
<div class="footer">localhost:${port} · 127.0.0.1 only · 10-strike lockout</div>
|
|
869
879
|
</div>
|
|
870
880
|
|
|
@@ -1158,8 +1168,25 @@ async function stopDaemon() {
|
|
|
1158
1168
|
}
|
|
1159
1169
|
|
|
1160
1170
|
// ── Load services ───────────────────────────
|
|
1161
|
-
let allServices = [];
|
|
1162
|
-
let activeProjectTab = "all";
|
|
1171
|
+
let allServices = [];
|
|
1172
|
+
let activeProjectTab = "all";
|
|
1173
|
+
let serviceSearchQuery = "";
|
|
1174
|
+
|
|
1175
|
+
function serviceSort(a, b) {
|
|
1176
|
+
return String(a.name || "").localeCompare(String(b.name || ""), undefined, { sensitivity: "base", numeric: true });
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
function matchesServiceSearch(s, query) {
|
|
1180
|
+
if (!query) return true;
|
|
1181
|
+
const q = query.toLowerCase();
|
|
1182
|
+
return String(s.name || "").toLowerCase().includes(q) ||
|
|
1183
|
+
String(s.label || "").toLowerCase().includes(q);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
function setServiceSearch(value) {
|
|
1187
|
+
serviceSearchQuery = value || "";
|
|
1188
|
+
renderServiceGrid(allServices);
|
|
1189
|
+
}
|
|
1163
1190
|
|
|
1164
1191
|
function renderProjectTabs(services) {
|
|
1165
1192
|
const tabsEl = document.getElementById("project-tabs");
|
|
@@ -1185,21 +1212,35 @@ function renderProjectTabs(services) {
|
|
|
1185
1212
|
).join("");
|
|
1186
1213
|
}
|
|
1187
1214
|
|
|
1188
|
-
function switchProjectTab(key) {
|
|
1189
|
-
activeProjectTab = key;
|
|
1190
|
-
renderProjectTabs(allServices);
|
|
1191
|
-
renderServiceGrid(allServices);
|
|
1192
|
-
}
|
|
1215
|
+
function switchProjectTab(key) {
|
|
1216
|
+
activeProjectTab = key;
|
|
1217
|
+
renderProjectTabs(allServices);
|
|
1218
|
+
renderServiceGrid(allServices);
|
|
1219
|
+
}
|
|
1193
1220
|
|
|
1194
1221
|
function renderServiceGrid(services) {
|
|
1195
1222
|
const grid = document.getElementById("grid");
|
|
1196
1223
|
let filtered = services;
|
|
1197
1224
|
if (activeProjectTab === "unassigned") {
|
|
1198
1225
|
filtered = services.filter(s => !s.project);
|
|
1199
|
-
} else if (activeProjectTab !== "all") {
|
|
1200
|
-
filtered = services.filter(s => s.project === activeProjectTab);
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1226
|
+
} else if (activeProjectTab !== "all") {
|
|
1227
|
+
filtered = services.filter(s => s.project === activeProjectTab);
|
|
1228
|
+
}
|
|
1229
|
+
filtered = filtered
|
|
1230
|
+
.filter(s => matchesServiceSearch(s, serviceSearchQuery))
|
|
1231
|
+
.slice()
|
|
1232
|
+
.sort(serviceSort);
|
|
1233
|
+
const searchCount = document.getElementById("service-search-count");
|
|
1234
|
+
if (searchCount) {
|
|
1235
|
+
const trimmed = serviceSearchQuery.trim();
|
|
1236
|
+
searchCount.textContent = trimmed ? filtered.length + " match" + (filtered.length === 1 ? "" : "es") : filtered.length + " shown";
|
|
1237
|
+
}
|
|
1238
|
+
if (!filtered.length) {
|
|
1239
|
+
grid.innerHTML = serviceSearchQuery.trim()
|
|
1240
|
+
? '<p class="loading">No services match that search.</p>'
|
|
1241
|
+
: '<p class="loading">No services in this group.</p>';
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1203
1244
|
grid.innerHTML = filtered.map(s => \`
|
|
1204
1245
|
<div class="card">
|
|
1205
1246
|
<div style="display:flex;align-items:flex-start;justify-content:space-between">
|