@memtensor/memos-local-openclaw-plugin 1.0.7 → 1.0.8-beta.2
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/.env.example +4 -0
- package/index.ts +74 -49
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -3
- package/scripts/postinstall.cjs +59 -25
- package/skill/memos-memory-guide/SKILL.md +5 -2
- package/src/ingest/providers/index.ts +14 -1
- package/src/recall/engine.ts +1 -1
- package/src/shared/llm-call.ts +14 -1
- package/src/storage/sqlite.ts +150 -6
- package/src/viewer/html.ts +779 -220
- package/src/viewer/server.ts +189 -8
- package/prebuilds/darwin-arm64/better_sqlite3.node +0 -0
- package/prebuilds/darwin-x64/better_sqlite3.node +0 -0
- package/prebuilds/linux-x64/better_sqlite3.node +0 -0
- package/prebuilds/win32-x64/better_sqlite3.node +0 -0
- package/telemetry.credentials.json +0 -5
package/src/viewer/html.ts
CHANGED
|
@@ -126,19 +126,25 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
126
126
|
.main-content{display:flex;flex:1;max-width:1400px;margin:0 auto;width:100%;padding:28px 32px;gap:28px}
|
|
127
127
|
|
|
128
128
|
/* ─── Sidebar ─── */
|
|
129
|
-
.sidebar{width:260px;min-width:260px;flex-shrink:0}
|
|
130
|
-
.sidebar
|
|
131
|
-
.
|
|
129
|
+
.sidebar{width:260px;min-width:260px;flex-shrink:0;position:sticky;top:84px;max-height:calc(100vh - 112px);display:flex;flex-direction:column}
|
|
130
|
+
.sidebar > * {flex-shrink:0}
|
|
131
|
+
.sidebar .stats-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:20px}
|
|
132
|
+
.stat-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;transition:all .2s;position:relative;overflow:hidden}
|
|
133
|
+
.stat-card::before{content:'';position:absolute;top:0;left:0;bottom:0;width:3px;border-radius:3px 0 0 3px;background:var(--border)}
|
|
132
134
|
.stat-card:hover{border-color:var(--border-glow);background:var(--bg-card-hover)}
|
|
133
|
-
.stat-card .stat-value{font-size:
|
|
134
|
-
.stat-card .stat-label{font-size:
|
|
135
|
+
.stat-card .stat-value{font-size:20px;font-weight:700;color:var(--text);letter-spacing:-.02em}
|
|
136
|
+
.stat-card .stat-label{font-size:11px;color:var(--text-sec);margin-top:2px;font-weight:500}
|
|
137
|
+
.stat-card.pri{border-left-color:transparent}.stat-card.pri::before{background:var(--pri)}
|
|
135
138
|
.stat-card.pri .stat-value{color:var(--pri)}
|
|
139
|
+
.stat-card.green{border-left-color:transparent}.stat-card.green::before{background:var(--green)}
|
|
136
140
|
.stat-card.green .stat-value{color:var(--green)}
|
|
141
|
+
.stat-card.amber{border-left-color:transparent}.stat-card.amber::before{background:var(--amber)}
|
|
137
142
|
.stat-card.amber .stat-value{color:var(--amber)}
|
|
143
|
+
.stat-card.rose{border-left-color:transparent}.stat-card.rose::before{background:var(--rose)}
|
|
138
144
|
.stat-card.rose .stat-value{color:var(--rose)}
|
|
139
145
|
|
|
140
146
|
.sidebar .section-title{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em;margin:24px 0 12px;padding:0 2px}
|
|
141
|
-
.sidebar .session-list{display:flex;flex-direction:column;gap:6px;
|
|
147
|
+
.sidebar .session-list{display:flex;flex-direction:column;gap:6px;flex:1;min-height:0;overflow-y:auto;padding-right:4px;flex-shrink:1}
|
|
142
148
|
.session-item{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;cursor:pointer;transition:all .15s;font-size:13px;color:var(--text)}
|
|
143
149
|
.session-item:hover{border-color:var(--pri);background:var(--pri-glow)}
|
|
144
150
|
.session-item.active{border-color:var(--pri);background:var(--pri-glow);font-weight:600;color:var(--pri)}
|
|
@@ -149,11 +155,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
149
155
|
|
|
150
156
|
/* ─── Feed ─── */
|
|
151
157
|
.feed{flex:1;min-width:0}
|
|
152
|
-
.search-bar{display:flex;gap:10px;margin-bottom:
|
|
158
|
+
.search-bar{display:flex;gap:10px;margin-bottom:14px;position:relative;align-items:center}
|
|
153
159
|
.search-bar input{flex:1;padding:10px 16px 10px 40px;border:1px solid var(--border);border-radius:10px;font-size:14px;outline:none;background:var(--bg-card);color:var(--text);transition:all .2s}
|
|
154
160
|
.search-bar input::placeholder{color:var(--text-muted)}
|
|
155
161
|
.search-bar input:focus{border-color:var(--pri);box-shadow:0 0 0 3px var(--pri-glow)}
|
|
156
162
|
.search-bar .search-icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:14px;pointer-events:none}
|
|
163
|
+
.search-bar .filter-select{padding:8px 14px;padding-right:30px;border-radius:10px;font-size:13px;background:var(--bg-card);flex-shrink:0}
|
|
157
164
|
.search-meta{font-size:12px;color:var(--text-sec);padding:0 2px}.search-meta:not(:empty){margin-bottom:14px}
|
|
158
165
|
.scope-select{padding:10px 12px;border:1px solid var(--border);border-radius:10px;background:var(--bg-card);color:var(--text);font-size:13px;min-width:110px;outline:none}
|
|
159
166
|
.sharing-inline-meta{font-size:12px;color:var(--text-muted);margin:-8px 0 14px 2px}
|
|
@@ -370,13 +377,13 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
370
377
|
.hub-source-badge{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:999px;background:rgba(34,197,94,.12);color:var(--green);font-size:11px;font-weight:700;border:1px solid rgba(34,197,94,.22)}
|
|
371
378
|
@media (max-width: 960px){.sharing-settings-grid{grid-template-columns:1fr}.search-bar{flex-wrap:wrap}.scope-select{width:100%}.task-detail-actions{width:100%;justify-content:flex-start}}
|
|
372
379
|
|
|
373
|
-
.filter-bar{display:flex;gap:8px;margin-bottom:
|
|
374
|
-
.filter-chip{padding:5px 14px;border:1px solid var(--border);border-radius:
|
|
375
|
-
.filter-chip:hover{border-color:var(--pri);color:var(--pri)}
|
|
376
|
-
.filter-chip.active{background:rgba(99,102,241,.
|
|
380
|
+
.filter-bar{display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;align-items:center}
|
|
381
|
+
.filter-chip{padding:5px 14px;border:1px solid var(--border);border-radius:8px;background:transparent;color:var(--text-sec);font-size:12px;font-weight:500;cursor:pointer;transition:all .15s}
|
|
382
|
+
.filter-chip:hover{border-color:var(--pri);color:var(--pri);background:rgba(99,102,241,.04)}
|
|
383
|
+
.filter-chip.active{background:rgba(99,102,241,.1);color:var(--pri);border-color:rgba(99,102,241,.3);font-weight:600}
|
|
377
384
|
|
|
378
|
-
.memory-list{display:flex;flex-direction:column;gap:
|
|
379
|
-
.memory-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius
|
|
385
|
+
.memory-list{display:flex;flex-direction:column;gap:10px}
|
|
386
|
+
.memory-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;transition:all .2s}
|
|
380
387
|
.memory-card:hover{border-color:var(--border-glow);background:var(--bg-card-hover)}
|
|
381
388
|
.memory-card .card-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;flex-wrap:wrap;gap:8px}
|
|
382
389
|
.memory-card .meta{display:flex;align-items:center;gap:8px}
|
|
@@ -392,6 +399,13 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
392
399
|
.card-content pre{white-space:pre-wrap;word-break:break-all;background:rgba(0,0,0,.25);padding:14px;border-radius:10px;font-size:12px;font-family:ui-monospace,monospace;margin-top:10px;border:1px solid var(--border);color:var(--text-sec)}
|
|
393
400
|
.card-actions{display:flex;align-items:center;gap:8px;margin-top:14px}
|
|
394
401
|
.card-actions-inline{display:inline-flex;align-items:center;gap:4px;margin-left:auto;flex-shrink:0}
|
|
402
|
+
.btn-warn{color:#f59e0b !important}
|
|
403
|
+
.btn-warn:hover{background:rgba(245,158,11,.15) !important}
|
|
404
|
+
.btn-danger{color:#ef4444 !important}
|
|
405
|
+
.btn-danger:hover{background:rgba(239,68,68,.15) !important}
|
|
406
|
+
.btn-success{color:#10b981 !important}
|
|
407
|
+
.btn-success:hover{background:rgba(16,185,129,.15) !important}
|
|
408
|
+
.skill-card.archived{opacity:0.55;border-style:dashed}
|
|
395
409
|
.vscore-badge{display:inline-flex;align-items:center;background:rgba(59,130,246,.15);color:#60a5fa;font-size:10px;font-weight:700;padding:4px 10px;border-radius:8px;margin-left:auto}
|
|
396
410
|
.merge-badge{display:inline-flex;align-items:center;gap:4px;background:rgba(16,185,129,.12);color:#10b981;font-size:10px;font-weight:600;padding:3px 10px;border-radius:8px}
|
|
397
411
|
.merge-history{margin-top:12px;padding:12px 14px;background:rgba(0,0,0,.15);border-radius:10px;border:1px solid var(--border);font-size:12px;line-height:1.7;color:var(--text-sec);max-height:200px;overflow-y:auto}
|
|
@@ -573,32 +587,39 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
573
587
|
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);border-radius:3px}
|
|
574
588
|
::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.25)}
|
|
575
589
|
|
|
576
|
-
.filter-sep{width:1px;height:20px;background:var(--border);margin:0
|
|
577
|
-
.filter-select{padding:
|
|
578
|
-
.filter-select:
|
|
590
|
+
.filter-sep{width:1px;height:20px;background:var(--border);margin:0 2px}
|
|
591
|
+
.filter-select{padding:5px 14px;border:1px solid var(--border);border-radius:8px;background:transparent;color:var(--text-sec);font-size:12px;font-weight:500;outline:none;cursor:pointer;transition:all .15s;-webkit-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236b7280'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px}
|
|
592
|
+
.filter-select:hover{border-color:var(--pri);color:var(--pri)}
|
|
593
|
+
.filter-select:focus{border-color:var(--pri);color:var(--pri);background-color:rgba(99,102,241,.04)}
|
|
579
594
|
.date-filter{display:flex;align-items:center;gap:10px;margin-bottom:18px;font-size:13px;color:var(--text-sec)}
|
|
580
|
-
.date-filter input[type="datetime-local"]{padding:
|
|
595
|
+
.date-filter input[type="datetime-local"]{padding:5px 12px;border:1px solid var(--border);border-radius:8px;font-size:12px;outline:none;background:transparent;color:var(--text-sec);transition:all .15s}
|
|
581
596
|
.date-filter input[type="datetime-local"]:focus{border-color:var(--pri)}
|
|
582
597
|
.date-filter label{font-weight:500}
|
|
583
|
-
|
|
584
|
-
.
|
|
585
|
-
.
|
|
586
|
-
.
|
|
587
|
-
|
|
588
|
-
.pagination
|
|
589
|
-
.pagination
|
|
598
|
+
.compact-filter-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
599
|
+
.compact-date{padding:5px 12px;border:1px solid var(--border);border-radius:8px;font-size:12px;font-weight:500;outline:none;background:transparent;color:var(--text-sec);max-width:180px;transition:all .15s}
|
|
600
|
+
.compact-date:hover{border-color:var(--pri);color:var(--pri)}
|
|
601
|
+
.compact-date:focus{border-color:var(--pri);color:var(--pri);background:rgba(99,102,241,.04)}
|
|
602
|
+
|
|
603
|
+
.pagination-row{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;padding:16px 0 8px}
|
|
604
|
+
.pagination{display:flex;align-items:center;justify-content:center;gap:4px;padding:0;flex-wrap:wrap}
|
|
605
|
+
.pagination .pg-btn{min-width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--text-sec);font-size:12px;font-weight:500;cursor:pointer;transition:all .15s}
|
|
606
|
+
.pagination .pg-btn:hover{background:rgba(99,102,241,.06);color:var(--pri);border-color:rgba(99,102,241,.15)}
|
|
607
|
+
.pagination .pg-btn.active{background:var(--pri-grad);color:#fff;border-color:transparent;box-shadow:0 2px 8px rgba(99,102,241,.3)}
|
|
608
|
+
.pagination .pg-btn.disabled{opacity:.3;pointer-events:none}
|
|
609
|
+
.pagination .pg-info{font-size:11px;color:var(--text-muted);padding:0 8px}
|
|
590
610
|
|
|
591
611
|
/* ─── Tasks 视图 ─── */
|
|
592
612
|
.view-container{flex:1;min-width:0}
|
|
593
613
|
.view-container>.vp{display:none;flex-direction:column}
|
|
594
614
|
.view-container>.vp.show{display:flex}
|
|
595
|
-
.tasks-view{flex:1;min-width:0;flex-direction:column
|
|
596
|
-
.tasks-header{display:flex;flex-direction:column;gap:
|
|
597
|
-
.tasks-stats{display:flex;gap:
|
|
598
|
-
.tasks-stat{display:flex;align-items:center;gap:8px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:
|
|
615
|
+
.tasks-view{flex:1;min-width:0;flex-direction:column}
|
|
616
|
+
.tasks-header{display:flex;flex-direction:column;gap:0}
|
|
617
|
+
.tasks-stats{display:flex;gap:10px}
|
|
618
|
+
.tasks-stat{display:flex;align-items:center;gap:8px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:10px 16px;flex:1;transition:all .2s;position:relative;overflow:hidden}
|
|
619
|
+
.tasks-stat::before{content:'';position:absolute;top:0;left:0;bottom:0;width:3px;border-radius:3px 0 0 3px}
|
|
599
620
|
.tasks-stat:hover{border-color:var(--border-glow)}
|
|
600
|
-
.tasks-stat-value{font-size:
|
|
601
|
-
.tasks-stat-label{font-size:
|
|
621
|
+
.tasks-stat-value{font-size:18px;font-weight:700;color:var(--text)}
|
|
622
|
+
.tasks-stat-label{font-size:11px;color:var(--text-sec);font-weight:500}
|
|
602
623
|
.tasks-filters{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
|
|
603
624
|
.tasks-list{display:flex;flex-direction:column;gap:10px}
|
|
604
625
|
.task-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:18px 20px;cursor:pointer;transition:all .25s;position:relative;overflow:hidden}
|
|
@@ -670,7 +691,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
670
691
|
[data-theme="light"] .tasks-stat{background:#fff}
|
|
671
692
|
|
|
672
693
|
/* ─── Skills ─── */
|
|
673
|
-
.skills-view{flex:1;min-width:0;flex-direction:column
|
|
694
|
+
.skills-view{flex:1;min-width:0;flex-direction:column}
|
|
674
695
|
.skill-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:18px 20px;cursor:pointer;transition:all .25s;position:relative;overflow:hidden}
|
|
675
696
|
.skill-card:hover{border-color:var(--border-glow);background:var(--bg-card-hover);transform:translateY(-1px);box-shadow:var(--shadow)}
|
|
676
697
|
.skill-card::before{content:'';position:absolute;top:0;left:0;bottom:0;width:3px;border-radius:3px 0 0 3px;background:var(--violet)}
|
|
@@ -697,6 +718,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
697
718
|
.skill-card-bottom .tag{display:flex;align-items:center;gap:4px}
|
|
698
719
|
.skill-card-tags{display:flex;gap:4px;flex-wrap:wrap}
|
|
699
720
|
.skill-tag{font-size:10px;padding:2px 8px;border-radius:10px;background:rgba(139,92,246,.1);color:var(--violet);font-weight:500}
|
|
721
|
+
.selection-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
722
|
+
#memorySelectionToolbar{margin-bottom:16px}
|
|
723
|
+
.item-select-box{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:5px;border:1px solid var(--border);background:var(--bg-card);cursor:pointer;margin-right:8px;vertical-align:middle}
|
|
724
|
+
.item-select-box input{width:14px;height:14px;cursor:pointer}
|
|
700
725
|
.skill-detail-desc{font-size:13px;color:var(--text-sec);line-height:1.6;margin-bottom:16px;padding:12px 16px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius)}
|
|
701
726
|
.skill-version-item{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px}
|
|
702
727
|
.skill-version-header{display:flex;align-items:center;gap:10px;margin-bottom:6px}
|
|
@@ -1225,8 +1250,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1225
1250
|
<div class="sidebar" id="sidebar">
|
|
1226
1251
|
<div class="stats-grid" id="statsGrid">
|
|
1227
1252
|
<div class="stat-card pri"><div class="stat-value" id="statTotal">-</div><div class="stat-label" data-i18n="stat.memories">Memories</div></div>
|
|
1228
|
-
<div class="stat-card green"><div class="stat-value" id="
|
|
1229
|
-
<div class="stat-card amber"><div class="stat-value" id="
|
|
1253
|
+
<div class="stat-card green"><div class="stat-value" id="statTasks">-</div><div class="stat-label" data-i18n="stat.tasks">Tasks</div></div>
|
|
1254
|
+
<div class="stat-card amber"><div class="stat-value" id="statSkills">-</div><div class="stat-label" data-i18n="stat.skills">Skills</div></div>
|
|
1230
1255
|
<div class="stat-card rose"><div class="stat-value" id="statAgents">-</div><div class="stat-label" data-i18n="stat.agents">Agents</div></div>
|
|
1231
1256
|
</div>
|
|
1232
1257
|
<div id="sidebarSharingSection" style="display:none">
|
|
@@ -1237,8 +1262,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1237
1262
|
</div>
|
|
1238
1263
|
</div>
|
|
1239
1264
|
<div id="embeddingStatus"></div>
|
|
1265
|
+
<button class="btn btn-sm btn-ghost" style="width:100%;margin:20px 0 12px;justify-content:center;color:var(--text-muted);font-size:11px" onclick="clearAll()" data-i18n="sidebar.clear">\u{1F5D1} Clear All Data</button>
|
|
1240
1266
|
<div class="session-list" id="sessionList" style="display:none"></div>
|
|
1241
|
-
<button class="btn btn-sm btn-ghost" style="width:100%;margin-top:20px;justify-content:center;color:var(--text-muted);font-size:11px" onclick="clearAll()" data-i18n="sidebar.clear">\u{1F5D1} Clear All Data</button>
|
|
1242
1267
|
</div>
|
|
1243
1268
|
|
|
1244
1269
|
<div class="view-container">
|
|
@@ -1251,14 +1276,13 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1251
1276
|
<option value="" data-i18n="filter.allagents">All agents</option>
|
|
1252
1277
|
</select>
|
|
1253
1278
|
<select id="memorySearchScope" class="filter-select" onchange="onMemoryScopeChange()" style="display:none">
|
|
1254
|
-
<option value="local" data-i18n="scope.thisAgent">This Agent</option>
|
|
1255
1279
|
<option value="allLocal" data-i18n="scope.thisDevice">This Device</option>
|
|
1256
1280
|
<option value="hub" data-i18n="scope.hub">Team</option>
|
|
1257
1281
|
</select>
|
|
1258
1282
|
</div>
|
|
1259
|
-
<div
|
|
1260
|
-
<div
|
|
1261
|
-
<div class="filter-bar" id="filterBar">
|
|
1283
|
+
<div id="searchMeta" style="display:none"></div>
|
|
1284
|
+
<div id="sharingSearchMeta" style="display:none"></div>
|
|
1285
|
+
<div class="filter-bar compact-filter-row" id="filterBar" style="flex-wrap:nowrap">
|
|
1262
1286
|
<button class="filter-chip active" data-role="" onclick="setRoleFilter(this,'')" data-i18n="filter.all">All</button>
|
|
1263
1287
|
<button class="filter-chip" data-role="user" onclick="setRoleFilter(this,'user')">User</button>
|
|
1264
1288
|
<button class="filter-chip" data-role="assistant" onclick="setRoleFilter(this,'assistant')">Assistant</button>
|
|
@@ -1267,42 +1291,48 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1267
1291
|
<option value="newest" data-i18n="filter.newest">Newest first</option>
|
|
1268
1292
|
<option value="oldest" data-i18n="filter.oldest">Oldest first</option>
|
|
1269
1293
|
</select>
|
|
1270
|
-
<span
|
|
1271
|
-
<
|
|
1272
|
-
|
|
1273
|
-
</select>
|
|
1294
|
+
<span style="flex:1"></span>
|
|
1295
|
+
<button class="filter-chip" id="memorySelectAllBtn" onclick="toggleSelectAllMemories()" data-i18n="skills.selectAll">Select All</button>
|
|
1296
|
+
<button class="filter-chip" id="memoryBulkDeleteBtn" onclick="deleteSelectedMemories()" style="display:none;color:#ef4444;border-color:rgba(239,68,68,.3)" data-i18n="memory.deleteSelected">Delete Selected</button>
|
|
1274
1297
|
</div>
|
|
1275
|
-
<div class="
|
|
1276
|
-
<
|
|
1277
|
-
<
|
|
1278
|
-
<
|
|
1298
|
+
<div class="filter-bar compact-filter-row" style="flex-wrap:nowrap;margin-bottom:12px">
|
|
1299
|
+
<input type="datetime-local" id="dateFrom" step="1" onchange="applyFilters()" class="compact-date" data-i18n-ph="filter.from" placeholder="From">
|
|
1300
|
+
<span style="color:var(--text-muted);font-size:12px">—</span>
|
|
1301
|
+
<input type="datetime-local" id="dateTo" step="1" onchange="applyFilters()" class="compact-date" data-i18n-ph="filter.to" placeholder="To">
|
|
1302
|
+
<button class="filter-chip" onclick="clearDateFilter()" data-i18n="filter.clear" style="font-size:11px;padding:4px 10px">Clear</button>
|
|
1279
1303
|
</div>
|
|
1280
1304
|
<div class="memory-list" id="memoryList"><div class="spinner"></div></div>
|
|
1281
|
-
<div class="pagination"
|
|
1305
|
+
<div class="pagination-row">
|
|
1306
|
+
<div class="pagination" id="pagination"></div>
|
|
1307
|
+
</div>
|
|
1282
1308
|
</div>
|
|
1283
1309
|
</div>
|
|
1284
1310
|
<div class="tasks-view vp" id="tasksView">
|
|
1285
|
-
<div class="
|
|
1286
|
-
<
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
<
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
<
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1311
|
+
<div class="search-bar">
|
|
1312
|
+
<span class="search-icon">\u{1F50D}</span>
|
|
1313
|
+
<input type="text" id="taskSearchInput" data-i18n-ph="tasks.search.placeholder" placeholder="Search tasks..." oninput="debounceTaskSearch()">
|
|
1314
|
+
<select id="taskFilterOwner" class="filter-select" onchange="onOwnerFilterChange()">
|
|
1315
|
+
<option value="" data-i18n="filter.allagents">All agents</option>
|
|
1316
|
+
</select>
|
|
1317
|
+
<select id="taskSearchScope" class="scope-select" onchange="onTaskScopeChange()" style="display:none">
|
|
1318
|
+
<option value="allLocal" data-i18n="scope.thisDevice">This Device</option>
|
|
1319
|
+
<option value="hub" data-i18n="scope.hub">Team</option>
|
|
1320
|
+
</select>
|
|
1321
|
+
</div>
|
|
1322
|
+
<div id="taskSearchMeta" style="display:none"></div>
|
|
1323
|
+
<div class="filter-bar compact-filter-row" style="flex-wrap:nowrap">
|
|
1324
|
+
<button class="filter-chip active" data-task-status="" onclick="setTaskStatusFilter(this,'')" data-i18n="filter.all">All</button>
|
|
1325
|
+
<button class="filter-chip" data-task-status="active" onclick="setTaskStatusFilter(this,'active')" data-i18n="tasks.status.active">Active</button>
|
|
1326
|
+
<button class="filter-chip" data-task-status="completed" onclick="setTaskStatusFilter(this,'completed')" data-i18n="tasks.status.completed">Completed</button>
|
|
1327
|
+
<button class="filter-chip" data-task-status="skipped" onclick="setTaskStatusFilter(this,'skipped')" data-i18n="tasks.status.skipped">Skipped</button>
|
|
1328
|
+
<span style="flex:1"></span>
|
|
1329
|
+
<button class="filter-chip" id="taskSelectAllBtn" onclick="toggleSelectAllTasks()" data-i18n="skills.selectAll">Select All</button>
|
|
1330
|
+
<button class="filter-chip" id="taskBulkDeleteBtn" onclick="deleteSelectedTasks()" style="display:none;color:#ef4444;border-color:rgba(239,68,68,.3)" data-i18n="task.deleteSelected">Delete Selected</button>
|
|
1303
1331
|
</div>
|
|
1304
1332
|
<div class="tasks-list" id="tasksList"><div class="spinner"></div></div>
|
|
1305
|
-
<div class="pagination"
|
|
1333
|
+
<div class="pagination-row">
|
|
1334
|
+
<div class="pagination" id="tasksPagination"></div>
|
|
1335
|
+
</div>
|
|
1306
1336
|
<div class="task-detail-overlay" id="taskDetailOverlay" onclick="closeTaskDetail(event)">
|
|
1307
1337
|
<div class="task-detail-panel" onclick="event.stopPropagation()">
|
|
1308
1338
|
<div class="task-detail-header">
|
|
@@ -1336,34 +1366,33 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1336
1366
|
<div class="search-bar">
|
|
1337
1367
|
<span class="search-icon">🔍</span>
|
|
1338
1368
|
<input type="text" id="skillSearchInput" placeholder="Search skills..." data-i18n-ph="skills.search.placeholder" oninput="debounceSkillSearch()">
|
|
1369
|
+
<select id="skillFilterOwner" class="filter-select" onchange="onOwnerFilterChange()">
|
|
1370
|
+
<option value="" data-i18n="filter.allagents">All agents</option>
|
|
1371
|
+
</select>
|
|
1339
1372
|
<select id="skillSearchScope" class="scope-select" onchange="onSkillScopeChange()" style="display:none">
|
|
1340
|
-
<option value="local" data-i18n="scope.thisAgent">This Agent</option>
|
|
1341
1373
|
<option value="allLocal" data-i18n="scope.thisDevice">This Device</option>
|
|
1342
1374
|
<option value="hub" data-i18n="scope.hub">Team</option>
|
|
1343
1375
|
</select>
|
|
1344
1376
|
</div>
|
|
1345
|
-
<div
|
|
1346
|
-
<div class="
|
|
1347
|
-
<
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
<
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
<select id="skillVisibilityFilter" class="filter-select" onchange="loadSkills()" style="display:none">
|
|
1360
|
-
<option value="" data-i18n="filter.allvisibility">All visibility</option>
|
|
1361
|
-
<option value="public" data-i18n="filter.public">Public</option>
|
|
1362
|
-
<option value="private" data-i18n="filter.private">Private</option>
|
|
1363
|
-
</select>
|
|
1364
|
-
</div>
|
|
1377
|
+
<div id="skillSearchMeta" style="display:none"></div>
|
|
1378
|
+
<div class="filter-bar compact-filter-row" style="flex-wrap:nowrap">
|
|
1379
|
+
<button class="filter-chip active" data-skill-status="" onclick="setSkillStatusFilter(this,'')" data-i18n="filter.all">All</button>
|
|
1380
|
+
<button class="filter-chip" data-skill-status="active" onclick="setSkillStatusFilter(this,'active')" data-i18n="skills.filter.active">Active</button>
|
|
1381
|
+
<button class="filter-chip" data-skill-status="draft" onclick="setSkillStatusFilter(this,'draft')" data-i18n="skills.filter.draft">Draft</button>
|
|
1382
|
+
<button class="filter-chip" data-skill-status="archived" onclick="setSkillStatusFilter(this,'archived')" data-i18n="skills.filter.archived">Archived</button>
|
|
1383
|
+
<select id="skillVisibilityFilter" class="filter-select" onchange="loadSkills()" style="display:none">
|
|
1384
|
+
<option value="" data-i18n="filter.allvisibility">All visibility</option>
|
|
1385
|
+
<option value="public" data-i18n="filter.public">Public</option>
|
|
1386
|
+
<option value="private" data-i18n="filter.private">Private</option>
|
|
1387
|
+
</select>
|
|
1388
|
+
<span style="flex:1"></span>
|
|
1389
|
+
<button class="filter-chip" id="skillSelectAllBtn" onclick="toggleSelectAllSkills()" data-i18n="skills.selectAll">Select All</button>
|
|
1390
|
+
<button class="filter-chip" id="skillBulkDeleteBtn" onclick="deleteSelectedSkills()" style="display:none;color:#ef4444;border-color:rgba(239,68,68,.3)" data-i18n="skills.deleteSelected">Delete Selected</button>
|
|
1365
1391
|
</div>
|
|
1366
1392
|
<div class="tasks-list" id="skillsList"><div class="spinner"></div></div>
|
|
1393
|
+
<div class="pagination-row">
|
|
1394
|
+
<div class="pagination" id="skillsPagination"></div>
|
|
1395
|
+
</div>
|
|
1367
1396
|
<div id="hubSkillsSection" style="display:none;margin-top:16px">
|
|
1368
1397
|
<div class="section-title" style="margin-bottom:12px" data-i18n="skills.hub.title">\u{1F310} Team Skills</div>
|
|
1369
1398
|
<div class="tasks-list" id="hubSkillsList"></div>
|
|
@@ -2029,11 +2058,21 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
2029
2058
|
<div class="toast-container" id="toasts"></div>
|
|
2030
2059
|
|
|
2031
2060
|
<script>
|
|
2032
|
-
let activeSession=null,activeRole='',editingId=null,searchTimer=null,memoryCache={},currentPage=1,totalPages=1,totalCount=0,PAGE_SIZE=
|
|
2033
|
-
let memorySearchScope='
|
|
2061
|
+
let activeSession=null,activeRole='',editingId=null,searchTimer=null,memoryCache={},currentPage=1,totalPages=1,totalCount=0,PAGE_SIZE=20,metricsDays=30;
|
|
2062
|
+
let memorySearchScope='allLocal',skillSearchScope='allLocal',taskSearchScope='allLocal';
|
|
2034
2063
|
let _lastMemoriesFingerprint='',_lastTasksFingerprint='',_lastSkillsFingerprint='';
|
|
2064
|
+
let selectedMemoryIds=new Set(),currentMemoryIds=[];
|
|
2065
|
+
let selectedTaskIds=new Set(),currentTaskIds=[];
|
|
2035
2066
|
let _embeddingWarningShown=false;
|
|
2036
2067
|
let _currentAgentOwner='agent:main';
|
|
2068
|
+
try {
|
|
2069
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
2070
|
+
const agentId = urlParams.get('agentId');
|
|
2071
|
+
if (agentId) {
|
|
2072
|
+
_currentAgentOwner = 'agent:' + agentId;
|
|
2073
|
+
}
|
|
2074
|
+
} catch(e) {}
|
|
2075
|
+
|
|
2037
2076
|
|
|
2038
2077
|
/* ─── i18n ─── */
|
|
2039
2078
|
const I18N={
|
|
@@ -2098,6 +2137,8 @@ const I18N={
|
|
|
2098
2137
|
'tasks.status.active':'Active',
|
|
2099
2138
|
'tasks.status.completed':'Completed',
|
|
2100
2139
|
'tasks.status.skipped':'Skipped',
|
|
2140
|
+
'tasks.search.placeholder':'Search tasks...',
|
|
2141
|
+
'tasks.search.meta':'Found {0} tasks',
|
|
2101
2142
|
'tasks.empty':'No tasks yet. Tasks are automatically created as you converse.',
|
|
2102
2143
|
'tasks.loading':'Loading...',
|
|
2103
2144
|
'tasks.untitled':'Untitled Task',
|
|
@@ -2138,8 +2179,8 @@ const I18N={
|
|
|
2138
2179
|
'notif.timeAgo.hour':'{n}h ago',
|
|
2139
2180
|
'notif.timeAgo.day':'{n}d ago',
|
|
2140
2181
|
'stat.memories':'Memories',
|
|
2141
|
-
'stat.
|
|
2142
|
-
'stat.
|
|
2182
|
+
'stat.tasks':'Tasks',
|
|
2183
|
+
'stat.skills':'Skills',
|
|
2143
2184
|
'stat.agents':'Agents',
|
|
2144
2185
|
'stat.active':'active',
|
|
2145
2186
|
'stat.deduped':'deduped',
|
|
@@ -2179,6 +2220,7 @@ const I18N={
|
|
|
2179
2220
|
'card.dedupTarget':'Target: ',
|
|
2180
2221
|
'card.dedupReason':'Reason: ',
|
|
2181
2222
|
'card.newSummary':'New',
|
|
2223
|
+
'pagination.pageSize':'Items per page',
|
|
2182
2224
|
'pagination.total':' total',
|
|
2183
2225
|
'range':'Range',
|
|
2184
2226
|
'range.days':'days',
|
|
@@ -2385,9 +2427,18 @@ const I18N={
|
|
|
2385
2427
|
'skills.nochangelog':'No changelog',
|
|
2386
2428
|
'skills.status.active':'Active',
|
|
2387
2429
|
'skills.status.draft':'Draft',
|
|
2388
|
-
'skills.status.archived':'
|
|
2430
|
+
'skills.status.archived':'Disabled',
|
|
2431
|
+
'skills.action.disable':'Disable',
|
|
2432
|
+
'skills.action.enable':'Enable',
|
|
2433
|
+
'skills.action.delete':'Delete',
|
|
2434
|
+
'skills.disable.confirm':'Are you sure you want to disable this skill? It will no longer be used in search or auto-recall, but can be re-enabled later.',
|
|
2435
|
+
'skills.disable.error':'Failed to disable skill: ',
|
|
2436
|
+
'skills.enable.error':'Failed to enable skill: ',
|
|
2389
2437
|
'skills.updated':'Updated: ',
|
|
2390
2438
|
'skills.task.prefix':'Task: ',
|
|
2439
|
+
'skills.selectAll':'Select All',
|
|
2440
|
+
'skills.unselectAll':'Unselect All',
|
|
2441
|
+
'skills.deleteSelected':'Delete Selected',
|
|
2391
2442
|
'tasks.chunks.label':'chunks',
|
|
2392
2443
|
'tasks.taskid':'Task ID: ',
|
|
2393
2444
|
'tasks.role.user':'You',
|
|
@@ -2728,6 +2779,10 @@ const I18N={
|
|
|
2728
2779
|
'task.cancel':'Cancel',
|
|
2729
2780
|
'task.delete.confirm':'Are you sure you want to delete this task? This cannot be undone.',
|
|
2730
2781
|
'task.delete.error':'Failed to delete task: ',
|
|
2782
|
+
'task.deleteSelected':'Delete Selected',
|
|
2783
|
+
'task.delete.selected.confirm':'Delete {count} selected tasks? This action cannot be undone.',
|
|
2784
|
+
'task.delete.success':'Deleted {count} tasks.',
|
|
2785
|
+
'task.delete.partial':'Deleted {ok} tasks, failed {fail}.',
|
|
2731
2786
|
'task.save.error':'Failed to save task: ',
|
|
2732
2787
|
'task.retrySkill':'Retry Skill Generation',
|
|
2733
2788
|
'task.retrySkill.short':'Retry Skill',
|
|
@@ -2738,7 +2793,14 @@ const I18N={
|
|
|
2738
2793
|
'skill.save':'Save',
|
|
2739
2794
|
'skill.cancel':'Cancel',
|
|
2740
2795
|
'skill.delete.confirm':'Are you sure you want to delete this skill? This will also remove all associated files and cannot be undone.',
|
|
2796
|
+
'skill.delete.selected.confirm':'Delete {count} selected skills? This action cannot be undone.',
|
|
2741
2797
|
'skill.delete.error':'Failed to delete skill: ',
|
|
2798
|
+
'skill.delete.partial':'Deleted {ok} skills, failed {fail}.',
|
|
2799
|
+
'skill.delete.success':'Deleted {count} skills.',
|
|
2800
|
+
'memory.deleteSelected':'Delete Selected',
|
|
2801
|
+
'memory.delete.selected.confirm':'Delete {count} selected memories? This action cannot be undone.',
|
|
2802
|
+
'memory.delete.success':'Deleted {count} memories.',
|
|
2803
|
+
'memory.delete.partial':'Deleted {ok} memories, failed {fail}.',
|
|
2742
2804
|
'skill.save.error':'Failed to save skill: ',
|
|
2743
2805
|
'update.available':'New version available',
|
|
2744
2806
|
'update.run':'Run',
|
|
@@ -2842,6 +2904,8 @@ const I18N={
|
|
|
2842
2904
|
'tasks.status.active':'进行中',
|
|
2843
2905
|
'tasks.status.completed':'已完成',
|
|
2844
2906
|
'tasks.status.skipped':'已跳过',
|
|
2907
|
+
'tasks.search.placeholder':'搜索任务...',
|
|
2908
|
+
'tasks.search.meta':'找到 {0} 个任务',
|
|
2845
2909
|
'tasks.empty':'暂无任务。任务会随着对话自动创建。',
|
|
2846
2910
|
'tasks.loading':'加载中...',
|
|
2847
2911
|
'tasks.untitled':'未命名任务',
|
|
@@ -2882,8 +2946,8 @@ const I18N={
|
|
|
2882
2946
|
'notif.timeAgo.hour':'{n}小时前',
|
|
2883
2947
|
'notif.timeAgo.day':'{n}天前',
|
|
2884
2948
|
'stat.memories':'记忆',
|
|
2885
|
-
'stat.
|
|
2886
|
-
'stat.
|
|
2949
|
+
'stat.tasks':'任务',
|
|
2950
|
+
'stat.skills':'技能',
|
|
2887
2951
|
'stat.agents':'智能体',
|
|
2888
2952
|
'stat.active':'活跃',
|
|
2889
2953
|
'stat.deduped':'已去重',
|
|
@@ -2923,6 +2987,7 @@ const I18N={
|
|
|
2923
2987
|
'card.dedupTarget':'关联: ',
|
|
2924
2988
|
'card.dedupReason':'原因: ',
|
|
2925
2989
|
'card.newSummary':'新摘要',
|
|
2990
|
+
'pagination.pageSize':'每页数量',
|
|
2926
2991
|
'pagination.total':' 条',
|
|
2927
2992
|
'range':'范围',
|
|
2928
2993
|
'range.days':'天',
|
|
@@ -3129,9 +3194,18 @@ const I18N={
|
|
|
3129
3194
|
'skills.nochangelog':'暂无变更记录',
|
|
3130
3195
|
'skills.status.active':'生效中',
|
|
3131
3196
|
'skills.status.draft':'草稿',
|
|
3132
|
-
'skills.status.archived':'
|
|
3197
|
+
'skills.status.archived':'已禁用',
|
|
3198
|
+
'skills.action.disable':'禁用',
|
|
3199
|
+
'skills.action.enable':'启用',
|
|
3200
|
+
'skills.action.delete':'删除',
|
|
3201
|
+
'skills.disable.confirm':'确定要禁用此技能吗?禁用后不再参与检索和自动召回,但可以随时重新启用。',
|
|
3202
|
+
'skills.disable.error':'禁用技能失败:',
|
|
3203
|
+
'skills.enable.error':'启用技能失败:',
|
|
3133
3204
|
'skills.updated':'更新于:',
|
|
3134
3205
|
'skills.task.prefix':'任务:',
|
|
3206
|
+
'skills.selectAll':'全选',
|
|
3207
|
+
'skills.unselectAll':'取消全选',
|
|
3208
|
+
'skills.deleteSelected':'删除选中',
|
|
3135
3209
|
'tasks.chunks.label':'条记忆',
|
|
3136
3210
|
'tasks.taskid':'任务 ID:',
|
|
3137
3211
|
'tasks.role.user':'你',
|
|
@@ -3472,6 +3546,10 @@ const I18N={
|
|
|
3472
3546
|
'task.cancel':'取消',
|
|
3473
3547
|
'task.delete.confirm':'确定要删除此任务吗?此操作不可撤销。',
|
|
3474
3548
|
'task.delete.error':'删除任务失败:',
|
|
3549
|
+
'task.deleteSelected':'删除选中',
|
|
3550
|
+
'task.delete.selected.confirm':'确定删除选中的 {count} 个任务吗?此操作不可撤销。',
|
|
3551
|
+
'task.delete.success':'已删除 {count} 个任务。',
|
|
3552
|
+
'task.delete.partial':'已删除 {ok} 个任务,失败 {fail} 个。',
|
|
3475
3553
|
'task.save.error':'保存任务失败:',
|
|
3476
3554
|
'task.retrySkill':'重新生成技能',
|
|
3477
3555
|
'task.retrySkill.short':'重试技能',
|
|
@@ -3482,7 +3560,14 @@ const I18N={
|
|
|
3482
3560
|
'skill.save':'保存',
|
|
3483
3561
|
'skill.cancel':'取消',
|
|
3484
3562
|
'skill.delete.confirm':'确定要删除此技能吗?关联的文件也会被删除,此操作不可撤销。',
|
|
3563
|
+
'skill.delete.selected.confirm':'确定删除选中的 {count} 个技能吗?此操作不可撤销。',
|
|
3485
3564
|
'skill.delete.error':'删除技能失败:',
|
|
3565
|
+
'skill.delete.partial':'已删除 {ok} 个技能,失败 {fail} 个。',
|
|
3566
|
+
'skill.delete.success':'已删除 {count} 个技能。',
|
|
3567
|
+
'memory.deleteSelected':'删除选中',
|
|
3568
|
+
'memory.delete.selected.confirm':'确定删除选中的 {count} 条记忆吗?此操作不可撤销。',
|
|
3569
|
+
'memory.delete.success':'已删除 {count} 条记忆。',
|
|
3570
|
+
'memory.delete.partial':'已删除 {ok} 条记忆,失败 {fail} 条。',
|
|
3486
3571
|
'skill.save.error':'保存技能失败:',
|
|
3487
3572
|
'update.available':'发现新版本',
|
|
3488
3573
|
'update.run':'执行命令',
|
|
@@ -3767,9 +3852,12 @@ function switchView(view){
|
|
|
3767
3852
|
}
|
|
3768
3853
|
var sessionSection=document.getElementById('sidebarSessionSection');
|
|
3769
3854
|
if(sessionSection){
|
|
3770
|
-
if(view==='memories'){sessionSection.style.visibility='';sessionSection.style.pointerEvents='';}
|
|
3855
|
+
if(view==='memories'||view==='tasks'||view==='skills'){sessionSection.style.visibility='';sessionSection.style.pointerEvents='';}
|
|
3771
3856
|
else{sessionSection.style.visibility='hidden';sessionSection.style.pointerEvents='none';}
|
|
3772
3857
|
}
|
|
3858
|
+
if(view==='memories'||view==='tasks'||view==='skills'){
|
|
3859
|
+
loadStats();
|
|
3860
|
+
}
|
|
3773
3861
|
if(view==='tasks') loadTasks();
|
|
3774
3862
|
else if(view==='skills') loadSkills();
|
|
3775
3863
|
else if(view==='analytics') loadMetrics();
|
|
@@ -3786,36 +3874,84 @@ function switchView(view){
|
|
|
3786
3874
|
}
|
|
3787
3875
|
|
|
3788
3876
|
function onMemoryScopeChange(){
|
|
3789
|
-
memorySearchScope=document.getElementById('memorySearchScope')?.value||'
|
|
3877
|
+
memorySearchScope=document.getElementById('memorySearchScope')?.value||'allLocal';
|
|
3790
3878
|
try{localStorage.setItem('memos_memorySearchScope',memorySearchScope);}catch(e){}
|
|
3791
3879
|
currentPage=1;
|
|
3792
3880
|
activeSession=null;activeRole='';
|
|
3793
3881
|
_lastMemoriesFingerprint='';
|
|
3882
|
+
if(memorySearchScope==='hub') selectedMemoryIds.clear();
|
|
3794
3883
|
var isHub=memorySearchScope==='hub';
|
|
3795
|
-
var isLocal=memorySearchScope==='local';
|
|
3796
3884
|
var ownerSel=document.getElementById('filterOwner');
|
|
3797
3885
|
var filterBar=document.getElementById('filterBar');
|
|
3798
3886
|
var dateFilter=document.querySelector('.date-filter');
|
|
3799
|
-
if(ownerSel){ownerSel.style.display=
|
|
3887
|
+
if(ownerSel){ownerSel.style.display=isHub?'none':'';if(isHub)ownerSel.value='';}
|
|
3800
3888
|
if(filterBar) filterBar.style.display=isHub?'none':'';
|
|
3801
3889
|
if(dateFilter) dateFilter.style.display=isHub?'none':'';
|
|
3890
|
+
updateMemorySelectionToolbar();
|
|
3802
3891
|
if(document.getElementById('searchInput').value.trim()) doSearch(document.getElementById('searchInput').value);
|
|
3803
3892
|
else if(isHub) { document.getElementById('sharingSearchMeta').textContent=''; loadHubMemories(); }
|
|
3804
3893
|
else {
|
|
3805
3894
|
document.getElementById('sharingSearchMeta').textContent='';
|
|
3806
|
-
var ownerArg=
|
|
3895
|
+
var ownerArg=undefined;
|
|
3807
3896
|
loadStats(ownerArg); loadMemories();
|
|
3808
3897
|
}
|
|
3809
3898
|
}
|
|
3810
3899
|
|
|
3900
|
+
function normalizePageSize(value,fallback){
|
|
3901
|
+
const v=Number(value);
|
|
3902
|
+
return v===10||v===20||v===40?v:fallback;
|
|
3903
|
+
}
|
|
3904
|
+
|
|
3905
|
+
function applyPageSizeFromSelect(selectId,storageKey,fallback,onApply){
|
|
3906
|
+
const el=document.getElementById(selectId);
|
|
3907
|
+
const next=normalizePageSize(el?.value,fallback);
|
|
3908
|
+
onApply(next);
|
|
3909
|
+
try{localStorage.setItem(storageKey,String(next));}catch(e){}
|
|
3910
|
+
return next;
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
function restorePageSizeSetting(storageKey,selectId,fallback,onApply){
|
|
3914
|
+
let next=fallback;
|
|
3915
|
+
try{
|
|
3916
|
+
const raw=localStorage.getItem(storageKey);
|
|
3917
|
+
next=normalizePageSize(raw||String(fallback),fallback);
|
|
3918
|
+
}catch(e){}
|
|
3919
|
+
onApply(next);
|
|
3920
|
+
const el=document.getElementById(selectId);
|
|
3921
|
+
if(el) el.value=String(next);
|
|
3922
|
+
return next;
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
function onMemoryPageSizeChange(){
|
|
3926
|
+
applyPageSizeFromSelect('memoryPageSize','memos_memoryPageSize',20,function(next){PAGE_SIZE=next;});
|
|
3927
|
+
currentPage=1;
|
|
3928
|
+
if(memorySearchScope==='hub') loadHubMemories();
|
|
3929
|
+
else loadMemories();
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3811
3932
|
function onSkillScopeChange(){
|
|
3812
|
-
skillSearchScope=document.getElementById('skillSearchScope')?.value||'
|
|
3933
|
+
skillSearchScope=document.getElementById('skillSearchScope')?.value||'allLocal';
|
|
3934
|
+
skillsPage=0;
|
|
3935
|
+
loadSkills();
|
|
3936
|
+
}
|
|
3937
|
+
|
|
3938
|
+
function onSkillsPageSizeChange(){
|
|
3939
|
+
applyPageSizeFromSelect('skillsPageSize','memos_skillsPageSize',20,function(next){skillsPageSize=next;});
|
|
3940
|
+
skillsPage=0;
|
|
3813
3941
|
loadSkills();
|
|
3814
3942
|
}
|
|
3815
3943
|
|
|
3944
|
+
function onTasksPageSizeChange(){
|
|
3945
|
+
applyPageSizeFromSelect('tasksPageSize','memos_tasksPageSize',20,function(next){tasksPageSize=next;});
|
|
3946
|
+
tasksPage=0;
|
|
3947
|
+
loadTasks();
|
|
3948
|
+
}
|
|
3949
|
+
|
|
3816
3950
|
function onTaskScopeChange(){
|
|
3817
|
-
taskSearchScope=document.getElementById('taskSearchScope')?.value||'
|
|
3951
|
+
taskSearchScope=document.getElementById('taskSearchScope')?.value||'allLocal';
|
|
3952
|
+
if(taskSearchScope==='hub') selectedTaskIds.clear();
|
|
3818
3953
|
tasksPage=0;
|
|
3954
|
+
updateTaskSelectionToolbar();
|
|
3819
3955
|
loadTasks();
|
|
3820
3956
|
}
|
|
3821
3957
|
|
|
@@ -5040,6 +5176,7 @@ function renderSharingMemorySearchResults(data,query){
|
|
|
5040
5176
|
const list=document.getElementById('memoryList');
|
|
5041
5177
|
const localHits=(data&&data.local&&Array.isArray(data.local.hits))?data.local.hits:[];
|
|
5042
5178
|
const hubHits=(data&&data.hub&&Array.isArray(data.hub.hits))?data.hub.hits:[];
|
|
5179
|
+
setPageSizeVisible('memoryPageSize',(localHits.length+hubHits.length)>0);
|
|
5043
5180
|
document.getElementById('searchMeta').textContent='Search results for "'+query+'"';
|
|
5044
5181
|
document.getElementById('sharingSearchMeta').textContent=t('scope.local')+' '+localHits.length+' · '+t('scope.hub')+' '+hubHits.length;
|
|
5045
5182
|
document.getElementById('pagination').innerHTML='';
|
|
@@ -5459,6 +5596,7 @@ function localMemoryErrorMessage(err){
|
|
|
5459
5596
|
|
|
5460
5597
|
function debounceSkillSearch(){
|
|
5461
5598
|
clearTimeout(skillSearchTimer);
|
|
5599
|
+
skillsPage=0;
|
|
5462
5600
|
skillSearchTimer=setTimeout(function(){loadSkills();},300);
|
|
5463
5601
|
}
|
|
5464
5602
|
|
|
@@ -5827,6 +5965,11 @@ function escapeHtml(s){
|
|
|
5827
5965
|
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
5828
5966
|
}
|
|
5829
5967
|
|
|
5968
|
+
function setPageSizeVisible(selectId,visible){
|
|
5969
|
+
var sel=document.getElementById(selectId);
|
|
5970
|
+
if(sel&&sel.parentElement){ sel.parentElement.style.display=visible?'inline-flex':'none'; }
|
|
5971
|
+
}
|
|
5972
|
+
|
|
5830
5973
|
function setMetricsDays(d){
|
|
5831
5974
|
metricsDays=d;
|
|
5832
5975
|
document.querySelectorAll('.metrics-toolbar .range-btn').forEach(btn=>btn.classList.toggle('active',Number(btn.dataset.days)===d));
|
|
@@ -5846,40 +5989,179 @@ async function loadMetrics(){
|
|
|
5846
5989
|
}catch(e){console.error('loadMetrics',e)}
|
|
5847
5990
|
}
|
|
5848
5991
|
|
|
5992
|
+
function _st(id,v){var e=document.getElementById(id);if(e)e.textContent=v;}
|
|
5849
5993
|
function formatNum(n){return n>=1e6?(n/1e6).toFixed(1)+'M':n>=1e3?(n/1e3).toFixed(1)+'k':String(n);}
|
|
5850
5994
|
function dateLoc(){return curLang==='zh'?'zh-CN':'en-US';}
|
|
5851
5995
|
|
|
5852
5996
|
/* ─── Tasks View Logic ─── */
|
|
5853
5997
|
let tasksStatusFilter='';
|
|
5854
5998
|
let tasksPage=0;
|
|
5855
|
-
|
|
5999
|
+
let tasksPageSize=20;
|
|
5856
6000
|
|
|
5857
6001
|
function setTaskStatusFilter(btn,status){
|
|
5858
|
-
document.querySelectorAll('.tasks-
|
|
6002
|
+
document.querySelectorAll('.tasks-view .filter-bar .filter-chip[data-task-status]').forEach(c=>c.classList.remove('active'));
|
|
5859
6003
|
btn.classList.add('active');
|
|
5860
6004
|
tasksStatusFilter=status;
|
|
5861
6005
|
tasksPage=0;
|
|
5862
6006
|
loadTasks();
|
|
5863
6007
|
}
|
|
5864
6008
|
|
|
6009
|
+
function updateTaskSelectionToolbar(){
|
|
6010
|
+
var toolbar=document.getElementById('taskSelectionToolbar');
|
|
6011
|
+
var selectAllBtn=document.getElementById('taskSelectAllBtn');
|
|
6012
|
+
var bulkDeleteBtn=document.getElementById('taskBulkDeleteBtn');
|
|
6013
|
+
var isHub=taskSearchScope==='hub';
|
|
6014
|
+
var total=document.querySelectorAll('#tasksList .task-select-check').length;
|
|
6015
|
+
var selected=selectedTaskIds.size;
|
|
6016
|
+
if(toolbar) toolbar.style.display=isHub?'none':'flex';
|
|
6017
|
+
if(selectAllBtn){
|
|
6018
|
+
selectAllBtn.textContent=t(selected>0&&selected===total&&total>0?'skills.unselectAll':'skills.selectAll');
|
|
6019
|
+
selectAllBtn.disabled=total===0;
|
|
6020
|
+
selectAllBtn.style.display=total===0?'none':'';
|
|
6021
|
+
}
|
|
6022
|
+
if(bulkDeleteBtn){
|
|
6023
|
+
var base=t('task.deleteSelected');
|
|
6024
|
+
bulkDeleteBtn.style.display=selected>0?'':'none';
|
|
6025
|
+
bulkDeleteBtn.textContent=selected>0?(base+' ('+selected+')'):base;
|
|
6026
|
+
}
|
|
6027
|
+
}
|
|
6028
|
+
|
|
6029
|
+
function toggleTaskSelection(taskId,checked){
|
|
6030
|
+
if(checked) selectedTaskIds.add(taskId);
|
|
6031
|
+
else selectedTaskIds.delete(taskId);
|
|
6032
|
+
updateTaskSelectionToolbar();
|
|
6033
|
+
}
|
|
6034
|
+
|
|
6035
|
+
function toggleSelectAllTasks(){
|
|
6036
|
+
var total=currentTaskIds.length;
|
|
6037
|
+
if(total===0) return;
|
|
6038
|
+
if(selectedTaskIds.size===total){
|
|
6039
|
+
selectedTaskIds.clear();
|
|
6040
|
+
}else{
|
|
6041
|
+
selectedTaskIds=new Set(currentTaskIds);
|
|
6042
|
+
}
|
|
6043
|
+
var checks=document.querySelectorAll('#tasksList .task-select-check');
|
|
6044
|
+
checks.forEach(function(cb){cb.checked=selectedTaskIds.has(cb.value);});
|
|
6045
|
+
updateTaskSelectionToolbar();
|
|
6046
|
+
}
|
|
6047
|
+
|
|
6048
|
+
async function deleteSelectedTasks(){
|
|
6049
|
+
var ids=Array.from(selectedTaskIds);
|
|
6050
|
+
if(ids.length===0) return;
|
|
6051
|
+
var msg=t('task.delete.selected.confirm').replace('{count}',String(ids.length));
|
|
6052
|
+
if(!(await confirmModal(msg,{danger:true}))) return;
|
|
6053
|
+
var ok=0;
|
|
6054
|
+
var fail=0;
|
|
6055
|
+
for(var i=0;i<ids.length;i++){
|
|
6056
|
+
try{
|
|
6057
|
+
var r=await fetch('/api/task/'+ids[i],{method:'DELETE'});
|
|
6058
|
+
var d=await r.json();
|
|
6059
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
6060
|
+
ok++;
|
|
6061
|
+
}catch(e){
|
|
6062
|
+
fail++;
|
|
6063
|
+
}
|
|
6064
|
+
}
|
|
6065
|
+
selectedTaskIds.clear();
|
|
6066
|
+
updateTaskSelectionToolbar();
|
|
6067
|
+
loadTasks();
|
|
6068
|
+
if(fail>0) toast(t('task.delete.partial').replace('{ok}',String(ok)).replace('{fail}',String(fail)),'warn');
|
|
6069
|
+
else toast(t('task.delete.success').replace('{count}',String(ok)),'success');
|
|
6070
|
+
}
|
|
6071
|
+
|
|
6072
|
+
var taskSearchQuery='';
|
|
6073
|
+
var _taskSearchTimer=null;
|
|
6074
|
+
function debounceTaskSearch(){
|
|
6075
|
+
clearTimeout(_taskSearchTimer);
|
|
6076
|
+
_taskSearchTimer=setTimeout(function(){
|
|
6077
|
+
taskSearchQuery=(document.getElementById('taskSearchInput')||{}).value||'';
|
|
6078
|
+
tasksPage=0;
|
|
6079
|
+
loadTasks();
|
|
6080
|
+
},350);
|
|
6081
|
+
}
|
|
6082
|
+
|
|
6083
|
+
function renderTaskCards(tasks,container){
|
|
6084
|
+
currentTaskIds=tasks.map(function(task){return task.id;});
|
|
6085
|
+
selectedTaskIds=new Set(Array.from(selectedTaskIds).filter(function(id){return currentTaskIds.includes(id);}));
|
|
6086
|
+
if(!tasks||tasks.length===0){
|
|
6087
|
+
container.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px" data-i18n="tasks.empty">'+t('tasks.empty')+'</div>';
|
|
6088
|
+
updateTaskSelectionToolbar();
|
|
6089
|
+
return;
|
|
6090
|
+
}
|
|
6091
|
+
container.innerHTML=tasks.map(function(task){
|
|
6092
|
+
var timeStr=formatTime(task.startedAt);
|
|
6093
|
+
var durationStr=task.endedAt?formatDuration(task.endedAt-task.startedAt):'';
|
|
6094
|
+
var taskIsLocalShared=task.owner==='public';
|
|
6095
|
+
var taskIsTeamShared=!!task.sharingVisibility;
|
|
6096
|
+
var taskScope=taskIsTeamShared?'team':taskIsLocalShared?'local':'private';
|
|
6097
|
+
var selectedAttr=selectedTaskIds.has(task.id)?' checked':'';
|
|
6098
|
+
return '<div class="task-card status-'+task.status+'" onclick="openTaskDetail(\\''+task.id+'\\')">'+
|
|
6099
|
+
'<div class="task-card-top">'+
|
|
6100
|
+
'<div class="task-card-title"><label class="item-select-box" onclick="event.stopPropagation()"><input class="task-select-check" type="checkbox" value="'+escAttr(task.id)+'"'+selectedAttr+' onchange="event.stopPropagation();toggleTaskSelection("'+escAttr(task.id)+'",this.checked)"></label>'+esc(task.title)+'</div>'+
|
|
6101
|
+
'<div class="task-card-badges">'+renderScopeBadge(taskScope)+'<span class="task-status-badge '+task.status+'">'+t('tasks.status.'+task.status)+'</span></div>'+
|
|
6102
|
+
'</div>'+
|
|
6103
|
+
(task.summary?'<div class="task-card-summary'+(task.status==='skipped'?' skipped-reason':'')+'">'+esc(task.summary)+'</div>':'')+
|
|
6104
|
+
'<div class="task-card-bottom">'+
|
|
6105
|
+
'<span class="tag"><span class="icon">\\u{1F4C5}</span> '+timeStr+'</span>'+
|
|
6106
|
+
(durationStr?'<span class="tag"><span class="icon">\\u23F1</span> '+durationStr+'</span>':'')+
|
|
6107
|
+
'<span class="tag"><span class="icon">\\u{1F4DD}</span> '+(task.chunkCount||0)+' '+t('tasks.chunks.label')+'</span>'+
|
|
6108
|
+
'<span class="tag"><span class="icon">\\u{1F4C2}</span> '+(task.sessionKey||'').slice(0,12)+'</span>'+
|
|
6109
|
+
'</div>'+
|
|
6110
|
+
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
6111
|
+
'<button class="btn btn-sm btn-ghost" onclick="openTaskDetail(\\''+task.id+'\\')">'+t('card.expand')+'</button>'+
|
|
6112
|
+
(task.status==='completed'&&(!task.skillStatus||task.skillStatus==='not_generated'||task.skillStatus==='skipped')?'<button class="btn btn-sm btn-ghost" onclick="retrySkillGen(\\''+task.id+'\\')">'+t('task.retrySkill.short')+'</button>':'')+
|
|
6113
|
+
(task.status==='completed'
|
|
6114
|
+
?'<button class="btn btn-sm btn-ghost" onclick="openTaskScopeModalFromList(\\''+task.id+'\\',\\''+taskScope+'\\')">\\u270F '+t('share.shareBtn')+'</button>'
|
|
6115
|
+
:'<button class="btn btn-sm btn-ghost" style="opacity:0.45;cursor:not-allowed" onclick="toast(t(\\x27share.scope.taskNotCompleted\\x27),\\x27warn\\x27)">\\u270F '+t('share.shareBtn')+'</button>')+
|
|
6116
|
+
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteTask(\\''+task.id+'\\')">'+t('task.delete')+'</button>'+
|
|
6117
|
+
'</div>'+
|
|
6118
|
+
'</div>';
|
|
6119
|
+
}).join('');
|
|
6120
|
+
updateTaskSelectionToolbar();
|
|
6121
|
+
}
|
|
6122
|
+
|
|
5865
6123
|
async function loadTasks(silent){
|
|
5866
6124
|
const scope=document.getElementById('taskSearchScope')?document.getElementById('taskSearchScope').value:taskSearchScope;
|
|
5867
|
-
taskSearchScope=scope||'
|
|
6125
|
+
taskSearchScope=scope||'allLocal';
|
|
5868
6126
|
if(taskSearchScope==='hub'){ return loadHubTasks(); }
|
|
5869
6127
|
const list=document.getElementById('tasksList');
|
|
5870
6128
|
if(!silent) list.innerHTML='<div class="spinner"></div>';
|
|
5871
6129
|
try{
|
|
5872
|
-
|
|
6130
|
+
var ownerSel=document.getElementById('taskFilterOwner')||document.getElementById('filterOwner');
|
|
6131
|
+
var ownerVal=ownerSel?ownerSel.value:'';
|
|
6132
|
+
|
|
6133
|
+
if(taskSearchQuery&&taskSearchQuery.trim()){
|
|
6134
|
+
var sp=new URLSearchParams({q:taskSearchQuery.trim(),limit:String(tasksPageSize)});
|
|
6135
|
+
if(ownerVal) sp.set('owner',ownerVal);
|
|
6136
|
+
var sr=await fetch('/api/task-search?'+sp).then(function(r){return r.json()});
|
|
6137
|
+
var tasks=sr.tasks||[];
|
|
6138
|
+
document.getElementById('taskSearchMeta').style.display='block';
|
|
6139
|
+
document.getElementById('taskSearchMeta').textContent=t('tasks.search.meta').replace('{0}',tasks.length);
|
|
6140
|
+
_st('tasksTotalCount',tasks.length);
|
|
6141
|
+
_st('tasksActiveCount',tasks.filter(function(tk){return tk.status==='active'}).length);
|
|
6142
|
+
_st('tasksCompletedCount',tasks.filter(function(tk){return tk.status==='completed'}).length);
|
|
6143
|
+
_st('tasksSkippedCount',tasks.filter(function(tk){return tk.status==='skipped'}).length);
|
|
6144
|
+
if(tasksStatusFilter) tasks=tasks.filter(function(tk){return tk.status===tasksStatusFilter});
|
|
6145
|
+
renderTaskCards(tasks,list);
|
|
6146
|
+
document.getElementById('tasksPagination').innerHTML='';
|
|
6147
|
+
return;
|
|
6148
|
+
}
|
|
6149
|
+
document.getElementById('taskSearchMeta').style.display='none';
|
|
6150
|
+
|
|
6151
|
+
const params=new URLSearchParams({limit:String(tasksPageSize),offset:String(tasksPage*tasksPageSize)});
|
|
5873
6152
|
if(tasksStatusFilter) params.set('status',tasksStatusFilter);
|
|
5874
|
-
if(
|
|
6153
|
+
if(activeSession) params.set('session',activeSession);
|
|
6154
|
+
if(ownerVal) params.set('owner',ownerVal);
|
|
5875
6155
|
var baseP=new URLSearchParams();
|
|
5876
|
-
if(
|
|
6156
|
+
if(activeSession) baseP.set('session',activeSession);
|
|
6157
|
+
if(ownerVal) baseP.set('owner',ownerVal);
|
|
6158
|
+
var baseQuery=baseP.toString();
|
|
5877
6159
|
const [data,allD,activeD,compD,skipD]=await Promise.all([
|
|
5878
6160
|
fetch('/api/tasks?'+params).then(r=>r.json()),
|
|
5879
|
-
fetch('/api/tasks?limit=1&offset=0&'+
|
|
5880
|
-
fetch('/api/tasks?status=active&limit=1&offset=0&'+
|
|
5881
|
-
fetch('/api/tasks?status=completed&limit=1&offset=0&'+
|
|
5882
|
-
fetch('/api/tasks?status=skipped&limit=1&offset=0&'+
|
|
6161
|
+
fetch('/api/tasks?limit=1&offset=0'+(baseQuery?'&'+baseQuery:'')).then(r=>r.json()),
|
|
6162
|
+
fetch('/api/tasks?status=active&limit=1&offset=0'+(baseQuery?'&'+baseQuery:'')).then(r=>r.json()),
|
|
6163
|
+
fetch('/api/tasks?status=completed&limit=1&offset=0'+(baseQuery?'&'+baseQuery:'')).then(r=>r.json()),
|
|
6164
|
+
fetch('/api/tasks?status=skipped&limit=1&offset=0'+(baseQuery?'&'+baseQuery:'')) .then(r=>r.json())
|
|
5883
6165
|
]);
|
|
5884
6166
|
if(silent){
|
|
5885
6167
|
var fp=JSON.stringify((data.tasks||[]).map(function(tk){return tk.id+'|'+tk.status+'|'+(tk.updatedAt||tk.startedAt)}));
|
|
@@ -5889,50 +6171,24 @@ async function loadTasks(silent){
|
|
|
5889
6171
|
}else{
|
|
5890
6172
|
_lastTasksFingerprint='';
|
|
5891
6173
|
}
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
6174
|
+
_st('tasksTotalCount',formatNum(allD.total));
|
|
6175
|
+
_st('tasksActiveCount',formatNum(activeD.total));
|
|
6176
|
+
_st('tasksCompletedCount',formatNum(compD.total));
|
|
6177
|
+
_st('tasksSkippedCount',formatNum(skipD.total));
|
|
6178
|
+
|
|
6179
|
+
renderTaskCards(data.tasks||[],list);
|
|
5896
6180
|
|
|
5897
6181
|
if(!data.tasks||data.tasks.length===0){
|
|
5898
|
-
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px" data-i18n="tasks.empty">'+t('tasks.empty')+'</div>';
|
|
5899
6182
|
document.getElementById('tasksPagination').innerHTML='';
|
|
5900
|
-
|
|
6183
|
+
} else {
|
|
6184
|
+
renderTasksPagination(data.total);
|
|
5901
6185
|
}
|
|
5902
|
-
|
|
5903
|
-
list.innerHTML=data.tasks.map(task=>{
|
|
5904
|
-
const timeStr=formatTime(task.startedAt);
|
|
5905
|
-
const endStr=task.endedAt?formatTime(task.endedAt):'';
|
|
5906
|
-
const durationStr=task.endedAt?formatDuration(task.endedAt-task.startedAt):'';
|
|
5907
|
-
var taskIsLocalShared=task.owner==='public';
|
|
5908
|
-
var taskIsTeamShared=!!task.sharingVisibility;
|
|
5909
|
-
var taskScope=taskIsTeamShared?'team':taskIsLocalShared?'local':'private';
|
|
5910
|
-
return '<div class="task-card status-'+task.status+'" onclick="openTaskDetail(\\''+task.id+'\\')">'+
|
|
5911
|
-
'<div class="task-card-top">'+
|
|
5912
|
-
'<div class="task-card-title">'+esc(task.title)+'</div>'+
|
|
5913
|
-
'<div class="task-card-badges">'+renderScopeBadge(taskScope)+'<span class="task-status-badge '+task.status+'">'+t('tasks.status.'+task.status)+'</span></div>'+
|
|
5914
|
-
'</div>'+
|
|
5915
|
-
(task.summary?'<div class="task-card-summary'+(task.status==='skipped'?' skipped-reason':'')+'">'+esc(task.summary)+'</div>':'')+
|
|
5916
|
-
'<div class="task-card-bottom">'+
|
|
5917
|
-
'<span class="tag"><span class="icon">\\u{1F4C5}</span> '+timeStr+'</span>'+
|
|
5918
|
-
(durationStr?'<span class="tag"><span class="icon">\\u23F1</span> '+durationStr+'</span>':'')+
|
|
5919
|
-
'<span class="tag"><span class="icon">\\u{1F4DD}</span> '+task.chunkCount+' '+t('tasks.chunks.label')+'</span>'+
|
|
5920
|
-
'<span class="tag"><span class="icon">\\u{1F4C2}</span> '+(task.sessionKey||'').slice(0,12)+'</span>'+
|
|
5921
|
-
'</div>'+
|
|
5922
|
-
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
5923
|
-
'<button class="btn btn-sm btn-ghost" onclick="openTaskDetail(\\''+task.id+'\\')">'+t('card.expand')+'</button>'+
|
|
5924
|
-
(task.status==='completed'&&(!task.skillStatus||task.skillStatus==='not_generated'||task.skillStatus==='skipped')?'<button class="btn btn-sm btn-ghost" onclick="retrySkillGen(\\''+task.id+'\\')">'+t('task.retrySkill.short')+'</button>':'')+
|
|
5925
|
-
(task.status==='completed'
|
|
5926
|
-
?'<button class="btn btn-sm btn-ghost" onclick="openTaskScopeModalFromList(\\''+task.id+'\\',\\''+taskScope+'\\')">\\u270F '+t('share.shareBtn')+'</button>'
|
|
5927
|
-
:'<button class="btn btn-sm btn-ghost" style="opacity:0.45;cursor:not-allowed" onclick="toast(t(\\x27share.scope.taskNotCompleted\\x27),\\x27warn\\x27)">\\u270F '+t('share.shareBtn')+'</button>')+
|
|
5928
|
-
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteTask(\\''+task.id+'\\')">'+t('task.delete')+'</button>'+
|
|
5929
|
-
'</div>'+
|
|
5930
|
-
'</div>';
|
|
5931
|
-
}).join('');
|
|
5932
|
-
|
|
5933
|
-
renderTasksPagination(data.total);
|
|
5934
6186
|
}catch(e){
|
|
5935
6187
|
console.error('loadTasks error:',e);
|
|
6188
|
+
currentTaskIds=[];
|
|
6189
|
+
selectedTaskIds.clear();
|
|
6190
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6191
|
+
updateTaskSelectionToolbar();
|
|
5936
6192
|
list.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">Failed to load tasks: '+String(e)+'</div>';
|
|
5937
6193
|
}
|
|
5938
6194
|
}
|
|
@@ -5953,7 +6209,7 @@ function updateTaskCardBadge(taskId,newScope){
|
|
|
5953
6209
|
|
|
5954
6210
|
function renderTasksPagination(total){
|
|
5955
6211
|
const el=document.getElementById('tasksPagination');
|
|
5956
|
-
const pages=Math.ceil(total/
|
|
6212
|
+
const pages=Math.ceil(total/tasksPageSize);
|
|
5957
6213
|
if(pages<=1){el.innerHTML='';return;}
|
|
5958
6214
|
let html='<button class="pg-btn'+(tasksPage===0?' disabled':'')+'" onclick="tasksPage=Math.max(0,tasksPage-1);loadTasks()">\\u2190</button>';
|
|
5959
6215
|
const start=Math.max(0,tasksPage-2),end=Math.min(pages,tasksPage+3);
|
|
@@ -6141,6 +6397,8 @@ async function deleteTask(taskId){
|
|
|
6141
6397
|
const r=await fetch('/api/task/'+taskId,{method:'DELETE'});
|
|
6142
6398
|
const d=await r.json();
|
|
6143
6399
|
if(!r.ok) throw new Error(d.error||'unknown');
|
|
6400
|
+
selectedTaskIds.delete(taskId);
|
|
6401
|
+
updateTaskSelectionToolbar();
|
|
6144
6402
|
closeTaskDetail();
|
|
6145
6403
|
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
6146
6404
|
loadTasks();
|
|
@@ -6150,14 +6408,55 @@ async function deleteTask(taskId){
|
|
|
6150
6408
|
|
|
6151
6409
|
/* ─── Skills View Logic ─── */
|
|
6152
6410
|
let skillsStatusFilter='';
|
|
6411
|
+
let skillsPage=0;
|
|
6412
|
+
let skillsPageSize=20;
|
|
6413
|
+
let selectedSkillIds=new Set();
|
|
6414
|
+
let currentLocalSkills=[];
|
|
6415
|
+
let skillsFilterSignature='';
|
|
6153
6416
|
|
|
6154
6417
|
function setSkillStatusFilter(btn,status){
|
|
6155
|
-
document.querySelectorAll('.skills-view .
|
|
6418
|
+
document.querySelectorAll('.skills-view .filter-bar .filter-chip[data-skill-status]').forEach(c=>c.classList.remove('active'));
|
|
6156
6419
|
btn.classList.add('active');
|
|
6157
6420
|
skillsStatusFilter=status;
|
|
6421
|
+
skillsPage=0;
|
|
6158
6422
|
loadSkills();
|
|
6159
6423
|
}
|
|
6160
6424
|
|
|
6425
|
+
function updateSkillSelectionToolbar(){
|
|
6426
|
+
var selectAllBtn=document.getElementById('skillSelectAllBtn');
|
|
6427
|
+
var bulkDeleteBtn=document.getElementById('skillBulkDeleteBtn');
|
|
6428
|
+
var total=document.querySelectorAll('#skillsList .skill-select-check').length;
|
|
6429
|
+
var selected=selectedSkillIds.size;
|
|
6430
|
+
if(selectAllBtn){
|
|
6431
|
+
selectAllBtn.textContent=t(selected>0&&selected===total&&total>0?'skills.unselectAll':'skills.selectAll');
|
|
6432
|
+
selectAllBtn.style.display=total===0?'none':'';
|
|
6433
|
+
}
|
|
6434
|
+
if(bulkDeleteBtn){
|
|
6435
|
+
var base=t('skills.deleteSelected');
|
|
6436
|
+
bulkDeleteBtn.style.display=selected>0?'':'none';
|
|
6437
|
+
bulkDeleteBtn.textContent=selected>0?(base+' ('+selected+')'):base;
|
|
6438
|
+
}
|
|
6439
|
+
}
|
|
6440
|
+
|
|
6441
|
+
function toggleSkillSelection(skillId,checked){
|
|
6442
|
+
if(checked) selectedSkillIds.add(skillId);
|
|
6443
|
+
else selectedSkillIds.delete(skillId);
|
|
6444
|
+
updateSkillSelectionToolbar();
|
|
6445
|
+
}
|
|
6446
|
+
|
|
6447
|
+
function toggleSelectAllSkills(){
|
|
6448
|
+
var total=currentLocalSkills.length;
|
|
6449
|
+
if(total===0) return;
|
|
6450
|
+
if(selectedSkillIds.size===total){
|
|
6451
|
+
selectedSkillIds.clear();
|
|
6452
|
+
}else{
|
|
6453
|
+
selectedSkillIds=new Set(currentLocalSkills.map(function(s){return s.id;}));
|
|
6454
|
+
}
|
|
6455
|
+
var checks=document.querySelectorAll('#skillsList .skill-select-check');
|
|
6456
|
+
checks.forEach(function(cb){cb.checked=selectedSkillIds.has(cb.value);});
|
|
6457
|
+
updateSkillSelectionToolbar();
|
|
6458
|
+
}
|
|
6459
|
+
|
|
6161
6460
|
function updateSkillCardBadge(skillId,newScope){
|
|
6162
6461
|
var cards=document.querySelectorAll('.skill-card');
|
|
6163
6462
|
for(var i=0;i<cards.length;i++){
|
|
@@ -6174,13 +6473,28 @@ function updateSkillCardBadge(skillId,newScope){
|
|
|
6174
6473
|
}
|
|
6175
6474
|
}
|
|
6176
6475
|
|
|
6476
|
+
function renderSkillsPagination(total){
|
|
6477
|
+
const el=document.getElementById('skillsPagination');
|
|
6478
|
+
if(!el) return;
|
|
6479
|
+
const pages=Math.ceil(total/skillsPageSize);
|
|
6480
|
+
if(pages<=1){el.innerHTML='';return;}
|
|
6481
|
+
let html='<button class="pg-btn'+(skillsPage===0?' disabled':'')+'" onclick="skillsPage=Math.max(0,skillsPage-1);loadSkills()">\\u2190</button>';
|
|
6482
|
+
const start=Math.max(0,skillsPage-2),end=Math.min(pages,skillsPage+3);
|
|
6483
|
+
for(let i=start;i<end;i++){
|
|
6484
|
+
html+='<button class="pg-btn'+(i===skillsPage?' active':'')+'" onclick="skillsPage='+i+';loadSkills()">'+(i+1)+'</button>';
|
|
6485
|
+
}
|
|
6486
|
+
html+='<button class="pg-btn'+(skillsPage>=pages-1?' disabled':'')+'" onclick="skillsPage=Math.min('+(pages-1)+',skillsPage+1);loadSkills()">\\u2192</button>';
|
|
6487
|
+
html+='<span class="pg-info">'+total+' '+t('pagination.total')+'</span>';
|
|
6488
|
+
el.innerHTML=html;
|
|
6489
|
+
}
|
|
6490
|
+
|
|
6177
6491
|
async function loadSkills(silent){
|
|
6178
6492
|
const list=document.getElementById('skillsList');
|
|
6179
6493
|
const hubList=document.getElementById('hubSkillsList');
|
|
6180
6494
|
if(!silent) list.innerHTML='<div class="spinner"></div>';
|
|
6181
6495
|
var hubSection=document.getElementById('hubSkillsSection');
|
|
6182
6496
|
if(hubList){
|
|
6183
|
-
if(skillSearchScope==='
|
|
6497
|
+
if(skillSearchScope==='allLocal'){
|
|
6184
6498
|
if(hubSection) hubSection.style.display='none';
|
|
6185
6499
|
}else{
|
|
6186
6500
|
if(hubSection) hubSection.style.display='block';
|
|
@@ -6190,24 +6504,37 @@ async function loadSkills(silent){
|
|
|
6190
6504
|
|
|
6191
6505
|
const query=(document.getElementById('skillSearchInput')?.value||'').trim();
|
|
6192
6506
|
const scope=document.getElementById('skillSearchScope') ? document.getElementById('skillSearchScope').value : skillSearchScope;
|
|
6193
|
-
skillSearchScope=scope||'
|
|
6507
|
+
skillSearchScope=scope||'allLocal';
|
|
6194
6508
|
|
|
6195
6509
|
try{
|
|
6196
6510
|
const params=new URLSearchParams();
|
|
6197
6511
|
if(skillsStatusFilter) params.set('status',skillsStatusFilter);
|
|
6512
|
+
if(activeSession) params.set('session',activeSession);
|
|
6513
|
+
var skillOwnerSel=document.getElementById('skillFilterOwner')||document.getElementById('filterOwner');
|
|
6514
|
+
var skillOwnerVal=skillOwnerSel?skillOwnerSel.value:'';
|
|
6515
|
+
if(skillOwnerVal) params.set('owner',skillOwnerVal);
|
|
6198
6516
|
const visFilter=document.getElementById('skillVisibilityFilter')?.value;
|
|
6199
6517
|
if(visFilter) params.set('visibility',visFilter);
|
|
6518
|
+
const filterSignature=[query,skillSearchScope,skillsStatusFilter,visFilter||'',skillOwnerVal].join('|');
|
|
6519
|
+
if(!silent&&filterSignature!==skillsFilterSignature){
|
|
6520
|
+
skillsPage=0;
|
|
6521
|
+
}
|
|
6522
|
+
skillsFilterSignature=filterSignature;
|
|
6200
6523
|
|
|
6201
6524
|
const localRes=await fetch('/api/skills?'+params.toString());
|
|
6202
6525
|
const localData=await localRes.json();
|
|
6203
6526
|
let localSkills=Array.isArray(localData.skills)?localData.skills:[];
|
|
6527
|
+
currentLocalSkills=localSkills.slice();
|
|
6204
6528
|
if(query){
|
|
6205
6529
|
const q=query.toLowerCase();
|
|
6206
6530
|
localSkills=localSkills.filter(skill=>{
|
|
6207
6531
|
const haystack=[skill.name,skill.description,skill.tags].filter(Boolean).join(' ').toLowerCase();
|
|
6208
6532
|
return haystack.includes(q);
|
|
6209
6533
|
});
|
|
6534
|
+
currentLocalSkills=localSkills.slice();
|
|
6210
6535
|
}
|
|
6536
|
+
var localIdSet=new Set(localSkills.map(function(s){return s.id;}));
|
|
6537
|
+
selectedSkillIds=new Set(Array.from(selectedSkillIds).filter(function(id){return localIdSet.has(id);}));
|
|
6211
6538
|
if(silent){
|
|
6212
6539
|
var fp=JSON.stringify(localSkills.map(function(s){return s.id+'|'+s.status+'|'+s.version+'|'+(s.visibility||'')}));
|
|
6213
6540
|
if(fp===_lastSkillsFingerprint) return;
|
|
@@ -6231,9 +6558,10 @@ async function loadSkills(silent){
|
|
|
6231
6558
|
const skillIsLocalShared=skill.visibility==='public';
|
|
6232
6559
|
const skillIsTeamShared=!!skill.sharingVisibility;
|
|
6233
6560
|
const skillScope=skillIsTeamShared?'team':skillIsLocalShared?'local':'private';
|
|
6561
|
+
const selectedAttr=selectedSkillIds.has(skill.id)?' checked':'';
|
|
6234
6562
|
return '<div class="skill-card '+installedClass+' '+statusClass+'" onclick="openSkillDetail("'+escAttr(skill.id)+'")">'+
|
|
6235
6563
|
'<div class="skill-card-top">'+
|
|
6236
|
-
'<div class="skill-card-name">🧠 '+esc(skill.name)+'</div>'+
|
|
6564
|
+
'<div class="skill-card-name"><label class="item-select-box" onclick="event.stopPropagation()"><input class="skill-select-check" type="checkbox" value="'+escAttr(skill.id)+'"'+selectedAttr+' onchange="event.stopPropagation();toggleSkillSelection("'+escAttr(skill.id)+'",this.checked)"></label>🧠 '+esc(skill.name)+'</div>'+
|
|
6237
6565
|
'<div class="skill-card-badges">'+
|
|
6238
6566
|
qsBadge+
|
|
6239
6567
|
'<span class="skill-badge version">v'+skill.version+'</span>'+
|
|
@@ -6249,25 +6577,40 @@ async function loadSkills(silent){
|
|
|
6249
6577
|
(tags.length>0?'<div class="skill-card-tags">'+tags.map(tg=>'<span class="skill-tag">'+esc(tg)+'</span>').join('')+'</div>':'')+
|
|
6250
6578
|
'<span class="card-actions-inline" onclick="event.stopPropagation()">'+
|
|
6251
6579
|
'<button class="btn btn-sm btn-ghost" onclick="openSkillDetail("'+escAttr(skill.id)+'")">'+t('card.expand')+'</button>'+
|
|
6580
|
+
'<button class="btn btn-sm btn-danger" onclick="deleteSkill("'+escAttr(skill.id)+'")">'+t('skill.delete')+'</button>'+
|
|
6252
6581
|
(skill.status==='active'
|
|
6253
6582
|
?'<button class="btn btn-sm btn-ghost" onclick="openSkillScopeModalFromList("'+escAttr(skill.id)+'","'+skillScope+'")">\\u270F '+t('share.shareBtn')+'</button>'
|
|
6254
6583
|
:'<button class="btn btn-sm btn-ghost" style="opacity:0.45;cursor:not-allowed" onclick="toast(t(\\x27share.scope.skillNotActive\\x27),\\x27warn\\x27)">\\u270F '+t('share.shareBtn')+'</button>')+
|
|
6584
|
+
(skill.status==='active'
|
|
6585
|
+
?'<button class="btn btn-sm btn-ghost btn-warn" onclick="disableSkill("'+escAttr(skill.id)+'")">'+t('skills.action.disable')+'</button>'
|
|
6586
|
+
:'')+
|
|
6587
|
+
(skill.status==='archived'
|
|
6588
|
+
?'<button class="btn btn-sm btn-ghost btn-success" onclick="enableSkill("'+escAttr(skill.id)+'")">'+t('skills.action.enable')+'</button>'
|
|
6589
|
+
:'')+
|
|
6590
|
+
'<button class="btn btn-sm btn-ghost btn-danger" onclick="deleteSkill("'+escAttr(skill.id)+'")">'+t('skills.action.delete')+'</button>'+
|
|
6255
6591
|
'</span>'+
|
|
6256
6592
|
'</div>'+
|
|
6257
6593
|
'</div>';
|
|
6258
6594
|
}).join('');
|
|
6259
6595
|
};
|
|
6260
6596
|
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
if(
|
|
6597
|
+
const totalLocalSkills=localSkills.length;
|
|
6598
|
+
const localPages=Math.ceil(totalLocalSkills/skillsPageSize)||1;
|
|
6599
|
+
if(skillsPage>=localPages) skillsPage=Math.max(0,localPages-1);
|
|
6600
|
+
const startIndex=skillsPage*skillsPageSize;
|
|
6601
|
+
const pageSkills=localSkills.slice(startIndex,startIndex+skillsPageSize);
|
|
6602
|
+
list.innerHTML=renderLocalCards(pageSkills);
|
|
6603
|
+
renderSkillsPagination(totalLocalSkills);
|
|
6604
|
+
setPageSizeVisible('skillsPageSize',totalLocalSkills>0);
|
|
6605
|
+
updateSkillSelectionToolbar();
|
|
6606
|
+
|
|
6607
|
+
if(skillSearchScope==='allLocal'){
|
|
6264
6608
|
if(hubSection) hubSection.style.display='none';
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
document.getElementById('skillsPublicCount').textContent=formatNum(localSkills.filter(s=>s.visibility==='public').length);
|
|
6609
|
+
_st('skillsTotalCount',formatNum(localSkills.length));
|
|
6610
|
+
_st('skillsActiveCount',formatNum(localSkills.filter(s=>s.status==='active').length));
|
|
6611
|
+
_st('skillsDraftCount',formatNum(localSkills.filter(s=>s.status==='draft').length));
|
|
6612
|
+
_st('skillsInstalledCount',formatNum(localSkills.filter(s=>s.installed).length));
|
|
6613
|
+
_st('skillsPublicCount',formatNum(localSkills.filter(s=>s.visibility==='public').length));
|
|
6271
6614
|
return;
|
|
6272
6615
|
}
|
|
6273
6616
|
|
|
@@ -6275,12 +6618,11 @@ async function loadSkills(silent){
|
|
|
6275
6618
|
if(hubSection) hubSection.style.display='block';
|
|
6276
6619
|
var localIds=new Set(localSkills.map(function(s){return s.id;}));
|
|
6277
6620
|
if(hubList){ loadHubSkills(hubList, localIds); }
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
document.getElementById('skillsPublicCount').textContent=formatNum(localSkills.filter(s=>s.visibility==='public').length);
|
|
6621
|
+
_st('skillsTotalCount',formatNum(localSkills.length));
|
|
6622
|
+
_st('skillsActiveCount',formatNum(localSkills.filter(s=>s.status==='active').length));
|
|
6623
|
+
_st('skillsDraftCount',formatNum(localSkills.filter(s=>s.status==='draft').length));
|
|
6624
|
+
_st('skillsInstalledCount',formatNum(localSkills.filter(s=>s.installed).length));
|
|
6625
|
+
_st('skillsPublicCount',formatNum(localSkills.filter(s=>s.visibility==='public').length));
|
|
6284
6626
|
return;
|
|
6285
6627
|
}
|
|
6286
6628
|
|
|
@@ -6290,9 +6632,13 @@ async function loadSkills(silent){
|
|
|
6290
6632
|
sharingParams.set('maxResults','20');
|
|
6291
6633
|
const r=await fetch('/api/sharing/search/skills?'+sharingParams.toString());
|
|
6292
6634
|
const data=await r.json();
|
|
6293
|
-
const
|
|
6635
|
+
const localSkillIdSet=new Set(currentLocalSkills.map(function(skill){return skill.id;}));
|
|
6636
|
+
const localHitsRaw=(data.local&&Array.isArray(data.local.hits))?data.local.hits:[];
|
|
6637
|
+
const localHits=localHitsRaw.filter(function(skill){return localSkillIdSet.has(skill.skillId);});
|
|
6294
6638
|
const hubHits=(data.hub&&Array.isArray(data.hub.hits))?data.hub.hits:[];
|
|
6295
6639
|
|
|
6640
|
+
const sp=document.getElementById('skillsPagination');
|
|
6641
|
+
if(sp) sp.innerHTML='';
|
|
6296
6642
|
list.innerHTML=localHits.length?localHits.map(function(skill){
|
|
6297
6643
|
return '<div class="hub-skill-card" onclick="openSkillDetail("'+escAttr(skill.skillId)+'")">'+
|
|
6298
6644
|
'<div class="summary">'+esc(skill.name)+'</div>'+
|
|
@@ -6318,14 +6664,18 @@ async function loadSkills(silent){
|
|
|
6318
6664
|
}).join(''):'';
|
|
6319
6665
|
}
|
|
6320
6666
|
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6667
|
+
_st('skillsTotalCount',formatNum(localHits.length+hubHits.length));
|
|
6668
|
+
_st('skillsActiveCount',formatNum(localHits.length));
|
|
6669
|
+
_st('skillsDraftCount','0');
|
|
6670
|
+
_st('skillsInstalledCount','-');
|
|
6671
|
+
_st('skillsPublicCount',formatNum(hubHits.filter(function(s){return s.visibility==='public';}).length));
|
|
6672
|
+
setPageSizeVisible('skillsPageSize',(localHits.length+hubHits.length)>0);
|
|
6673
|
+
updateSkillSelectionToolbar();
|
|
6327
6674
|
}catch(e){
|
|
6328
6675
|
list.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">'+t('skills.load.error')+': '+esc(String(e))+'</div>';
|
|
6676
|
+
const sp=document.getElementById('skillsPagination');
|
|
6677
|
+
if(sp) sp.innerHTML='';
|
|
6678
|
+
setPageSizeVisible('skillsPageSize',false);
|
|
6329
6679
|
if(hubList){
|
|
6330
6680
|
hubList.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">'+t('skills.load.error')+'</div>';
|
|
6331
6681
|
}
|
|
@@ -6335,19 +6685,28 @@ async function loadSkills(silent){
|
|
|
6335
6685
|
async function loadHubTasks(){
|
|
6336
6686
|
var list=document.getElementById('tasksList');
|
|
6337
6687
|
if(!list) return;
|
|
6688
|
+
currentTaskIds=[];
|
|
6689
|
+
selectedTaskIds.clear();
|
|
6690
|
+
updateTaskSelectionToolbar();
|
|
6338
6691
|
list.innerHTML='<div class="spinner"></div>';
|
|
6339
6692
|
try{
|
|
6340
|
-
var r=await fetch('/api/sharing/tasks/list?limit=
|
|
6693
|
+
var r=await fetch('/api/sharing/tasks/list?limit='+tasksPageSize);
|
|
6341
6694
|
var d=await r.json();
|
|
6342
6695
|
var tasks=Array.isArray(d.tasks)?d.tasks:[];
|
|
6696
|
+
if(activeSession){
|
|
6697
|
+
tasks=tasks.filter(function(task){
|
|
6698
|
+
return (task.sessionKey||task.session_key||'')===activeSession;
|
|
6699
|
+
});
|
|
6700
|
+
}
|
|
6343
6701
|
hubTasksCache=tasks;
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6702
|
+
_st('tasksTotalCount',formatNum(tasks.length));
|
|
6703
|
+
_st('tasksActiveCount','-');
|
|
6704
|
+
_st('tasksCompletedCount','-');
|
|
6705
|
+
_st('tasksSkippedCount','-');
|
|
6348
6706
|
if(!tasks.length){
|
|
6349
6707
|
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px">'+t('tasks.empty')+'</div>';
|
|
6350
6708
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6709
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6351
6710
|
return;
|
|
6352
6711
|
}
|
|
6353
6712
|
list.innerHTML=tasks.map(function(task,idx){
|
|
@@ -6366,9 +6725,11 @@ async function loadHubTasks(){
|
|
|
6366
6725
|
'</div>';
|
|
6367
6726
|
}).join('');
|
|
6368
6727
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6728
|
+
setPageSizeVisible('tasksPageSize',true);
|
|
6369
6729
|
}catch(e){
|
|
6370
6730
|
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px">'+t('tasks.empty')+'</div>';
|
|
6371
6731
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6732
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6372
6733
|
}
|
|
6373
6734
|
}
|
|
6374
6735
|
|
|
@@ -6524,7 +6885,14 @@ async function openSkillDetail(skillId){
|
|
|
6524
6885
|
}
|
|
6525
6886
|
|
|
6526
6887
|
window._currentSkillData=skill;
|
|
6527
|
-
|
|
6888
|
+
var detailActionsHtml='';
|
|
6889
|
+
if(skill.status==='active'){
|
|
6890
|
+
detailActionsHtml+='<button class="btn btn-sm btn-warn" onclick="disableSkill("'+escAttr(skill.id)+'")">'+t('skills.action.disable')+'</button>';
|
|
6891
|
+
}else if(skill.status==='archived'){
|
|
6892
|
+
detailActionsHtml+='<button class="btn btn-sm btn-success" onclick="enableSkill("'+escAttr(skill.id)+'")">'+t('skills.action.enable')+'</button>';
|
|
6893
|
+
}
|
|
6894
|
+
detailActionsHtml+='<button class="btn btn-sm btn-danger" onclick="deleteSkill("'+escAttr(skill.id)+'")">'+t('skills.action.delete')+'</button>';
|
|
6895
|
+
document.getElementById('skillDetailActions').innerHTML=detailActionsHtml;
|
|
6528
6896
|
|
|
6529
6897
|
}catch(e){
|
|
6530
6898
|
document.getElementById('skillDetailTitle').textContent=t('skills.error');
|
|
@@ -7106,11 +7474,60 @@ async function deleteSkill(skillId){
|
|
|
7106
7474
|
const r=await fetch('/api/skill/'+skillId,{method:'DELETE'});
|
|
7107
7475
|
const d=await r.json();
|
|
7108
7476
|
if(!r.ok) throw new Error(d.error||'unknown');
|
|
7477
|
+
selectedSkillIds.delete(skillId);
|
|
7478
|
+
updateSkillSelectionToolbar();
|
|
7109
7479
|
closeSkillDetail();
|
|
7110
7480
|
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
7111
7481
|
loadSkills();
|
|
7112
7482
|
}catch(e){ alert(t('skill.delete.error')+e.message); }
|
|
7113
7483
|
}
|
|
7484
|
+
async function disableSkill(skillId){
|
|
7485
|
+
if(!(await confirmModal(t('skills.disable.confirm')))) return;
|
|
7486
|
+
try{
|
|
7487
|
+
const r=await fetch('/api/skill/'+skillId+'/disable',{method:'PUT'});
|
|
7488
|
+
const d=await r.json();
|
|
7489
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
7490
|
+
toast(t('skills.action.disable')+' ✓','ok');
|
|
7491
|
+
closeSkillDetail();
|
|
7492
|
+
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
7493
|
+
loadSkills();
|
|
7494
|
+
}catch(e){ alert(t('skills.disable.error')+e.message); }
|
|
7495
|
+
}
|
|
7496
|
+
async function enableSkill(skillId){
|
|
7497
|
+
try{
|
|
7498
|
+
const r=await fetch('/api/skill/'+skillId+'/enable',{method:'PUT'});
|
|
7499
|
+
const d=await r.json();
|
|
7500
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
7501
|
+
toast(t('skills.action.enable')+' ✓','ok');
|
|
7502
|
+
closeSkillDetail();
|
|
7503
|
+
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
7504
|
+
loadSkills();
|
|
7505
|
+
}catch(e){ alert(t('skills.enable.error')+e.message); }
|
|
7506
|
+
}
|
|
7507
|
+
|
|
7508
|
+
async function deleteSelectedSkills(){
|
|
7509
|
+
var ids=Array.from(selectedSkillIds);
|
|
7510
|
+
if(ids.length===0) return;
|
|
7511
|
+
var msg=t('skill.delete.selected.confirm').replace('{count}',String(ids.length));
|
|
7512
|
+
if(!(await confirmModal(msg,{danger:true}))) return;
|
|
7513
|
+
var ok=0;
|
|
7514
|
+
var fail=0;
|
|
7515
|
+
for(var i=0;i<ids.length;i++){
|
|
7516
|
+
try{
|
|
7517
|
+
var r=await fetch('/api/skill/'+ids[i],{method:'DELETE'});
|
|
7518
|
+
var d=await r.json();
|
|
7519
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
7520
|
+
ok++;
|
|
7521
|
+
}catch(e){
|
|
7522
|
+
fail++;
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
7525
|
+
selectedSkillIds.clear();
|
|
7526
|
+
updateSkillSelectionToolbar();
|
|
7527
|
+
loadSkills();
|
|
7528
|
+
if(fail>0) toast(t('skill.delete.partial').replace('{ok}',String(ok)).replace('{fail}',String(fail)),'warn');
|
|
7529
|
+
else toast(t('skill.delete.success').replace('{count}',String(ok)),'success');
|
|
7530
|
+
}
|
|
7114
7531
|
|
|
7115
7532
|
|
|
7116
7533
|
function formatDuration(ms){
|
|
@@ -7445,7 +7862,7 @@ async function _livePollTick(){
|
|
|
7445
7862
|
var _searchVal=(document.getElementById('searchInput')||{}).value||'';
|
|
7446
7863
|
if(!_searchVal.trim()){
|
|
7447
7864
|
if(memorySearchScope==='hub') await loadHubMemories(true);
|
|
7448
|
-
else{var _pollOwner=
|
|
7865
|
+
else{var _pollOwner=undefined;await loadStats(_pollOwner);await loadMemories(null,true);}
|
|
7449
7866
|
}
|
|
7450
7867
|
}
|
|
7451
7868
|
else if(_activeView==='tasks') await loadTasks(true);
|
|
@@ -7718,7 +8135,7 @@ function stopNotifPoll(){ }
|
|
|
7718
8135
|
/* ─── Data loading ─── */
|
|
7719
8136
|
async function loadAll(){
|
|
7720
8137
|
await loadStats();
|
|
7721
|
-
var initOwner=
|
|
8138
|
+
var initOwner=undefined;
|
|
7722
8139
|
if(initOwner) await loadStats(initOwner);
|
|
7723
8140
|
await Promise.all([loadMemories(),loadSharingStatus(false)]);
|
|
7724
8141
|
checkMigrateStatus();
|
|
@@ -7738,21 +8155,23 @@ async function loadStats(ownerFilter){
|
|
|
7738
8155
|
d=await r.json();
|
|
7739
8156
|
}catch(e){ d={}; }
|
|
7740
8157
|
if(!d||typeof d!=='object') d={};
|
|
7741
|
-
if(d.currentAgentOwner) _currentAgentOwner=d.currentAgentOwner;
|
|
8158
|
+
if(d.currentAgentOwner && !new URLSearchParams(window.location.search).get('agentId')) _currentAgentOwner=d.currentAgentOwner;
|
|
7742
8159
|
const tm=d.totalMemories||0;
|
|
7743
8160
|
const dedupB=d.dedupBreakdown||{};
|
|
7744
8161
|
const activeCount=dedupB.active||tm;
|
|
7745
8162
|
const inactiveCount=(dedupB.duplicate||0)+(dedupB.merged||0);
|
|
7746
8163
|
var agentCount=(d.owners&&d.owners.length)?d.owners.length:1;
|
|
7747
|
-
var
|
|
8164
|
+
var tvc=(d.taskSessions||[]).length;
|
|
8165
|
+
var svc=(d.skillSessions||[]).length;
|
|
8166
|
+
var sfp=tm+':'+(d.totalSessions||0)+':'+(d.totalEmbeddings||0)+':'+agentCount+':'+(d.embeddingProvider||'none')+':'+(ownerFilter||'')+':'+(_activeView||'memories')+':'+tvc+':'+svc;
|
|
7748
8167
|
if(sfp===_lastStatsFp) return;
|
|
7749
8168
|
_lastStatsFp=sfp;
|
|
7750
8169
|
document.getElementById('statTotal').textContent=tm;
|
|
7751
8170
|
if(inactiveCount>0){
|
|
7752
8171
|
document.getElementById('statTotal').title=activeCount+' '+t('stat.active')+', '+inactiveCount+' '+t('stat.deduped');
|
|
7753
8172
|
}
|
|
7754
|
-
document.getElementById('
|
|
7755
|
-
document.getElementById('
|
|
8173
|
+
document.getElementById('statTasks').textContent=d.totalTasks||0;
|
|
8174
|
+
document.getElementById('statSkills').textContent=d.totalSkills||0;
|
|
7756
8175
|
document.getElementById('statAgents').textContent=agentCount;
|
|
7757
8176
|
|
|
7758
8177
|
const provEl=document.getElementById('embeddingStatus');
|
|
@@ -7776,45 +8195,76 @@ async function loadStats(ownerFilter){
|
|
|
7776
8195
|
}).catch(()=>{});
|
|
7777
8196
|
}
|
|
7778
8197
|
|
|
8198
|
+
const memorySessions=d.sessions||[];
|
|
8199
|
+
const taskSessions=d.taskSessions||[];
|
|
8200
|
+
const skillSessions=d.skillSessions||[];
|
|
8201
|
+
const sessionMap={memories:memorySessions,tasks:taskSessions,skills:skillSessions};
|
|
8202
|
+
function getSessionsForView(view){
|
|
8203
|
+
return sessionMap[view]||memorySessions;
|
|
8204
|
+
}
|
|
8205
|
+
function countBadgeHtml(cnt){
|
|
8206
|
+
return cnt&&cnt>0?'<span class="count">'+cnt+'</span>':'';
|
|
8207
|
+
}
|
|
8208
|
+
|
|
8209
|
+
const sidebarSessions=getSessionsForView(_activeView);
|
|
7779
8210
|
const sl=document.getElementById('sessionList');
|
|
7780
|
-
sl.
|
|
7781
|
-
(
|
|
8211
|
+
if(sl) sl.style.display=sidebarSessions.length>0?'':'none';
|
|
8212
|
+
sl.innerHTML='<div class="session-item'+(activeSession===null?' active':'')+'" onclick="filterSession(null)"><span>'+t('sidebar.allsessions')+'</span>'+countBadgeHtml(sidebarSessions.reduce(function(sum,s){return sum+(s.count||0);},0))+'</div>';
|
|
8213
|
+
sidebarSessions.forEach(s=>{
|
|
7782
8214
|
const isActive=activeSession===s.session_key;
|
|
7783
8215
|
const name=s.session_key.length>20?s.session_key.slice(0,8)+'...'+s.session_key.slice(-8):s.session_key;
|
|
7784
|
-
sl.innerHTML+='<div class="session-item'+(isActive?' active':'')+'" onclick="filterSession(\\''+s.session_key.replace(/'/g,"\\\\'")+'\\')"><span title="'+s.session_key+'">'+name+'</span
|
|
8216
|
+
sl.innerHTML+='<div class="session-item'+(isActive?' active':'')+'" onclick="filterSession(\\''+s.session_key.replace(/'/g,"\\\\'")+'\\')"><span title="'+s.session_key+'">'+name+'</span>'+countBadgeHtml(s.count||0)+'</div>';
|
|
7785
8217
|
});
|
|
7786
8218
|
|
|
7787
|
-
|
|
7788
|
-
|
|
8219
|
+
[['filterSession','memories'],['taskFilterSession','tasks'],['skillFilterSession','skills']].forEach(function(pair){
|
|
8220
|
+
var selId=pair[0];
|
|
8221
|
+
var viewKey=pair[1];
|
|
8222
|
+
var viewSessions=getSessionsForView(viewKey);
|
|
8223
|
+
const fSel=document.getElementById(selId);
|
|
8224
|
+
if(!fSel) return;
|
|
7789
8225
|
const curVal=activeSession||'';
|
|
7790
|
-
var sessionCount=
|
|
8226
|
+
var sessionCount=viewSessions.length;
|
|
8227
|
+
fSel.style.display=sessionCount>0?'':'none';
|
|
7791
8228
|
fSel.innerHTML='<option value="">'+t('filter.allsessions')+' ('+sessionCount+')</option>';
|
|
7792
|
-
|
|
8229
|
+
viewSessions.forEach(s=>{
|
|
7793
8230
|
const sName=s.session_key.length>30?s.session_key.slice(0,12)+'...'+s.session_key.slice(-10):s.session_key;
|
|
7794
|
-
|
|
8231
|
+
const countLabel=(s.count&&s.count>0)?' ('+s.count+')':'';
|
|
8232
|
+
fSel.innerHTML+='<option value="'+s.session_key.replace(/"/g,'"')+'"'+(s.session_key===curVal?' selected':'')+'>'+sName+countLabel+'</option>';
|
|
7795
8233
|
});
|
|
7796
|
-
}
|
|
8234
|
+
});
|
|
7797
8235
|
|
|
7798
|
-
|
|
7799
|
-
if(ownerSel && d.owners && d.owners.length>0){
|
|
7800
|
-
const curVal=ownerSel.value;
|
|
8236
|
+
if(d.owners && d.owners.length>0){
|
|
7801
8237
|
var agents=d.owners.filter(function(o){return o && o.indexOf('agent:')===0;});
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
8238
|
+
['filterOwner','taskFilterOwner','skillFilterOwner'].forEach(function(selId){
|
|
8239
|
+
var sel=document.getElementById(selId);
|
|
8240
|
+
if(!sel) return;
|
|
8241
|
+
var curVal=sel.value;
|
|
8242
|
+
sel.innerHTML='<option value="">'+t('filter.allagents')+'</option>';
|
|
8243
|
+
agents.forEach(function(o){
|
|
8244
|
+
var label=o.replace('agent:','');
|
|
8245
|
+
sel.innerHTML+='<option value="'+o+'"'+(o===curVal?' selected':'')+'>'+label+'</option>';
|
|
8246
|
+
});
|
|
8247
|
+
if(agents.length<=1) sel.style.display='none';
|
|
8248
|
+
else sel.style.display='';
|
|
7806
8249
|
});
|
|
7807
|
-
if(agents.length<=1) ownerSel.style.display='none';
|
|
7808
|
-
else ownerSel.style.display='';
|
|
7809
8250
|
}
|
|
7810
8251
|
}
|
|
7811
8252
|
|
|
7812
8253
|
function onOwnerFilterChange(){
|
|
7813
|
-
var
|
|
8254
|
+
var src=event&&event.target?event.target:document.getElementById('filterOwner');
|
|
8255
|
+
var owner=src.value;
|
|
8256
|
+
['filterOwner','taskFilterOwner','skillFilterOwner'].forEach(function(id){
|
|
8257
|
+
var el=document.getElementById(id);
|
|
8258
|
+
if(el&&el!==src) el.value=owner;
|
|
8259
|
+
});
|
|
7814
8260
|
activeSession=null;
|
|
7815
8261
|
currentPage=1;
|
|
8262
|
+
taskSearchQuery='';
|
|
8263
|
+
var tsi=document.getElementById('taskSearchInput');if(tsi)tsi.value='';
|
|
7816
8264
|
refreshSessionDropdown(owner);
|
|
7817
8265
|
applyFilters();
|
|
8266
|
+
loadTasks();
|
|
8267
|
+
loadSkills();
|
|
7818
8268
|
}
|
|
7819
8269
|
|
|
7820
8270
|
async function refreshSessionDropdown(ownerFilter){
|
|
@@ -7845,12 +8295,13 @@ function getFilterParams(){
|
|
|
7845
8295
|
if(dt) p.set('dateTo',dt);
|
|
7846
8296
|
const sort=document.getElementById('filterSort').value;
|
|
7847
8297
|
if(sort==='oldest') p.set('sort','oldest');
|
|
7848
|
-
const scope=memorySearchScope||'
|
|
7849
|
-
if(scope==='
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
8298
|
+
const scope=memorySearchScope||'allLocal';
|
|
8299
|
+
if(scope==='allLocal'){
|
|
8300
|
+
const owner=document.getElementById('filterOwner').value;
|
|
8301
|
+
if(owner) {
|
|
8302
|
+
p.set('owner',owner);
|
|
8303
|
+
_currentAgentOwner = owner;
|
|
8304
|
+
}
|
|
7854
8305
|
}
|
|
7855
8306
|
return p;
|
|
7856
8307
|
}
|
|
@@ -7911,6 +8362,8 @@ async function loadMemories(page,silent){
|
|
|
7911
8362
|
|
|
7912
8363
|
async function loadHubMemories(silent){
|
|
7913
8364
|
const list=document.getElementById('memoryList');
|
|
8365
|
+
selectedMemoryIds.clear();
|
|
8366
|
+
updateMemorySelectionToolbar();
|
|
7914
8367
|
if(!silent) list.innerHTML='<div class="spinner"></div>';
|
|
7915
8368
|
try{
|
|
7916
8369
|
const r=await fetch('/api/sharing/memories/list?limit='+PAGE_SIZE);
|
|
@@ -7947,7 +8400,7 @@ async function doSearch(query){
|
|
|
7947
8400
|
return;
|
|
7948
8401
|
}
|
|
7949
8402
|
currentPage=1;
|
|
7950
|
-
var scope=document.getElementById('memorySearchScope')?.value||memorySearchScope||'
|
|
8403
|
+
var scope=document.getElementById('memorySearchScope')?.value||memorySearchScope||'allLocal';
|
|
7951
8404
|
var list=document.getElementById('memoryList');
|
|
7952
8405
|
list.innerHTML='<div class="spinner"></div>';
|
|
7953
8406
|
if(scope==='hub'){
|
|
@@ -7999,12 +8452,26 @@ function debounceSearch(){
|
|
|
7999
8452
|
function filterSession(key){
|
|
8000
8453
|
activeSession=key;
|
|
8001
8454
|
currentPage=1;
|
|
8002
|
-
|
|
8003
|
-
|
|
8455
|
+
tasksPage=0;
|
|
8456
|
+
skillsPage=0;
|
|
8457
|
+
['filterSession','taskFilterSession','skillFilterSession'].forEach(function(selId){
|
|
8458
|
+
var fSel=document.getElementById(selId);
|
|
8459
|
+
if(fSel) fSel.value=key||'';
|
|
8460
|
+
});
|
|
8004
8461
|
document.querySelectorAll('#sessionList .session-item').forEach(function(el,i){
|
|
8005
8462
|
if(i===0) el.classList.toggle('active',!key);
|
|
8006
8463
|
else el.classList.toggle('active',el.querySelector('span')?.title===key);
|
|
8007
8464
|
});
|
|
8465
|
+
if(_activeView==='tasks'){
|
|
8466
|
+
loadStats();
|
|
8467
|
+
loadTasks();
|
|
8468
|
+
return;
|
|
8469
|
+
}
|
|
8470
|
+
if(_activeView==='skills'){
|
|
8471
|
+
loadStats();
|
|
8472
|
+
loadSkills();
|
|
8473
|
+
return;
|
|
8474
|
+
}
|
|
8008
8475
|
loadAll();
|
|
8009
8476
|
}
|
|
8010
8477
|
|
|
@@ -8031,14 +8498,88 @@ function clearDateFilter(){
|
|
|
8031
8498
|
applyFilters();
|
|
8032
8499
|
}
|
|
8033
8500
|
|
|
8501
|
+
function updateMemorySelectionToolbar(){
|
|
8502
|
+
var toolbar=document.getElementById('memorySelectionToolbar');
|
|
8503
|
+
var selectAllBtn=document.getElementById('memorySelectAllBtn');
|
|
8504
|
+
var bulkDeleteBtn=document.getElementById('memoryBulkDeleteBtn');
|
|
8505
|
+
var isHub=memorySearchScope==='hub';
|
|
8506
|
+
var total=document.querySelectorAll('#memoryList .memory-select-check').length;
|
|
8507
|
+
var selected=selectedMemoryIds.size;
|
|
8508
|
+
if(toolbar) toolbar.style.display=isHub?'none':'flex';
|
|
8509
|
+
if(selectAllBtn){
|
|
8510
|
+
selectAllBtn.textContent=t(selected>0&&selected===total&&total>0?'skills.unselectAll':'skills.selectAll');
|
|
8511
|
+
selectAllBtn.disabled=total===0;
|
|
8512
|
+
selectAllBtn.style.display=total===0?'none':'';
|
|
8513
|
+
}
|
|
8514
|
+
if(bulkDeleteBtn){
|
|
8515
|
+
var base=t('memory.deleteSelected');
|
|
8516
|
+
bulkDeleteBtn.style.display=selected>0?'':'none';
|
|
8517
|
+
bulkDeleteBtn.textContent=selected>0?(base+' ('+selected+')'):base;
|
|
8518
|
+
}
|
|
8519
|
+
}
|
|
8520
|
+
|
|
8521
|
+
function toggleMemorySelection(memoryId,checked){
|
|
8522
|
+
if(checked) selectedMemoryIds.add(memoryId);
|
|
8523
|
+
else selectedMemoryIds.delete(memoryId);
|
|
8524
|
+
updateMemorySelectionToolbar();
|
|
8525
|
+
}
|
|
8526
|
+
|
|
8527
|
+
function toggleSelectAllMemories(){
|
|
8528
|
+
var total=currentMemoryIds.length;
|
|
8529
|
+
if(total===0) return;
|
|
8530
|
+
if(selectedMemoryIds.size===total){
|
|
8531
|
+
selectedMemoryIds.clear();
|
|
8532
|
+
}else{
|
|
8533
|
+
selectedMemoryIds=new Set(currentMemoryIds);
|
|
8534
|
+
}
|
|
8535
|
+
var checks=document.querySelectorAll('#memoryList .memory-select-check');
|
|
8536
|
+
checks.forEach(function(cb){cb.checked=selectedMemoryIds.has(cb.value);});
|
|
8537
|
+
updateMemorySelectionToolbar();
|
|
8538
|
+
}
|
|
8539
|
+
|
|
8540
|
+
async function deleteSelectedMemories(){
|
|
8541
|
+
var ids=Array.from(selectedMemoryIds);
|
|
8542
|
+
if(ids.length===0) return;
|
|
8543
|
+
var msg=t('memory.delete.selected.confirm').replace('{count}',String(ids.length));
|
|
8544
|
+
if(!(await confirmModal(msg,{danger:true}))) return;
|
|
8545
|
+
var ok=0;
|
|
8546
|
+
var fail=0;
|
|
8547
|
+
for(var i=0;i<ids.length;i++){
|
|
8548
|
+
try{
|
|
8549
|
+
var r=await fetch('/api/memory/'+ids[i],{method:'DELETE'});
|
|
8550
|
+
var d=await r.json();
|
|
8551
|
+
if(!d.ok) throw new Error(d.error||'unknown');
|
|
8552
|
+
ok++;
|
|
8553
|
+
}catch(e){
|
|
8554
|
+
fail++;
|
|
8555
|
+
}
|
|
8556
|
+
}
|
|
8557
|
+
selectedMemoryIds.clear();
|
|
8558
|
+
updateMemorySelectionToolbar();
|
|
8559
|
+
if(document.getElementById('searchInput').value.trim()){
|
|
8560
|
+
doSearch(document.getElementById('searchInput').value);
|
|
8561
|
+
}else if(memorySearchScope==='hub'){
|
|
8562
|
+
loadHubMemories();
|
|
8563
|
+
}else{
|
|
8564
|
+
loadMemories();
|
|
8565
|
+
}
|
|
8566
|
+
if(fail>0) toast(t('memory.delete.partial').replace('{ok}',String(ok)).replace('{fail}',String(fail)),'warn');
|
|
8567
|
+
else toast(t('memory.delete.success').replace('{count}',String(ok)),'success');
|
|
8568
|
+
}
|
|
8569
|
+
|
|
8034
8570
|
/* ─── Rendering ─── */
|
|
8035
8571
|
function renderMemories(items){
|
|
8036
8572
|
const list=document.getElementById('memoryList');
|
|
8573
|
+
setPageSizeVisible('memoryPageSize',items.length>0);
|
|
8037
8574
|
if(!items.length){
|
|
8038
8575
|
list.innerHTML='<div class="empty"><div class="icon">\\u{1F4ED}</div><p>'+t('empty.text')+'</p></div>';
|
|
8576
|
+
currentMemoryIds=[];
|
|
8577
|
+
updateMemorySelectionToolbar();
|
|
8039
8578
|
return;
|
|
8040
8579
|
}
|
|
8041
8580
|
items.forEach(m=>{memoryCache[m.id]=m});
|
|
8581
|
+
currentMemoryIds=items.map(function(m){return m.id;});
|
|
8582
|
+
selectedMemoryIds=new Set(Array.from(selectedMemoryIds).filter(function(id){return currentMemoryIds.includes(id);}));
|
|
8042
8583
|
list.innerHTML=items.map(m=>{
|
|
8043
8584
|
const time=m.created_at?new Date(typeof m.created_at==='number'?m.created_at:m.created_at).toLocaleString(dateLoc()):'';
|
|
8044
8585
|
const role=m.role||'user';
|
|
@@ -8065,6 +8606,8 @@ function renderMemories(items){
|
|
|
8065
8606
|
const isHubScope=memorySearchScope==='hub';
|
|
8066
8607
|
const memScope=memShared?'team':isPublicMem?'local':'private';
|
|
8067
8608
|
const memScopeBadge=isHubScope?renderScopeBadge('team'):renderScopeBadge(memScope);
|
|
8609
|
+
const selectedAttr=selectedMemoryIds.has(id)?' checked':'';
|
|
8610
|
+
const selectBoxHtml=isHubScope?'':'<label class="item-select-box" onclick="event.stopPropagation()"><input class="memory-select-check" type="checkbox" value="'+escAttr(id)+'"'+selectedAttr+' onchange="event.stopPropagation();toggleMemorySelection("'+escAttr(id)+'",this.checked)"></label>';
|
|
8068
8611
|
let dedupInfo='';
|
|
8069
8612
|
if(ds==='duplicate'||ds==='merged'){
|
|
8070
8613
|
const reason=m.dedup_reason?'<span style="font-size:11px;color:var(--text-muted)">'+t('card.dedupReason')+esc(m.dedup_reason)+'</span>':'';
|
|
@@ -8090,7 +8633,7 @@ function renderMemories(items){
|
|
|
8090
8633
|
}
|
|
8091
8634
|
return '<div class="memory-card'+(isInactive?' dedup-inactive':'')+'">'+
|
|
8092
8635
|
'<div class="card-header"><div class="meta"><span class="role-tag '+role+'">'+role+'</span>'+memScopeBadge+importBadge+dedupBadge+mergeBadge+'</div><span class="card-time"><span class="session-tag" title="'+esc(sid)+'">'+esc(sidShort)+'</span> '+time+updatedAt+'</span></div>'+
|
|
8093
|
-
'<div class="card-summary">'+cardTitle+'</div>'+
|
|
8636
|
+
'<div class="card-summary">'+selectBoxHtml+cardTitle+'</div>'+
|
|
8094
8637
|
(function(){
|
|
8095
8638
|
if(mc<=0) return '';
|
|
8096
8639
|
var mergeHtml='<div class="card-merged-info">';
|
|
@@ -8120,6 +8663,7 @@ function renderMemories(items){
|
|
|
8120
8663
|
vscore+
|
|
8121
8664
|
'</div></div>';
|
|
8122
8665
|
}).join('');
|
|
8666
|
+
updateMemorySelectionToolbar();
|
|
8123
8667
|
}
|
|
8124
8668
|
|
|
8125
8669
|
function updateMemoryCardBadge(chunkId,newScope){
|
|
@@ -8322,7 +8866,18 @@ async function deleteMemory(id){
|
|
|
8322
8866
|
if(!(await confirmModal(t('confirm.delete'),{danger:true})))return;
|
|
8323
8867
|
const r=await fetch('/api/memory/'+id,{method:'DELETE'});
|
|
8324
8868
|
const d=await r.json();
|
|
8325
|
-
if(d.ok){
|
|
8869
|
+
if(d.ok){
|
|
8870
|
+
selectedMemoryIds.delete(id);
|
|
8871
|
+
updateMemorySelectionToolbar();
|
|
8872
|
+
toast(t('toast.deleted'),'success');
|
|
8873
|
+
if(document.getElementById('searchInput').value.trim()){
|
|
8874
|
+
doSearch(document.getElementById('searchInput').value);
|
|
8875
|
+
}else if(memorySearchScope==='hub'){
|
|
8876
|
+
loadHubMemories();
|
|
8877
|
+
}else{
|
|
8878
|
+
loadMemories();
|
|
8879
|
+
}
|
|
8880
|
+
}
|
|
8326
8881
|
else{toast(t('toast.delfail'),'error')}
|
|
8327
8882
|
}
|
|
8328
8883
|
|
|
@@ -9126,12 +9681,16 @@ async function checkForUpdate(){
|
|
|
9126
9681
|
/* ─── Init ─── */
|
|
9127
9682
|
try{
|
|
9128
9683
|
var savedScope=localStorage.getItem('memos_memorySearchScope');
|
|
9129
|
-
if(savedScope
|
|
9684
|
+
if(savedScope==='local') savedScope='allLocal';
|
|
9685
|
+
if(savedScope&&(savedScope==='allLocal'||savedScope==='hub')){
|
|
9130
9686
|
memorySearchScope=savedScope;
|
|
9131
9687
|
var scopeEl=document.getElementById('memorySearchScope');
|
|
9132
9688
|
if(scopeEl) scopeEl.value=savedScope;
|
|
9133
9689
|
}
|
|
9134
9690
|
}catch(e){}
|
|
9691
|
+
restorePageSizeSetting('memos_memoryPageSize','memoryPageSize',20,function(next){PAGE_SIZE=next;});
|
|
9692
|
+
restorePageSizeSetting('memos_skillsPageSize','skillsPageSize',20,function(next){skillsPageSize=next;});
|
|
9693
|
+
restorePageSizeSetting('memos_tasksPageSize','tasksPageSize',20,function(next){tasksPageSize=next;});
|
|
9135
9694
|
document.getElementById('modalOverlay').addEventListener('click',e=>{if(e.target.id==='modalOverlay')closeModal()});
|
|
9136
9695
|
document.getElementById('searchInput').addEventListener('keydown',e=>{if(e.key==='Escape'){e.target.value='';currentPage=1;if(memorySearchScope==='hub')loadHubMemories();else loadMemories();}});
|
|
9137
9696
|
applyI18n();
|