@memtensor/memos-local-openclaw-plugin 1.0.8-beta → 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/index.ts +5 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/storage/sqlite.ts +140 -4
- package/src/viewer/html.ts +579 -212
- package/src/viewer/server.ts +177 -8
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,9 +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}
|
|
700
|
-
.
|
|
701
|
-
|
|
702
|
-
.
|
|
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}
|
|
703
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)}
|
|
704
726
|
.skill-version-item{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px}
|
|
705
727
|
.skill-version-header{display:flex;align-items:center;gap:10px;margin-bottom:6px}
|
|
@@ -1228,8 +1250,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1228
1250
|
<div class="sidebar" id="sidebar">
|
|
1229
1251
|
<div class="stats-grid" id="statsGrid">
|
|
1230
1252
|
<div class="stat-card pri"><div class="stat-value" id="statTotal">-</div><div class="stat-label" data-i18n="stat.memories">Memories</div></div>
|
|
1231
|
-
<div class="stat-card green"><div class="stat-value" id="
|
|
1232
|
-
<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>
|
|
1233
1255
|
<div class="stat-card rose"><div class="stat-value" id="statAgents">-</div><div class="stat-label" data-i18n="stat.agents">Agents</div></div>
|
|
1234
1256
|
</div>
|
|
1235
1257
|
<div id="sidebarSharingSection" style="display:none">
|
|
@@ -1240,8 +1262,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1240
1262
|
</div>
|
|
1241
1263
|
</div>
|
|
1242
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>
|
|
1243
1266
|
<div class="session-list" id="sessionList" style="display:none"></div>
|
|
1244
|
-
<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>
|
|
1245
1267
|
</div>
|
|
1246
1268
|
|
|
1247
1269
|
<div class="view-container">
|
|
@@ -1257,15 +1279,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1257
1279
|
<option value="allLocal" data-i18n="scope.thisDevice">This Device</option>
|
|
1258
1280
|
<option value="hub" data-i18n="scope.hub">Team</option>
|
|
1259
1281
|
</select>
|
|
1260
|
-
<select id="memoryPageSize" class="filter-select" onchange="onMemoryPageSizeChange()">
|
|
1261
|
-
<option value="10">10 / page</option>
|
|
1262
|
-
<option value="20" selected>20 / page</option>
|
|
1263
|
-
<option value="40">40 / page</option>
|
|
1264
|
-
</select>
|
|
1265
1282
|
</div>
|
|
1266
|
-
<div
|
|
1267
|
-
<div
|
|
1268
|
-
<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">
|
|
1269
1286
|
<button class="filter-chip active" data-role="" onclick="setRoleFilter(this,'')" data-i18n="filter.all">All</button>
|
|
1270
1287
|
<button class="filter-chip" data-role="user" onclick="setRoleFilter(this,'user')">User</button>
|
|
1271
1288
|
<button class="filter-chip" data-role="assistant" onclick="setRoleFilter(this,'assistant')">Assistant</button>
|
|
@@ -1274,46 +1291,48 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1274
1291
|
<option value="newest" data-i18n="filter.newest">Newest first</option>
|
|
1275
1292
|
<option value="oldest" data-i18n="filter.oldest">Oldest first</option>
|
|
1276
1293
|
</select>
|
|
1277
|
-
<span
|
|
1278
|
-
<
|
|
1279
|
-
|
|
1280
|
-
</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>
|
|
1281
1297
|
</div>
|
|
1282
|
-
<div class="
|
|
1283
|
-
<
|
|
1284
|
-
<
|
|
1285
|
-
<
|
|
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>
|
|
1286
1303
|
</div>
|
|
1287
1304
|
<div class="memory-list" id="memoryList"><div class="spinner"></div></div>
|
|
1288
|
-
<div class="pagination"
|
|
1305
|
+
<div class="pagination-row">
|
|
1306
|
+
<div class="pagination" id="pagination"></div>
|
|
1307
|
+
</div>
|
|
1289
1308
|
</div>
|
|
1290
1309
|
</div>
|
|
1291
1310
|
<div class="tasks-view vp" id="tasksView">
|
|
1292
|
-
<div class="
|
|
1293
|
-
<
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
<
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
<
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
</select>
|
|
1313
|
-
</div>
|
|
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>
|
|
1314
1331
|
</div>
|
|
1315
1332
|
<div class="tasks-list" id="tasksList"><div class="spinner"></div></div>
|
|
1316
|
-
<div class="pagination"
|
|
1333
|
+
<div class="pagination-row">
|
|
1334
|
+
<div class="pagination" id="tasksPagination"></div>
|
|
1335
|
+
</div>
|
|
1317
1336
|
<div class="task-detail-overlay" id="taskDetailOverlay" onclick="closeTaskDetail(event)">
|
|
1318
1337
|
<div class="task-detail-panel" onclick="event.stopPropagation()">
|
|
1319
1338
|
<div class="task-detail-header">
|
|
@@ -1347,43 +1366,33 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1347
1366
|
<div class="search-bar">
|
|
1348
1367
|
<span class="search-icon">🔍</span>
|
|
1349
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>
|
|
1350
1372
|
<select id="skillSearchScope" class="scope-select" onchange="onSkillScopeChange()" style="display:none">
|
|
1351
1373
|
<option value="allLocal" data-i18n="scope.thisDevice">This Device</option>
|
|
1352
1374
|
<option value="hub" data-i18n="scope.hub">Team</option>
|
|
1353
1375
|
</select>
|
|
1354
|
-
<select id="skillsPageSize" class="filter-select" onchange="onSkillsPageSizeChange()">
|
|
1355
|
-
<option value="10">10 / page</option>
|
|
1356
|
-
<option value="20" selected>20 / page</option>
|
|
1357
|
-
<option value="40">40 / page</option>
|
|
1358
|
-
</select>
|
|
1359
1376
|
</div>
|
|
1360
|
-
<div
|
|
1361
|
-
<div class="
|
|
1362
|
-
<
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
<
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
<select id="skillVisibilityFilter" class="filter-select" onchange="loadSkills()" style="display:none">
|
|
1375
|
-
<option value="" data-i18n="filter.allvisibility">All visibility</option>
|
|
1376
|
-
<option value="public" data-i18n="filter.public">Public</option>
|
|
1377
|
-
<option value="private" data-i18n="filter.private">Private</option>
|
|
1378
|
-
</select>
|
|
1379
|
-
</div>
|
|
1380
|
-
<div class="skill-selection-toolbar">
|
|
1381
|
-
<button class="btn btn-sm btn-ghost" id="skillSelectAllBtn" onclick="toggleSelectAllSkills()" data-i18n="skills.selectAll">Select All</button>
|
|
1382
|
-
<button class="btn btn-sm btn-danger" id="skillBulkDeleteBtn" onclick="deleteSelectedSkills()" disabled data-i18n="skills.deleteSelected">Delete Selected</button>
|
|
1383
|
-
</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>
|
|
1384
1391
|
</div>
|
|
1385
1392
|
<div class="tasks-list" id="skillsList"><div class="spinner"></div></div>
|
|
1386
|
-
<div class="pagination"
|
|
1393
|
+
<div class="pagination-row">
|
|
1394
|
+
<div class="pagination" id="skillsPagination"></div>
|
|
1395
|
+
</div>
|
|
1387
1396
|
<div id="hubSkillsSection" style="display:none;margin-top:16px">
|
|
1388
1397
|
<div class="section-title" style="margin-bottom:12px" data-i18n="skills.hub.title">\u{1F310} Team Skills</div>
|
|
1389
1398
|
<div class="tasks-list" id="hubSkillsList"></div>
|
|
@@ -2052,6 +2061,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
2052
2061
|
let activeSession=null,activeRole='',editingId=null,searchTimer=null,memoryCache={},currentPage=1,totalPages=1,totalCount=0,PAGE_SIZE=20,metricsDays=30;
|
|
2053
2062
|
let memorySearchScope='allLocal',skillSearchScope='allLocal',taskSearchScope='allLocal';
|
|
2054
2063
|
let _lastMemoriesFingerprint='',_lastTasksFingerprint='',_lastSkillsFingerprint='';
|
|
2064
|
+
let selectedMemoryIds=new Set(),currentMemoryIds=[];
|
|
2065
|
+
let selectedTaskIds=new Set(),currentTaskIds=[];
|
|
2055
2066
|
let _embeddingWarningShown=false;
|
|
2056
2067
|
let _currentAgentOwner='agent:main';
|
|
2057
2068
|
try {
|
|
@@ -2126,6 +2137,8 @@ const I18N={
|
|
|
2126
2137
|
'tasks.status.active':'Active',
|
|
2127
2138
|
'tasks.status.completed':'Completed',
|
|
2128
2139
|
'tasks.status.skipped':'Skipped',
|
|
2140
|
+
'tasks.search.placeholder':'Search tasks...',
|
|
2141
|
+
'tasks.search.meta':'Found {0} tasks',
|
|
2129
2142
|
'tasks.empty':'No tasks yet. Tasks are automatically created as you converse.',
|
|
2130
2143
|
'tasks.loading':'Loading...',
|
|
2131
2144
|
'tasks.untitled':'Untitled Task',
|
|
@@ -2166,8 +2179,8 @@ const I18N={
|
|
|
2166
2179
|
'notif.timeAgo.hour':'{n}h ago',
|
|
2167
2180
|
'notif.timeAgo.day':'{n}d ago',
|
|
2168
2181
|
'stat.memories':'Memories',
|
|
2169
|
-
'stat.
|
|
2170
|
-
'stat.
|
|
2182
|
+
'stat.tasks':'Tasks',
|
|
2183
|
+
'stat.skills':'Skills',
|
|
2171
2184
|
'stat.agents':'Agents',
|
|
2172
2185
|
'stat.active':'active',
|
|
2173
2186
|
'stat.deduped':'deduped',
|
|
@@ -2207,6 +2220,7 @@ const I18N={
|
|
|
2207
2220
|
'card.dedupTarget':'Target: ',
|
|
2208
2221
|
'card.dedupReason':'Reason: ',
|
|
2209
2222
|
'card.newSummary':'New',
|
|
2223
|
+
'pagination.pageSize':'Items per page',
|
|
2210
2224
|
'pagination.total':' total',
|
|
2211
2225
|
'range':'Range',
|
|
2212
2226
|
'range.days':'days',
|
|
@@ -2413,7 +2427,13 @@ const I18N={
|
|
|
2413
2427
|
'skills.nochangelog':'No changelog',
|
|
2414
2428
|
'skills.status.active':'Active',
|
|
2415
2429
|
'skills.status.draft':'Draft',
|
|
2416
|
-
'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: ',
|
|
2417
2437
|
'skills.updated':'Updated: ',
|
|
2418
2438
|
'skills.task.prefix':'Task: ',
|
|
2419
2439
|
'skills.selectAll':'Select All',
|
|
@@ -2759,6 +2779,10 @@ const I18N={
|
|
|
2759
2779
|
'task.cancel':'Cancel',
|
|
2760
2780
|
'task.delete.confirm':'Are you sure you want to delete this task? This cannot be undone.',
|
|
2761
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}.',
|
|
2762
2786
|
'task.save.error':'Failed to save task: ',
|
|
2763
2787
|
'task.retrySkill':'Retry Skill Generation',
|
|
2764
2788
|
'task.retrySkill.short':'Retry Skill',
|
|
@@ -2773,6 +2797,10 @@ const I18N={
|
|
|
2773
2797
|
'skill.delete.error':'Failed to delete skill: ',
|
|
2774
2798
|
'skill.delete.partial':'Deleted {ok} skills, failed {fail}.',
|
|
2775
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}.',
|
|
2776
2804
|
'skill.save.error':'Failed to save skill: ',
|
|
2777
2805
|
'update.available':'New version available',
|
|
2778
2806
|
'update.run':'Run',
|
|
@@ -2876,6 +2904,8 @@ const I18N={
|
|
|
2876
2904
|
'tasks.status.active':'进行中',
|
|
2877
2905
|
'tasks.status.completed':'已完成',
|
|
2878
2906
|
'tasks.status.skipped':'已跳过',
|
|
2907
|
+
'tasks.search.placeholder':'搜索任务...',
|
|
2908
|
+
'tasks.search.meta':'找到 {0} 个任务',
|
|
2879
2909
|
'tasks.empty':'暂无任务。任务会随着对话自动创建。',
|
|
2880
2910
|
'tasks.loading':'加载中...',
|
|
2881
2911
|
'tasks.untitled':'未命名任务',
|
|
@@ -2916,8 +2946,8 @@ const I18N={
|
|
|
2916
2946
|
'notif.timeAgo.hour':'{n}小时前',
|
|
2917
2947
|
'notif.timeAgo.day':'{n}天前',
|
|
2918
2948
|
'stat.memories':'记忆',
|
|
2919
|
-
'stat.
|
|
2920
|
-
'stat.
|
|
2949
|
+
'stat.tasks':'任务',
|
|
2950
|
+
'stat.skills':'技能',
|
|
2921
2951
|
'stat.agents':'智能体',
|
|
2922
2952
|
'stat.active':'活跃',
|
|
2923
2953
|
'stat.deduped':'已去重',
|
|
@@ -2957,6 +2987,7 @@ const I18N={
|
|
|
2957
2987
|
'card.dedupTarget':'关联: ',
|
|
2958
2988
|
'card.dedupReason':'原因: ',
|
|
2959
2989
|
'card.newSummary':'新摘要',
|
|
2990
|
+
'pagination.pageSize':'每页数量',
|
|
2960
2991
|
'pagination.total':' 条',
|
|
2961
2992
|
'range':'范围',
|
|
2962
2993
|
'range.days':'天',
|
|
@@ -3163,7 +3194,13 @@ const I18N={
|
|
|
3163
3194
|
'skills.nochangelog':'暂无变更记录',
|
|
3164
3195
|
'skills.status.active':'生效中',
|
|
3165
3196
|
'skills.status.draft':'草稿',
|
|
3166
|
-
'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':'启用技能失败:',
|
|
3167
3204
|
'skills.updated':'更新于:',
|
|
3168
3205
|
'skills.task.prefix':'任务:',
|
|
3169
3206
|
'skills.selectAll':'全选',
|
|
@@ -3509,6 +3546,10 @@ const I18N={
|
|
|
3509
3546
|
'task.cancel':'取消',
|
|
3510
3547
|
'task.delete.confirm':'确定要删除此任务吗?此操作不可撤销。',
|
|
3511
3548
|
'task.delete.error':'删除任务失败:',
|
|
3549
|
+
'task.deleteSelected':'删除选中',
|
|
3550
|
+
'task.delete.selected.confirm':'确定删除选中的 {count} 个任务吗?此操作不可撤销。',
|
|
3551
|
+
'task.delete.success':'已删除 {count} 个任务。',
|
|
3552
|
+
'task.delete.partial':'已删除 {ok} 个任务,失败 {fail} 个。',
|
|
3512
3553
|
'task.save.error':'保存任务失败:',
|
|
3513
3554
|
'task.retrySkill':'重新生成技能',
|
|
3514
3555
|
'task.retrySkill.short':'重试技能',
|
|
@@ -3523,6 +3564,10 @@ const I18N={
|
|
|
3523
3564
|
'skill.delete.error':'删除技能失败:',
|
|
3524
3565
|
'skill.delete.partial':'已删除 {ok} 个技能,失败 {fail} 个。',
|
|
3525
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} 条。',
|
|
3526
3571
|
'skill.save.error':'保存技能失败:',
|
|
3527
3572
|
'update.available':'发现新版本',
|
|
3528
3573
|
'update.run':'执行命令',
|
|
@@ -3807,9 +3852,12 @@ function switchView(view){
|
|
|
3807
3852
|
}
|
|
3808
3853
|
var sessionSection=document.getElementById('sidebarSessionSection');
|
|
3809
3854
|
if(sessionSection){
|
|
3810
|
-
if(view==='memories'){sessionSection.style.visibility='';sessionSection.style.pointerEvents='';}
|
|
3855
|
+
if(view==='memories'||view==='tasks'||view==='skills'){sessionSection.style.visibility='';sessionSection.style.pointerEvents='';}
|
|
3811
3856
|
else{sessionSection.style.visibility='hidden';sessionSection.style.pointerEvents='none';}
|
|
3812
3857
|
}
|
|
3858
|
+
if(view==='memories'||view==='tasks'||view==='skills'){
|
|
3859
|
+
loadStats();
|
|
3860
|
+
}
|
|
3813
3861
|
if(view==='tasks') loadTasks();
|
|
3814
3862
|
else if(view==='skills') loadSkills();
|
|
3815
3863
|
else if(view==='analytics') loadMetrics();
|
|
@@ -3831,6 +3879,7 @@ function onMemoryScopeChange(){
|
|
|
3831
3879
|
currentPage=1;
|
|
3832
3880
|
activeSession=null;activeRole='';
|
|
3833
3881
|
_lastMemoriesFingerprint='';
|
|
3882
|
+
if(memorySearchScope==='hub') selectedMemoryIds.clear();
|
|
3834
3883
|
var isHub=memorySearchScope==='hub';
|
|
3835
3884
|
var ownerSel=document.getElementById('filterOwner');
|
|
3836
3885
|
var filterBar=document.getElementById('filterBar');
|
|
@@ -3838,6 +3887,7 @@ function onMemoryScopeChange(){
|
|
|
3838
3887
|
if(ownerSel){ownerSel.style.display=isHub?'none':'';if(isHub)ownerSel.value='';}
|
|
3839
3888
|
if(filterBar) filterBar.style.display=isHub?'none':'';
|
|
3840
3889
|
if(dateFilter) dateFilter.style.display=isHub?'none':'';
|
|
3890
|
+
updateMemorySelectionToolbar();
|
|
3841
3891
|
if(document.getElementById('searchInput').value.trim()) doSearch(document.getElementById('searchInput').value);
|
|
3842
3892
|
else if(isHub) { document.getElementById('sharingSearchMeta').textContent=''; loadHubMemories(); }
|
|
3843
3893
|
else {
|
|
@@ -3899,7 +3949,9 @@ function onTasksPageSizeChange(){
|
|
|
3899
3949
|
|
|
3900
3950
|
function onTaskScopeChange(){
|
|
3901
3951
|
taskSearchScope=document.getElementById('taskSearchScope')?.value||'allLocal';
|
|
3952
|
+
if(taskSearchScope==='hub') selectedTaskIds.clear();
|
|
3902
3953
|
tasksPage=0;
|
|
3954
|
+
updateTaskSelectionToolbar();
|
|
3903
3955
|
loadTasks();
|
|
3904
3956
|
}
|
|
3905
3957
|
|
|
@@ -5124,6 +5176,7 @@ function renderSharingMemorySearchResults(data,query){
|
|
|
5124
5176
|
const list=document.getElementById('memoryList');
|
|
5125
5177
|
const localHits=(data&&data.local&&Array.isArray(data.local.hits))?data.local.hits:[];
|
|
5126
5178
|
const hubHits=(data&&data.hub&&Array.isArray(data.hub.hits))?data.hub.hits:[];
|
|
5179
|
+
setPageSizeVisible('memoryPageSize',(localHits.length+hubHits.length)>0);
|
|
5127
5180
|
document.getElementById('searchMeta').textContent='Search results for "'+query+'"';
|
|
5128
5181
|
document.getElementById('sharingSearchMeta').textContent=t('scope.local')+' '+localHits.length+' · '+t('scope.hub')+' '+hubHits.length;
|
|
5129
5182
|
document.getElementById('pagination').innerHTML='';
|
|
@@ -5912,6 +5965,11 @@ function escapeHtml(s){
|
|
|
5912
5965
|
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
5913
5966
|
}
|
|
5914
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
|
+
|
|
5915
5973
|
function setMetricsDays(d){
|
|
5916
5974
|
metricsDays=d;
|
|
5917
5975
|
document.querySelectorAll('.metrics-toolbar .range-btn').forEach(btn=>btn.classList.toggle('active',Number(btn.dataset.days)===d));
|
|
@@ -5931,6 +5989,7 @@ async function loadMetrics(){
|
|
|
5931
5989
|
}catch(e){console.error('loadMetrics',e)}
|
|
5932
5990
|
}
|
|
5933
5991
|
|
|
5992
|
+
function _st(id,v){var e=document.getElementById(id);if(e)e.textContent=v;}
|
|
5934
5993
|
function formatNum(n){return n>=1e6?(n/1e6).toFixed(1)+'M':n>=1e3?(n/1e3).toFixed(1)+'k':String(n);}
|
|
5935
5994
|
function dateLoc(){return curLang==='zh'?'zh-CN':'en-US';}
|
|
5936
5995
|
|
|
@@ -5940,13 +5999,127 @@ let tasksPage=0;
|
|
|
5940
5999
|
let tasksPageSize=20;
|
|
5941
6000
|
|
|
5942
6001
|
function setTaskStatusFilter(btn,status){
|
|
5943
|
-
document.querySelectorAll('.tasks-
|
|
6002
|
+
document.querySelectorAll('.tasks-view .filter-bar .filter-chip[data-task-status]').forEach(c=>c.classList.remove('active'));
|
|
5944
6003
|
btn.classList.add('active');
|
|
5945
6004
|
tasksStatusFilter=status;
|
|
5946
6005
|
tasksPage=0;
|
|
5947
6006
|
loadTasks();
|
|
5948
6007
|
}
|
|
5949
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
|
+
|
|
5950
6123
|
async function loadTasks(silent){
|
|
5951
6124
|
const scope=document.getElementById('taskSearchScope')?document.getElementById('taskSearchScope').value:taskSearchScope;
|
|
5952
6125
|
taskSearchScope=scope||'allLocal';
|
|
@@ -5954,15 +6127,41 @@ async function loadTasks(silent){
|
|
|
5954
6127
|
const list=document.getElementById('tasksList');
|
|
5955
6128
|
if(!silent) list.innerHTML='<div class="spinner"></div>';
|
|
5956
6129
|
try{
|
|
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
|
+
|
|
5957
6151
|
const params=new URLSearchParams({limit:String(tasksPageSize),offset:String(tasksPage*tasksPageSize)});
|
|
5958
6152
|
if(tasksStatusFilter) params.set('status',tasksStatusFilter);
|
|
6153
|
+
if(activeSession) params.set('session',activeSession);
|
|
6154
|
+
if(ownerVal) params.set('owner',ownerVal);
|
|
5959
6155
|
var baseP=new URLSearchParams();
|
|
6156
|
+
if(activeSession) baseP.set('session',activeSession);
|
|
6157
|
+
if(ownerVal) baseP.set('owner',ownerVal);
|
|
6158
|
+
var baseQuery=baseP.toString();
|
|
5960
6159
|
const [data,allD,activeD,compD,skipD]=await Promise.all([
|
|
5961
6160
|
fetch('/api/tasks?'+params).then(r=>r.json()),
|
|
5962
|
-
fetch('/api/tasks?limit=1&offset=0&'+
|
|
5963
|
-
fetch('/api/tasks?status=active&limit=1&offset=0&'+
|
|
5964
|
-
fetch('/api/tasks?status=completed&limit=1&offset=0&'+
|
|
5965
|
-
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())
|
|
5966
6165
|
]);
|
|
5967
6166
|
if(silent){
|
|
5968
6167
|
var fp=JSON.stringify((data.tasks||[]).map(function(tk){return tk.id+'|'+tk.status+'|'+(tk.updatedAt||tk.startedAt)}));
|
|
@@ -5972,50 +6171,24 @@ async function loadTasks(silent){
|
|
|
5972
6171
|
}else{
|
|
5973
6172
|
_lastTasksFingerprint='';
|
|
5974
6173
|
}
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
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);
|
|
5979
6180
|
|
|
5980
6181
|
if(!data.tasks||data.tasks.length===0){
|
|
5981
|
-
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px" data-i18n="tasks.empty">'+t('tasks.empty')+'</div>';
|
|
5982
6182
|
document.getElementById('tasksPagination').innerHTML='';
|
|
5983
|
-
|
|
6183
|
+
} else {
|
|
6184
|
+
renderTasksPagination(data.total);
|
|
5984
6185
|
}
|
|
5985
|
-
|
|
5986
|
-
list.innerHTML=data.tasks.map(task=>{
|
|
5987
|
-
const timeStr=formatTime(task.startedAt);
|
|
5988
|
-
const endStr=task.endedAt?formatTime(task.endedAt):'';
|
|
5989
|
-
const durationStr=task.endedAt?formatDuration(task.endedAt-task.startedAt):'';
|
|
5990
|
-
var taskIsLocalShared=task.owner==='public';
|
|
5991
|
-
var taskIsTeamShared=!!task.sharingVisibility;
|
|
5992
|
-
var taskScope=taskIsTeamShared?'team':taskIsLocalShared?'local':'private';
|
|
5993
|
-
return '<div class="task-card status-'+task.status+'" onclick="openTaskDetail(\\''+task.id+'\\')">'+
|
|
5994
|
-
'<div class="task-card-top">'+
|
|
5995
|
-
'<div class="task-card-title">'+esc(task.title)+'</div>'+
|
|
5996
|
-
'<div class="task-card-badges">'+renderScopeBadge(taskScope)+'<span class="task-status-badge '+task.status+'">'+t('tasks.status.'+task.status)+'</span></div>'+
|
|
5997
|
-
'</div>'+
|
|
5998
|
-
(task.summary?'<div class="task-card-summary'+(task.status==='skipped'?' skipped-reason':'')+'">'+esc(task.summary)+'</div>':'')+
|
|
5999
|
-
'<div class="task-card-bottom">'+
|
|
6000
|
-
'<span class="tag"><span class="icon">\\u{1F4C5}</span> '+timeStr+'</span>'+
|
|
6001
|
-
(durationStr?'<span class="tag"><span class="icon">\\u23F1</span> '+durationStr+'</span>':'')+
|
|
6002
|
-
'<span class="tag"><span class="icon">\\u{1F4DD}</span> '+task.chunkCount+' '+t('tasks.chunks.label')+'</span>'+
|
|
6003
|
-
'<span class="tag"><span class="icon">\\u{1F4C2}</span> '+(task.sessionKey||'').slice(0,12)+'</span>'+
|
|
6004
|
-
'</div>'+
|
|
6005
|
-
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
6006
|
-
'<button class="btn btn-sm btn-ghost" onclick="openTaskDetail(\\''+task.id+'\\')">'+t('card.expand')+'</button>'+
|
|
6007
|
-
(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>':'')+
|
|
6008
|
-
(task.status==='completed'
|
|
6009
|
-
?'<button class="btn btn-sm btn-ghost" onclick="openTaskScopeModalFromList(\\''+task.id+'\\',\\''+taskScope+'\\')">\\u270F '+t('share.shareBtn')+'</button>'
|
|
6010
|
-
:'<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>')+
|
|
6011
|
-
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteTask(\\''+task.id+'\\')">'+t('task.delete')+'</button>'+
|
|
6012
|
-
'</div>'+
|
|
6013
|
-
'</div>';
|
|
6014
|
-
}).join('');
|
|
6015
|
-
|
|
6016
|
-
renderTasksPagination(data.total);
|
|
6017
6186
|
}catch(e){
|
|
6018
6187
|
console.error('loadTasks error:',e);
|
|
6188
|
+
currentTaskIds=[];
|
|
6189
|
+
selectedTaskIds.clear();
|
|
6190
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6191
|
+
updateTaskSelectionToolbar();
|
|
6019
6192
|
list.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">Failed to load tasks: '+String(e)+'</div>';
|
|
6020
6193
|
}
|
|
6021
6194
|
}
|
|
@@ -6224,6 +6397,8 @@ async function deleteTask(taskId){
|
|
|
6224
6397
|
const r=await fetch('/api/task/'+taskId,{method:'DELETE'});
|
|
6225
6398
|
const d=await r.json();
|
|
6226
6399
|
if(!r.ok) throw new Error(d.error||'unknown');
|
|
6400
|
+
selectedTaskIds.delete(taskId);
|
|
6401
|
+
updateTaskSelectionToolbar();
|
|
6227
6402
|
closeTaskDetail();
|
|
6228
6403
|
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
6229
6404
|
loadTasks();
|
|
@@ -6240,7 +6415,7 @@ let currentLocalSkills=[];
|
|
|
6240
6415
|
let skillsFilterSignature='';
|
|
6241
6416
|
|
|
6242
6417
|
function setSkillStatusFilter(btn,status){
|
|
6243
|
-
document.querySelectorAll('.skills-view .
|
|
6418
|
+
document.querySelectorAll('.skills-view .filter-bar .filter-chip[data-skill-status]').forEach(c=>c.classList.remove('active'));
|
|
6244
6419
|
btn.classList.add('active');
|
|
6245
6420
|
skillsStatusFilter=status;
|
|
6246
6421
|
skillsPage=0;
|
|
@@ -6250,14 +6425,15 @@ function setSkillStatusFilter(btn,status){
|
|
|
6250
6425
|
function updateSkillSelectionToolbar(){
|
|
6251
6426
|
var selectAllBtn=document.getElementById('skillSelectAllBtn');
|
|
6252
6427
|
var bulkDeleteBtn=document.getElementById('skillBulkDeleteBtn');
|
|
6253
|
-
var total=
|
|
6428
|
+
var total=document.querySelectorAll('#skillsList .skill-select-check').length;
|
|
6254
6429
|
var selected=selectedSkillIds.size;
|
|
6255
6430
|
if(selectAllBtn){
|
|
6256
6431
|
selectAllBtn.textContent=t(selected>0&&selected===total&&total>0?'skills.unselectAll':'skills.selectAll');
|
|
6432
|
+
selectAllBtn.style.display=total===0?'none':'';
|
|
6257
6433
|
}
|
|
6258
6434
|
if(bulkDeleteBtn){
|
|
6259
|
-
bulkDeleteBtn.disabled=selected===0;
|
|
6260
6435
|
var base=t('skills.deleteSelected');
|
|
6436
|
+
bulkDeleteBtn.style.display=selected>0?'':'none';
|
|
6261
6437
|
bulkDeleteBtn.textContent=selected>0?(base+' ('+selected+')'):base;
|
|
6262
6438
|
}
|
|
6263
6439
|
}
|
|
@@ -6333,9 +6509,13 @@ async function loadSkills(silent){
|
|
|
6333
6509
|
try{
|
|
6334
6510
|
const params=new URLSearchParams();
|
|
6335
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);
|
|
6336
6516
|
const visFilter=document.getElementById('skillVisibilityFilter')?.value;
|
|
6337
6517
|
if(visFilter) params.set('visibility',visFilter);
|
|
6338
|
-
const filterSignature=[query,skillSearchScope,skillsStatusFilter,visFilter||''].join('|');
|
|
6518
|
+
const filterSignature=[query,skillSearchScope,skillsStatusFilter,visFilter||'',skillOwnerVal].join('|');
|
|
6339
6519
|
if(!silent&&filterSignature!==skillsFilterSignature){
|
|
6340
6520
|
skillsPage=0;
|
|
6341
6521
|
}
|
|
@@ -6381,7 +6561,7 @@ async function loadSkills(silent){
|
|
|
6381
6561
|
const selectedAttr=selectedSkillIds.has(skill.id)?' checked':'';
|
|
6382
6562
|
return '<div class="skill-card '+installedClass+' '+statusClass+'" onclick="openSkillDetail("'+escAttr(skill.id)+'")">'+
|
|
6383
6563
|
'<div class="skill-card-top">'+
|
|
6384
|
-
'<div class="skill-card-name"><label class="
|
|
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>'+
|
|
6385
6565
|
'<div class="skill-card-badges">'+
|
|
6386
6566
|
qsBadge+
|
|
6387
6567
|
'<span class="skill-badge version">v'+skill.version+'</span>'+
|
|
@@ -6401,6 +6581,13 @@ async function loadSkills(silent){
|
|
|
6401
6581
|
(skill.status==='active'
|
|
6402
6582
|
?'<button class="btn btn-sm btn-ghost" onclick="openSkillScopeModalFromList("'+escAttr(skill.id)+'","'+skillScope+'")">\\u270F '+t('share.shareBtn')+'</button>'
|
|
6403
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>'+
|
|
6404
6591
|
'</span>'+
|
|
6405
6592
|
'</div>'+
|
|
6406
6593
|
'</div>';
|
|
@@ -6414,16 +6601,16 @@ async function loadSkills(silent){
|
|
|
6414
6601
|
const pageSkills=localSkills.slice(startIndex,startIndex+skillsPageSize);
|
|
6415
6602
|
list.innerHTML=renderLocalCards(pageSkills);
|
|
6416
6603
|
renderSkillsPagination(totalLocalSkills);
|
|
6604
|
+
setPageSizeVisible('skillsPageSize',totalLocalSkills>0);
|
|
6417
6605
|
updateSkillSelectionToolbar();
|
|
6418
6606
|
|
|
6419
6607
|
if(skillSearchScope==='allLocal'){
|
|
6420
6608
|
if(hubSection) hubSection.style.display='none';
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
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));
|
|
6427
6614
|
return;
|
|
6428
6615
|
}
|
|
6429
6616
|
|
|
@@ -6431,12 +6618,11 @@ async function loadSkills(silent){
|
|
|
6431
6618
|
if(hubSection) hubSection.style.display='block';
|
|
6432
6619
|
var localIds=new Set(localSkills.map(function(s){return s.id;}));
|
|
6433
6620
|
if(hubList){ loadHubSkills(hubList, localIds); }
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
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));
|
|
6440
6626
|
return;
|
|
6441
6627
|
}
|
|
6442
6628
|
|
|
@@ -6446,7 +6632,9 @@ async function loadSkills(silent){
|
|
|
6446
6632
|
sharingParams.set('maxResults','20');
|
|
6447
6633
|
const r=await fetch('/api/sharing/search/skills?'+sharingParams.toString());
|
|
6448
6634
|
const data=await r.json();
|
|
6449
|
-
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);});
|
|
6450
6638
|
const hubHits=(data.hub&&Array.isArray(data.hub.hits))?data.hub.hits:[];
|
|
6451
6639
|
|
|
6452
6640
|
const sp=document.getElementById('skillsPagination');
|
|
@@ -6476,17 +6664,18 @@ async function loadSkills(silent){
|
|
|
6476
6664
|
}).join(''):'';
|
|
6477
6665
|
}
|
|
6478
6666
|
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
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);
|
|
6485
6673
|
updateSkillSelectionToolbar();
|
|
6486
6674
|
}catch(e){
|
|
6487
6675
|
list.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">'+t('skills.load.error')+': '+esc(String(e))+'</div>';
|
|
6488
6676
|
const sp=document.getElementById('skillsPagination');
|
|
6489
6677
|
if(sp) sp.innerHTML='';
|
|
6678
|
+
setPageSizeVisible('skillsPageSize',false);
|
|
6490
6679
|
if(hubList){
|
|
6491
6680
|
hubList.innerHTML='<div style="text-align:center;padding:24px;color:var(--rose)">'+t('skills.load.error')+'</div>';
|
|
6492
6681
|
}
|
|
@@ -6496,19 +6685,28 @@ async function loadSkills(silent){
|
|
|
6496
6685
|
async function loadHubTasks(){
|
|
6497
6686
|
var list=document.getElementById('tasksList');
|
|
6498
6687
|
if(!list) return;
|
|
6688
|
+
currentTaskIds=[];
|
|
6689
|
+
selectedTaskIds.clear();
|
|
6690
|
+
updateTaskSelectionToolbar();
|
|
6499
6691
|
list.innerHTML='<div class="spinner"></div>';
|
|
6500
6692
|
try{
|
|
6501
6693
|
var r=await fetch('/api/sharing/tasks/list?limit='+tasksPageSize);
|
|
6502
6694
|
var d=await r.json();
|
|
6503
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
|
+
}
|
|
6504
6701
|
hubTasksCache=tasks;
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6702
|
+
_st('tasksTotalCount',formatNum(tasks.length));
|
|
6703
|
+
_st('tasksActiveCount','-');
|
|
6704
|
+
_st('tasksCompletedCount','-');
|
|
6705
|
+
_st('tasksSkippedCount','-');
|
|
6509
6706
|
if(!tasks.length){
|
|
6510
6707
|
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px">'+t('tasks.empty')+'</div>';
|
|
6511
6708
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6709
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6512
6710
|
return;
|
|
6513
6711
|
}
|
|
6514
6712
|
list.innerHTML=tasks.map(function(task,idx){
|
|
@@ -6527,9 +6725,11 @@ async function loadHubTasks(){
|
|
|
6527
6725
|
'</div>';
|
|
6528
6726
|
}).join('');
|
|
6529
6727
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6728
|
+
setPageSizeVisible('tasksPageSize',true);
|
|
6530
6729
|
}catch(e){
|
|
6531
6730
|
list.innerHTML='<div style="text-align:center;padding:48px;color:var(--text-muted);font-size:14px">'+t('tasks.empty')+'</div>';
|
|
6532
6731
|
document.getElementById('tasksPagination').innerHTML='';
|
|
6732
|
+
setPageSizeVisible('tasksPageSize',false);
|
|
6533
6733
|
}
|
|
6534
6734
|
}
|
|
6535
6735
|
|
|
@@ -6685,7 +6885,14 @@ async function openSkillDetail(skillId){
|
|
|
6685
6885
|
}
|
|
6686
6886
|
|
|
6687
6887
|
window._currentSkillData=skill;
|
|
6688
|
-
|
|
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;
|
|
6689
6896
|
|
|
6690
6897
|
}catch(e){
|
|
6691
6898
|
document.getElementById('skillDetailTitle').textContent=t('skills.error');
|
|
@@ -7274,6 +7481,29 @@ async function deleteSkill(skillId){
|
|
|
7274
7481
|
loadSkills();
|
|
7275
7482
|
}catch(e){ alert(t('skill.delete.error')+e.message); }
|
|
7276
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
|
+
}
|
|
7277
7507
|
|
|
7278
7508
|
async function deleteSelectedSkills(){
|
|
7279
7509
|
var ids=Array.from(selectedSkillIds);
|
|
@@ -7931,15 +8161,17 @@ async function loadStats(ownerFilter){
|
|
|
7931
8161
|
const activeCount=dedupB.active||tm;
|
|
7932
8162
|
const inactiveCount=(dedupB.duplicate||0)+(dedupB.merged||0);
|
|
7933
8163
|
var agentCount=(d.owners&&d.owners.length)?d.owners.length:1;
|
|
7934
|
-
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;
|
|
7935
8167
|
if(sfp===_lastStatsFp) return;
|
|
7936
8168
|
_lastStatsFp=sfp;
|
|
7937
8169
|
document.getElementById('statTotal').textContent=tm;
|
|
7938
8170
|
if(inactiveCount>0){
|
|
7939
8171
|
document.getElementById('statTotal').title=activeCount+' '+t('stat.active')+', '+inactiveCount+' '+t('stat.deduped');
|
|
7940
8172
|
}
|
|
7941
|
-
document.getElementById('
|
|
7942
|
-
document.getElementById('
|
|
8173
|
+
document.getElementById('statTasks').textContent=d.totalTasks||0;
|
|
8174
|
+
document.getElementById('statSkills').textContent=d.totalSkills||0;
|
|
7943
8175
|
document.getElementById('statAgents').textContent=agentCount;
|
|
7944
8176
|
|
|
7945
8177
|
const provEl=document.getElementById('embeddingStatus');
|
|
@@ -7963,45 +8195,76 @@ async function loadStats(ownerFilter){
|
|
|
7963
8195
|
}).catch(()=>{});
|
|
7964
8196
|
}
|
|
7965
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);
|
|
7966
8210
|
const sl=document.getElementById('sessionList');
|
|
7967
|
-
sl.
|
|
7968
|
-
(
|
|
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=>{
|
|
7969
8214
|
const isActive=activeSession===s.session_key;
|
|
7970
8215
|
const name=s.session_key.length>20?s.session_key.slice(0,8)+'...'+s.session_key.slice(-8):s.session_key;
|
|
7971
|
-
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>';
|
|
7972
8217
|
});
|
|
7973
8218
|
|
|
7974
|
-
|
|
7975
|
-
|
|
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;
|
|
7976
8225
|
const curVal=activeSession||'';
|
|
7977
|
-
var sessionCount=
|
|
8226
|
+
var sessionCount=viewSessions.length;
|
|
8227
|
+
fSel.style.display=sessionCount>0?'':'none';
|
|
7978
8228
|
fSel.innerHTML='<option value="">'+t('filter.allsessions')+' ('+sessionCount+')</option>';
|
|
7979
|
-
|
|
8229
|
+
viewSessions.forEach(s=>{
|
|
7980
8230
|
const sName=s.session_key.length>30?s.session_key.slice(0,12)+'...'+s.session_key.slice(-10):s.session_key;
|
|
7981
|
-
|
|
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>';
|
|
7982
8233
|
});
|
|
7983
|
-
}
|
|
8234
|
+
});
|
|
7984
8235
|
|
|
7985
|
-
|
|
7986
|
-
if(ownerSel && d.owners && d.owners.length>0){
|
|
7987
|
-
const curVal=ownerSel.value;
|
|
8236
|
+
if(d.owners && d.owners.length>0){
|
|
7988
8237
|
var agents=d.owners.filter(function(o){return o && o.indexOf('agent:')===0;});
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
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='';
|
|
7993
8249
|
});
|
|
7994
|
-
if(agents.length<=1) ownerSel.style.display='none';
|
|
7995
|
-
else ownerSel.style.display='';
|
|
7996
8250
|
}
|
|
7997
8251
|
}
|
|
7998
8252
|
|
|
7999
8253
|
function onOwnerFilterChange(){
|
|
8000
|
-
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
|
+
});
|
|
8001
8260
|
activeSession=null;
|
|
8002
8261
|
currentPage=1;
|
|
8262
|
+
taskSearchQuery='';
|
|
8263
|
+
var tsi=document.getElementById('taskSearchInput');if(tsi)tsi.value='';
|
|
8003
8264
|
refreshSessionDropdown(owner);
|
|
8004
8265
|
applyFilters();
|
|
8266
|
+
loadTasks();
|
|
8267
|
+
loadSkills();
|
|
8005
8268
|
}
|
|
8006
8269
|
|
|
8007
8270
|
async function refreshSessionDropdown(ownerFilter){
|
|
@@ -8099,6 +8362,8 @@ async function loadMemories(page,silent){
|
|
|
8099
8362
|
|
|
8100
8363
|
async function loadHubMemories(silent){
|
|
8101
8364
|
const list=document.getElementById('memoryList');
|
|
8365
|
+
selectedMemoryIds.clear();
|
|
8366
|
+
updateMemorySelectionToolbar();
|
|
8102
8367
|
if(!silent) list.innerHTML='<div class="spinner"></div>';
|
|
8103
8368
|
try{
|
|
8104
8369
|
const r=await fetch('/api/sharing/memories/list?limit='+PAGE_SIZE);
|
|
@@ -8187,12 +8452,26 @@ function debounceSearch(){
|
|
|
8187
8452
|
function filterSession(key){
|
|
8188
8453
|
activeSession=key;
|
|
8189
8454
|
currentPage=1;
|
|
8190
|
-
|
|
8191
|
-
|
|
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
|
+
});
|
|
8192
8461
|
document.querySelectorAll('#sessionList .session-item').forEach(function(el,i){
|
|
8193
8462
|
if(i===0) el.classList.toggle('active',!key);
|
|
8194
8463
|
else el.classList.toggle('active',el.querySelector('span')?.title===key);
|
|
8195
8464
|
});
|
|
8465
|
+
if(_activeView==='tasks'){
|
|
8466
|
+
loadStats();
|
|
8467
|
+
loadTasks();
|
|
8468
|
+
return;
|
|
8469
|
+
}
|
|
8470
|
+
if(_activeView==='skills'){
|
|
8471
|
+
loadStats();
|
|
8472
|
+
loadSkills();
|
|
8473
|
+
return;
|
|
8474
|
+
}
|
|
8196
8475
|
loadAll();
|
|
8197
8476
|
}
|
|
8198
8477
|
|
|
@@ -8219,14 +8498,88 @@ function clearDateFilter(){
|
|
|
8219
8498
|
applyFilters();
|
|
8220
8499
|
}
|
|
8221
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
|
+
|
|
8222
8570
|
/* ─── Rendering ─── */
|
|
8223
8571
|
function renderMemories(items){
|
|
8224
8572
|
const list=document.getElementById('memoryList');
|
|
8573
|
+
setPageSizeVisible('memoryPageSize',items.length>0);
|
|
8225
8574
|
if(!items.length){
|
|
8226
8575
|
list.innerHTML='<div class="empty"><div class="icon">\\u{1F4ED}</div><p>'+t('empty.text')+'</p></div>';
|
|
8576
|
+
currentMemoryIds=[];
|
|
8577
|
+
updateMemorySelectionToolbar();
|
|
8227
8578
|
return;
|
|
8228
8579
|
}
|
|
8229
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);}));
|
|
8230
8583
|
list.innerHTML=items.map(m=>{
|
|
8231
8584
|
const time=m.created_at?new Date(typeof m.created_at==='number'?m.created_at:m.created_at).toLocaleString(dateLoc()):'';
|
|
8232
8585
|
const role=m.role||'user';
|
|
@@ -8253,6 +8606,8 @@ function renderMemories(items){
|
|
|
8253
8606
|
const isHubScope=memorySearchScope==='hub';
|
|
8254
8607
|
const memScope=memShared?'team':isPublicMem?'local':'private';
|
|
8255
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>';
|
|
8256
8611
|
let dedupInfo='';
|
|
8257
8612
|
if(ds==='duplicate'||ds==='merged'){
|
|
8258
8613
|
const reason=m.dedup_reason?'<span style="font-size:11px;color:var(--text-muted)">'+t('card.dedupReason')+esc(m.dedup_reason)+'</span>':'';
|
|
@@ -8278,7 +8633,7 @@ function renderMemories(items){
|
|
|
8278
8633
|
}
|
|
8279
8634
|
return '<div class="memory-card'+(isInactive?' dedup-inactive':'')+'">'+
|
|
8280
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>'+
|
|
8281
|
-
'<div class="card-summary">'+cardTitle+'</div>'+
|
|
8636
|
+
'<div class="card-summary">'+selectBoxHtml+cardTitle+'</div>'+
|
|
8282
8637
|
(function(){
|
|
8283
8638
|
if(mc<=0) return '';
|
|
8284
8639
|
var mergeHtml='<div class="card-merged-info">';
|
|
@@ -8308,6 +8663,7 @@ function renderMemories(items){
|
|
|
8308
8663
|
vscore+
|
|
8309
8664
|
'</div></div>';
|
|
8310
8665
|
}).join('');
|
|
8666
|
+
updateMemorySelectionToolbar();
|
|
8311
8667
|
}
|
|
8312
8668
|
|
|
8313
8669
|
function updateMemoryCardBadge(chunkId,newScope){
|
|
@@ -8510,7 +8866,18 @@ async function deleteMemory(id){
|
|
|
8510
8866
|
if(!(await confirmModal(t('confirm.delete'),{danger:true})))return;
|
|
8511
8867
|
const r=await fetch('/api/memory/'+id,{method:'DELETE'});
|
|
8512
8868
|
const d=await r.json();
|
|
8513
|
-
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
|
+
}
|
|
8514
8881
|
else{toast(t('toast.delfail'),'error')}
|
|
8515
8882
|
}
|
|
8516
8883
|
|