1
-<html>
1
+<script type="module">
2
+ import { store } from "/components/settings/memory/memory-dashboard-store.js";
3
+</script>
4
3
-<head>
4
- <title>Memory Dashboard</title>
5
- <script type="module">
6
- import { store } from "/components/settings/memory/memory-dashboard-store.js";
7
- </script>
8
-</head>
9
-
10
-<body>
11
- <div x-data>
12
- <template x-if="$store.memoryDashboardStore">
13
- <div x-init="$store.memoryDashboardStore.initialize()" class="memory-dashboard">
5
+<div x-data>
6
+ <template x-if="$store.memoryDashboardStore">
7
+ <div x-init="$store.memoryDashboardStore.initialize()" class="memory-dashboard">
8
9
<!-- Header with title and statistics -->
10
<div class="dashboard-header">
25
</div>
26
</div>
27
34
- <!-- Filters -->
28
+ <!-- Search and Filters -->
29
<div class="filters-section">
30
<div class="filter-row">
31
+ <div class="filter-group">
32
+ <label for="memory-subdir-select">Memory Directory:</label>
33
+ <select id="memory-subdir-select"
34
+ x-model="$store.memoryDashboardStore.selectedMemorySubdir"
35
+ @change="$store.memoryDashboardStore.onMemorySubdirChange()"
36
+ :disabled="$store.memoryDashboardStore.loadingSubdirs">
37
+ <template x-for="subdir in $store.memoryDashboardStore.memorySubdirs" :key="subdir">
38
+ <option :value="subdir" x-text="subdir"></option>
39
+ </template>
40
+ </select>
41
+ <span x-show="$store.memoryDashboardStore.loadingSubdirs" class="loading-text">Loading...</span>
42
+ </div>
43
+
44
<div class="filter-group">
45
<label for="area-filter">Area:</label>
46
<select id="area-filter" x-model="$store.memoryDashboardStore.areaFilter">
47
<option value="">All Areas</option>
41
- <option value="main">Main</option>
42
- <option value="fragments">Fragments</option>
43
- <option value="solutions">Solutions</option>
44
- <option value="instruments">Instruments</option>
48
+ <option value="MAIN">Main</option>
49
+ <option value="FRAGMENTS">Fragments</option>
50
+ <option value="SOLUTIONS">Solutions</option>
51
+ <option value="INSTRUMENTS">Instruments</option>
52
</select>
53
</div>
54
55
<div class="filter-group">
56
<label for="search-input">Search:</label>
57
<input type="text" id="search-input" x-model="$store.memoryDashboardStore.searchQuery"
51
- placeholder="Search memory content..." />
58
+ placeholder="Search memory content..."
59
+ @keyup.enter="$store.memoryDashboardStore.searchMemories()" />
60
+ </div>
61
+
62
+ <div class="filter-group">
63
+ <label for="limit-input">Limit:</label>
64
+ <input type="number" id="limit-input" x-model.number="$store.memoryDashboardStore.limit"
65
+ min="10" max="1000" step="10"
66
+ style="min-width: 100px;" />
67
</div>
68
69
<div class="filter-actions">
55
- <button class="btn primary slim" @click="$store.memoryDashboardStore.applyFilters()"
56
- :disabled="$store.memoryDashboardStore.loading">
57
- Apply Filters
70
+ <button class="btn primary slim" @click="$store.memoryDashboardStore.searchMemories()"
71
+ :disabled="$store.memoryDashboardStore.loading || $store.memoryDashboardStore.loadingSubdirs">
72
+ <span x-show="!$store.memoryDashboardStore.initializingMemory">Search</span>
73
+ <span x-show="$store.memoryDashboardStore.initializingMemory">Initializing Memory...</span>
74
</button>
59
- <button class="btn slim" @click="$store.memoryDashboardStore.clearFilters()">
75
+ <button class="btn slim" @click="$store.memoryDashboardStore.clearSearch()">
76
Clear
77
</button>
78
</div>
82
<!-- Loading state -->
83
<div x-show="$store.memoryDashboardStore.loading" class="loading-state">
84
<div class="loading-spinner"></div>
69
- <span>Loading memories...</span>
85
+ <span x-show="!$store.memoryDashboardStore.initializingMemory">Searching memories...</span>
86
+ <span x-show="$store.memoryDashboardStore.initializingMemory">Initializing memory database...</span>
87
</div>
88
89
<!-- Error state -->
110
Previous
111
</button>
112
96
- <span class="page-numbers">
113
+ <select class="page-select"
114
+ x-model.number="$store.memoryDashboardStore.currentPage"
115
+ @change="$store.memoryDashboardStore.goToPage($store.memoryDashboardStore.currentPage)">
116
<template x-for="page in Array.from({length: $store.memoryDashboardStore.totalPages}, (_, i) => i + 1)" :key="page">
98
- <button class="page-btn"
99
- @click="$store.memoryDashboardStore.goToPage(page)"
100
- :class="{'active': page === $store.memoryDashboardStore.currentPage}"
101
- x-text="page">
102
- </button>
117
+ <option :value="page" x-text="'Page ' + page"></option>
118
</template>
104
- </span>
119
+ </select>
120
121
<button class="btn slim" @click="$store.memoryDashboardStore.nextPage()"
122
:disabled="$store.memoryDashboardStore.currentPage === $store.memoryDashboardStore.totalPages">
125
</div>
126
</div>
127
128
+ <!-- Mass action toolbar -->
129
+ <div x-show="$store.memoryDashboardStore.selectedCount > 0" class="mass-action-toolbar">
130
+ <div class="selection-info">
131
+ <span x-text="$store.memoryDashboardStore.selectedCount"></span> memories selected
132
+ </div>
133
+
134
+ <div class="mass-actions">
135
+ <button class="btn-mass copy" @click="$store.memoryDashboardStore.bulkCopyMemories()"
136
+ title="Copy Selected Content">
137
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
138
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
139
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
140
+ </svg>
141
+ Copy
142
+ </button>
143
+
144
+ <button class="btn-mass export" @click="$store.memoryDashboardStore.bulkExportMemories()"
145
+ title="Export Selected Memories">
146
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
147
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
148
+ <polyline points="7,10 12,15 17,10"></polyline>
149
+ <line x1="12" y1="15" x2="12" y2="3"></line>
150
+ </svg>
151
+ Export
152
+ </button>
153
+
154
+ <button class="btn-mass delete" @click="$store.memoryDashboardStore.bulkDeleteMemories()"
155
+ title="Delete Selected Memories">
156
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
157
+ <polyline points="3,6 5,6 21,6"></polyline>
158
+ <path d="M19,6V20a2,2,0,0,1-2,2H7a2,2,0,0,1-2-2V6m3,0V4a2,2,0,0,1,2-2h4a2,2,0,0,1,2,2V6"></path>
159
+ <line x1="10" y1="11" x2="10" y2="17"></line>
160
+ <line x1="14" y1="11" x2="14" y2="17"></line>
161
+ </svg>
162
+ Delete
163
+ </button>
164
+
165
+ <button class="btn-mass clear" @click="$store.memoryDashboardStore.clearSelection()"
166
+ title="Clear Selection">
167
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
168
+ <line x1="18" y1="6" x2="6" y2="18"></line>
169
+ <line x1="6" y1="6" x2="18" y2="18"></line>
170
+ </svg>
171
+ Clear
172
+ </button>
173
+ </div>
174
+ </div>
175
+
176
<div class="table-wrapper">
177
<table class="memory-table">
178
<thead>
179
<tr>
117
- <th class="col-area">Area</th>
118
- <th class="col-timestamp">Timestamp</th>
119
- <th class="col-source">Source</th>
180
+ <th class="col-select">
181
+ <input type="checkbox"
182
+ :checked="$store.memoryDashboardStore.allSelected"
183
+ :indeterminate="$store.memoryDashboardStore.someSelected && !$store.memoryDashboardStore.allSelected"
184
+ @change="$store.memoryDashboardStore.toggleSelectAll()"
185
+ title="Select/Deselect All" />
186
+ </th>
187
+ <th class="col-metadata">Metadata</th>
188
<th class="col-preview">Preview</th>
189
<th class="col-actions">Actions</th>
190
</tr>
191
</thead>
192
<tbody>
193
<template x-for="memory in $store.memoryDashboardStore.paginatedMemories" :key="memory.id">
126
- <tr class="memory-row">
127
- <!-- Area with color indicator -->
128
- <td class="area-cell">
129
- <span class="area-badge"
130
- :style="`background-color: ${$store.memoryDashboardStore.getAreaColor(memory.area)}`"
131
- x-text="memory.area.toUpperCase()"></span>
194
+ <tr class="memory-row" :class="{'selected': memory.selected}"
195
+ @click="$store.memoryDashboardStore.showMemoryDetails(memory)"
196
+ style="cursor: pointer;">
197
+ <!-- Selection checkbox -->
198
+ <td class="select-cell" @click.stop>
199
+ <input type="checkbox"
200
+ x-model="memory.selected" />
201
</td>
202
134
- <!-- Timestamp -->
135
- <td class="timestamp-cell">
136
- <span x-text="$store.memoryDashboardStore.formatTimestamp(memory.timestamp, true)"
137
- :title="$store.memoryDashboardStore.formatTimestamp(memory.timestamp, false)"></span>
138
- </td>
139
-
140
- <!-- Source -->
141
- <td class="source-cell">
142
- <template x-if="memory.knowledge_source">
143
- <div class="source-info">
144
- <span class="source-type knowledge">Knowledge</span>
145
- <span class="source-file" x-text="memory.source_file" x-show="memory.source_file"></span>
203
+ <!-- Metadata (merged Area, Timestamp, Source) -->
204
+ <td class="metadata-cell">
205
+ <div class="metadata-info">
206
+ <div class="metadata-row">
207
+ <span class="area-badge"
208
+ :style="`background-color: ${$store.memoryDashboardStore.getAreaColor(memory.area)}`"
209
+ x-text="memory.area"></span>
210
+ </div>
211
+ <div class="metadata-row metadata-timestamp">
212
+ <span x-text="$store.memoryDashboardStore.formatTimestamp(memory.timestamp, true)"
213
+ :title="$store.memoryDashboardStore.formatTimestamp(memory.timestamp, false)"></span>
214
</div>
147
- </template>
148
- <template x-if="!memory.knowledge_source">
149
- <span class="source-type conversation">Conversation</span>
150
- </template>
215
+ <div class="metadata-row">
216
+ <template x-if="memory.knowledge_source">
217
+ <span class="source-type knowledge">📚 Knowledge</span>
218
+ </template>
219
+ <template x-if="!memory.knowledge_source">
220
+ <span class="source-type conversation">💬 Conversation</span>
221
+ </template>
222
+ </div>
223
+ </div>
224
</td>
225
226
<!-- Content preview -->
234
</td>
235
236
<!-- Actions -->
164
- <td class="actions-cell">
165
- <button class="btn-action view" @click="$store.memoryDashboardStore.showMemoryDetails(memory)"
166
- title="View Details">
167
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
168
- <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
169
- <circle cx="12" cy="12" r="3"></circle>
170
- </svg>
171
- </button>
172
- <button class="btn-action copy" @click="$store.memoryDashboardStore.copyToClipboard(memory.content_full)"
173
- title="Copy Content">
237
+ <td class="actions-cell" @click.stop>
238
+ <button class="btn-action copy" @click="$store.memoryDashboardStore.copyToClipboard($store.memoryDashboardStore.formatMemoryForCopy(memory))"
239
+ title="Copy Memory">
240
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
241
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
242
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
243
</svg>
244
</button>
245
+
246
<button class="btn-action delete" @click="$store.memoryDashboardStore.deleteMemory(memory)"
247
title="Delete Memory">
248
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
257
</template>
258
</tbody>
259
</table>
260
+
261
+ <!-- Pagination controls at bottom -->
262
+ <div class="pagination-controls-bottom" x-show="$store.memoryDashboardStore.totalPages > 1">
263
+ <div class="pagination-info-inline">
264
+ <span>Page <span x-text="$store.memoryDashboardStore.currentPage"></span>
265
+ of <span x-text="$store.memoryDashboardStore.totalPages"></span>
266
+ (<span x-text="$store.memoryDashboardStore.memories.length"></span> total memories)
267
+ </span>
268
+ </div>
269
+
270
+ <div class="pagination-controls">
271
+ <button class="btn slim" @click="$store.memoryDashboardStore.prevPage()"
272
+ :disabled="$store.memoryDashboardStore.currentPage === 1">
273
+ Previous
274
+ </button>
275
+
276
+ <select class="page-select"
277
+ x-model.number="$store.memoryDashboardStore.currentPage"
278
+ @change="$store.memoryDashboardStore.goToPage($store.memoryDashboardStore.currentPage)">
279
+ <template x-for="page in Array.from({length: $store.memoryDashboardStore.totalPages}, (_, i) => i + 1)" :key="page">
280
+ <option :value="page" x-text="'Page ' + page"></option>
281
+ </template>
282
+ </select>
283
+
284
+ <button class="btn slim" @click="$store.memoryDashboardStore.nextPage()"
285
+ :disabled="$store.memoryDashboardStore.currentPage === $store.memoryDashboardStore.totalPages">
286
+ Next
287
+ </button>
288
+ </div>
289
+ </div>
290
+
291
</div>
292
293
<!-- No memories message -->
310
</div>
311
</div>
312
215
- <!-- Enhanced Detail Modal -->
216
- <div x-show="$store.memoryDashboardStore.showDetailModal"
217
- x-transition:enter="modal-enter"
218
- x-transition:enter-start="modal-enter-start"
219
- x-transition:enter-end="modal-enter-end"
220
- x-transition:leave="modal-leave"
221
- x-transition:leave-start="modal-leave-start"
222
- x-transition:leave-end="modal-leave-end"
223
- class="modal-overlay"
224
- @click.self="$store.memoryDashboardStore.closeDetailModal()">
225
- <div class="modal-content memory-detail-modal" x-show="$store.memoryDashboardStore.selectedMemory" x-cloak>
226
-
227
- <!-- Modal Header with Memory Info -->
228
- <div class="modal-header-enhanced">
229
- <div class="header-left">
230
- <div class="memory-title">
231
- <span class="area-badge-large"
232
- :style="`background: linear-gradient(135deg, ${$store.memoryDashboardStore.getAreaColor($store.memoryDashboardStore.selectedMemory?.area)} 0%, ${$store.memoryDashboardStore.getAreaColor($store.memoryDashboardStore.selectedMemory?.area)}cc 100%)`"
233
- x-text="$store.memoryDashboardStore.selectedMemory?.area?.toUpperCase() || 'UNKNOWN'"></span>
234
- <h3>Memory Details</h3>
235
- </div>
236
- <div class="memory-meta-quick">
237
- <span class="timestamp-badge" x-text="$store.memoryDashboardStore.formatTimestamp($store.memoryDashboardStore.selectedMemory?.timestamp, true)"></span>
238
- <span class="source-badge"
239
- :class="$store.memoryDashboardStore.selectedMemory?.knowledge_source ? 'knowledge' : 'conversation'"
240
- x-text="$store.memoryDashboardStore.selectedMemory?.knowledge_source ? 'Knowledge' : 'Conversation'"></span>
241
- </div>
242
- </div>
243
- <div class="header-actions">
244
- <button class="btn-action-header copy" @click="$store.memoryDashboardStore.copyToClipboard($store.memoryDashboardStore.selectedMemory?.content_full)"
245
- title="Copy Full Content">
246
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
247
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
248
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
249
- </svg>
250
- </button>
251
- <button class="btn-action-header delete" @click="$store.memoryDashboardStore.deleteMemory($store.memoryDashboardStore.selectedMemory)"
252
- title="Delete Memory">
253
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
254
- <polyline points="3,6 5,6 21,6"></polyline>
255
- <path d="M19,6V20a2,2,0,0,1-2,2H7a2,2,0,0,1-2-2V6M8,6V4a2,2,0,0,1,2-2h4a2,2,0,0,1,2,2V6"></path>
256
- <line x1="10" y1="11" x2="10" y2="17"></line>
257
- <line x1="14" y1="11" x2="14" y2="17"></line>
258
- </svg>
259
- </button>
260
- <button class="btn-close-enhanced" @click="$store.memoryDashboardStore.closeDetailModal()">
261
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
262
- <line x1="18" y1="6" x2="6" y2="18"></line>
263
- <line x1="6" y1="6" x2="18" y2="18"></line>
264
- </svg>
265
- </button>
266
- </div>
267
- </div>
313
269
- <!-- Modal Body with Enhanced Layout -->
270
- <div class="modal-body-enhanced">
271
-
272
- <!-- Content Section -->
273
- <div class="content-section-main">
274
- <div class="section-header">
275
- <h4>
276
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
277
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
278
- <polyline points="14,2 14,8 20,8"></polyline>
279
- </svg>
280
- Content
281
- </h4>
282
- </div>
283
- <div class="content-display" x-text="$store.memoryDashboardStore.selectedMemory?.content_full"></div>
284
- </div>
285
-
286
- <!-- Metadata Sidebar -->
287
- <div class="metadata-sidebar">
288
- <div class="section-header">
289
- <h4>
290
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
291
- <circle cx="12" cy="12" r="3"></circle>
292
- <path d="M12 1v6m0 6v6m11-7h-6m-6 0H1"></path>
293
- </svg>
294
- Metadata
295
- </h4>
296
- </div>
297
-
298
- <div class="metadata-grid">
299
- <div class="metadata-item">
300
- <label>Memory ID</label>
301
- <value class="monospace" x-text="$store.memoryDashboardStore.selectedMemory?.id"></value>
302
- </div>
303
-
304
- <div class="metadata-item">
305
- <label>Area</label>
306
- <value x-text="$store.memoryDashboardStore.selectedMemory?.area"></value>
307
- </div>
308
-
309
- <div class="metadata-item">
310
- <label>Created</label>
311
- <value x-text="$store.memoryDashboardStore.formatTimestamp($store.memoryDashboardStore.selectedMemory?.timestamp)"></value>
312
- </div>
313
-
314
- <div class="metadata-item">
315
- <label>Source Type</label>
316
- <value x-text="$store.memoryDashboardStore.selectedMemory?.knowledge_source ? 'Knowledge File' : 'Conversation'"></value>
317
- </div>
318
-
319
- <div class="metadata-item" x-show="$store.memoryDashboardStore.selectedMemory?.source_file">
320
- <label>Source File</label>
321
- <value class="monospace" x-text="$store.memoryDashboardStore.selectedMemory?.source_file"></value>
322
- </div>
323
-
324
- <div class="metadata-item" x-show="$store.memoryDashboardStore.selectedMemory?.file_type">
325
- <label>File Type</label>
326
- <value x-text="$store.memoryDashboardStore.selectedMemory?.file_type"></value>
327
- </div>
328
-
329
- <div class="metadata-item" x-show="$store.memoryDashboardStore.selectedMemory?.consolidation_action">
330
- <label>Consolidation</label>
331
- <value class="consolidation-badge" x-text="$store.memoryDashboardStore.selectedMemory?.consolidation_action"></value>
332
- </div>
333
-
334
- <div class="metadata-item" x-show="$store.memoryDashboardStore.selectedMemory?.tags && $store.memoryDashboardStore.selectedMemory?.tags.length > 0">
335
- <label>Tags</label>
336
- <div class="tags-display">
337
- <template x-for="tag in $store.memoryDashboardStore.selectedMemory?.tags" :key="tag">
338
- <span class="tag-pill" x-text="tag"></span>
339
- </template>
340
- </div>
341
- </div>
342
- </div>
343
- </div>
344
- </div>
345
- </div>
346
- </div>
314
315
</div>
316
</template>
400
border-radius: 6px;
401
font-size: 0.9rem;
402
min-width: 200px;
403
+ height: 40px;
404
+ box-sizing: border-box;
405
}
406
407
.filter-group input:focus, .filter-group select:focus {
413
.filter-actions {
414
display: flex;
415
gap: 0.5rem;
416
+ align-items: stretch;
417
+ }
418
+
419
+ .filter-actions .btn {
420
+ height: 40px;
421
+ display: flex;
422
+ align-items: center;
423
+ justify-content: center;
424
+ }
425
+
426
+ .loading-text {
427
+ font-size: 0.85rem;
428
+ color: var(--color-secondary);
429
+ font-style: italic;
430
}
431
432
.loading-state, .error-state, .no-memories, .init-message {
485
}
486
487
/* Fixed column widths for proper fit */
505
- .col-area { width: 15%; }
506
- .col-timestamp { width: 18%; }
507
- .col-source { width: 15%; }
508
- .col-preview { width: 30%; }
509
- .col-actions { width: 22%; }
488
+ .col-select { width: 5%; }
489
+ .col-metadata { width: 25%; }
490
+ .col-preview { width: 55%; }
491
+ .col-actions { width: 15%; }
492
493
.memory-table th,
494
.memory-table td {
499
overflow: hidden;
500
}
501
520
- /* Allow source column to wrap properly */
521
- .source-cell {
502
+ /* Metadata cell styling */
503
+ .metadata-cell {
504
overflow: visible;
505
white-space: normal;
506
word-wrap: break-word;
507
}
508
509
+ .metadata-info {
510
+ display: flex;
511
+ flex-direction: column;
512
+ gap: 0.5rem;
513
+ }
514
+
515
+ .metadata-row {
516
+ display: flex;
517
+ align-items: center;
518
+ gap: 0.5rem;
519
+ }
520
+
521
+ .metadata-timestamp {
522
+ font-size: 0.85rem;
523
+ color: var(--color-text);
524
+ font-family: monospace;
525
+ }
526
+
527
+ .source-type {
528
+ font-size: 0.8rem;
529
+ color: var(--color-text);
530
+ font-weight: 500;
531
+ }
532
+
533
+ /* Selection column styling */
534
+ .select-cell, .col-select {
535
+ text-align: center;
536
+ padding: 0.5rem !important;
537
+ }
538
+
539
+ .select-cell input[type="checkbox"],
540
+ .col-select input[type="checkbox"] {
541
+ cursor: pointer;
542
+ transform: scale(1.2);
543
+ }
544
+
545
+ /* Selected row styling */
546
+ .memory-row.selected {
547
+ background: rgba(115, 122, 129, 0.1);
548
+ border-left: 3px solid var(--color-primary);
549
+ }
550
+
551
+ .light-mode .memory-row.selected {
552
+ background: rgba(115, 122, 129, 0.05);
553
+ }
554
+
555
+ /* Mass action toolbar */
556
+ .mass-action-toolbar {
557
+ display: flex;
558
+ justify-content: space-between;
559
+ align-items: center;
560
+ padding: 1rem;
561
+ background: rgba(115, 122, 129, 0.1);
562
+ border: 1px solid var(--color-primary);
563
+ border-radius: 8px;
564
+ margin: 1rem 0;
565
+ animation: slideDown 0.3s ease;
566
+ }
567
+
568
+ .light-mode .mass-action-toolbar {
569
+ background: rgba(115, 122, 129, 0.05);
570
+ }
571
+
572
+ .selection-info {
573
+ font-weight: 600;
574
+ color: var(--color-primary);
575
+ }
576
+
577
+ .mass-actions {
578
+ display: flex;
579
+ gap: 0.5rem;
580
+ }
581
+
582
+ .btn-mass {
583
+ display: flex;
584
+ align-items: center;
585
+ gap: 0.5rem;
586
+ padding: 0.5rem 1rem;
587
+ border: 1px solid var(--color-border);
588
+ background: var(--color-background);
589
+ color: var(--color-text);
590
+ border-radius: 6px;
591
+ cursor: pointer;
592
+ font-size: 0.9rem;
593
+ font-weight: 500;
594
+ transition: all 0.2s ease;
595
+ }
596
+
597
+ .btn-mass:hover {
598
+ border-color: var(--color-primary);
599
+ background: rgba(115, 122, 129, 0.1);
600
+ }
601
+
602
+ .btn-mass.copy:hover {
603
+ border-color: #4caf50;
604
+ color: #4caf50;
605
+ }
606
+
607
+ .btn-mass.export:hover {
608
+ border-color: #2196f3;
609
+ color: #2196f3;
610
+ }
611
+
612
+ .btn-mass.delete:hover {
613
+ border-color: #f44336;
614
+ color: #f44336;
615
+ }
616
+
617
+ .btn-mass.clear:hover {
618
+ border-color: #ff9800;
619
+ color: #ff9800;
620
+ }
621
+
622
+ @keyframes slideDown {
623
+ from {
624
+ opacity: 0;
625
+ transform: translateY(-10px);
626
+ }
627
+ to {
628
+ opacity: 1;
629
+ transform: translateY(0);
630
+ }
631
+ }
632
+
633
.memory-table th {
634
background: var(--color-panel);
635
font-weight: 600;
663
color: white;
664
font-size: 0.75rem;
665
font-weight: bold;
560
- text-transform: uppercase;
666
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
667
}
668
722
.content-preview {
723
line-height: 1.4;
724
font-size: 0.9rem;
725
+ color: var(--color-text);
726
word-wrap: break-word;
727
overflow-wrap: break-word;
728
max-width: 100%;
822
border-radius: 8px;
823
}
824
719
- .page-numbers {
720
- display: flex;
721
- gap: 0.25rem;
722
- }
723
-
724
- .page-btn {
825
+ .page-select {
826
background: var(--color-background);
827
border: 1px solid var(--color-border);
828
color: var(--color-text);
829
padding: 0.5rem 0.75rem;
729
- cursor: pointer;
830
border-radius: 6px;
831
font-size: 0.9rem;
732
- transition: all 0.2s ease;
832
+ cursor: pointer;
833
+ min-width: 120px;
834
}
835
735
- .page-btn:hover {
736
- background: rgba(255, 255, 255, 0.1);
836
+ .page-select:focus {
837
+ outline: none;
838
border-color: var(--color-primary);
839
+ box-shadow: 0 0 0 2px rgba(115, 122, 129, 0.1);
840
}
841
740
- .page-btn.active {
741
- background: var(--color-primary);
742
- color: white;
743
- border-color: var(--color-primary);
842
+ .pagination-controls-top, .pagination-controls-bottom {
843
+ display: flex;
844
+ justify-content: space-between;
845
+ align-items: center;
846
+ padding: 1rem;
847
+ background: var(--color-panel);
848
+ border-bottom: 1px solid var(--color-border);
849
+ }
850
+
851
+ .pagination-controls-bottom {
852
+ border-top: 1px solid var(--color-border);
853
+ border-bottom: none;
854
}
855
856
.export-section {
1274
justify-content: center;
1275
}
1276
}
1167
- </style>
1277
1169
-</body>
1278
+ /* Memory Detail Modal Styles */
1279
+ .modal-header-enhanced {
1280
+ display: flex;
1281
+ justify-content: space-between;
1282
+ align-items: flex-start;
1283
+ padding: 1.5rem;
1284
+ border-bottom: 2px solid var(--color-border);
1285
+ background: linear-gradient(135deg, var(--color-panel) 0%, var(--color-background) 100%);
1286
+ }
1287
+
1288
+ .memory-title {
1289
+ display: flex;
1290
+ align-items: center;
1291
+ gap: 1rem;
1292
+ margin-bottom: 0.5rem;
1293
+ }
1294
+
1295
+ .area-badge-large {
1296
+ color: white;
1297
+ padding: 0.5rem 1rem;
1298
+ border-radius: 20px;
1299
+ font-size: 0.8rem;
1300
+ font-weight: bold;
1301
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
1302
+ }
1303
+
1304
+ .memory-meta-quick {
1305
+ display: flex;
1306
+ gap: 1rem;
1307
+ align-items: center;
1308
+ }
1309
+
1310
+ .timestamp-badge, .source-badge {
1311
+ padding: 0.25rem 0.75rem;
1312
+ border-radius: 12px;
1313
+ font-size: 0.75rem;
1314
+ font-weight: 500;
1315
+ background: var(--color-panel);
1316
+ border: 1px solid var(--color-border);
1317
+ }
1318
+
1319
+ .source-badge.knowledge {
1320
+ background: rgba(115, 122, 129, 0.1);
1321
+ color: var(--color-primary);
1322
+ border-color: var(--color-primary);
1323
+ }
1324
+
1325
+ .source-badge.conversation {
1326
+ background: rgba(101, 101, 101, 0.1);
1327
+ color: var(--color-secondary);
1328
+ border-color: var(--color-secondary);
1329
+ }
1330
+
1331
+ .header-actions {
1332
+ display: flex;
1333
+ gap: 0.5rem;
1334
+ }
1335
+
1336
+ .btn-action-header {
1337
+ background: var(--color-background);
1338
+ border: 1px solid var(--color-border);
1339
+ color: var(--color-text);
1340
+ padding: 0.5rem;
1341
+ border-radius: 8px;
1342
+ cursor: pointer;
1343
+ transition: all 0.2s ease;
1344
+ }
1345
+
1346
+ .btn-action-header:hover {
1347
+ border-color: var(--color-primary);
1348
+ background: rgba(115, 122, 129, 0.1);
1349
+ }
1350
+
1351
+ .modal-body-enhanced {
1352
+ display: flex;
1353
+ min-height: 60vh;
1354
+ max-height: 70vh;
1355
+ }
1356
+
1357
+ .content-section-main {
1358
+ flex: 1;
1359
+ padding: 1.5rem;
1360
+ overflow-y: auto;
1361
+ }
1362
+
1363
+ .content-block {
1364
+ margin-bottom: 2rem;
1365
+ }
1366
+
1367
+ .content-block h4 {
1368
+ margin: 0 0 1rem 0;
1369
+ color: var(--color-primary);
1370
+ font-size: 1.1rem;
1371
+ font-weight: 600;
1372
+ border-bottom: 1px solid var(--color-border);
1373
+ padding-bottom: 0.5rem;
1374
+ }
1375
+
1376
+ .memory-content-display {
1377
+ background: var(--color-panel);
1378
+ border: 1px solid var(--color-border);
1379
+ border-radius: 8px;
1380
+ padding: 1.5rem;
1381
+ line-height: 1.6;
1382
+ color: var(--color-text);
1383
+ white-space: pre-wrap;
1384
+ word-break: break-word;
1385
+ max-height: 300px;
1386
+ overflow-y: auto;
1387
+ }
1388
+
1389
+ .tags-display {
1390
+ display: flex;
1391
+ flex-wrap: wrap;
1392
+ gap: 0.5rem;
1393
+ }
1394
+
1395
+ .tag-display {
1396
+ background: var(--color-primary);
1397
+ color: white;
1398
+ padding: 0.25rem 0.75rem;
1399
+ border-radius: 12px;
1400
+ font-size: 0.75rem;
1401
+ font-weight: 500;
1402
+ }
1403
+
1404
+ .metadata-sidebar {
1405
+ min-width: 300px;
1406
+ max-width: 350px;
1407
+ background: var(--color-panel);
1408
+ border-left: 1px solid var(--color-border);
1409
+ padding: 1.5rem;
1410
+ overflow-y: auto;
1411
+ }
1412
+
1413
+ .metadata-sidebar h4 {
1414
+ margin: 0 0 1rem 0;
1415
+ color: var(--color-primary);
1416
+ font-size: 1.1rem;
1417
+ font-weight: 600;
1418
+ }
1419
+
1420
+ .metadata-group {
1421
+ margin-bottom: 1.5rem;
1422
+ }
1423
+
1424
+ .metadata-group h5 {
1425
+ margin: 0 0 0.75rem 0;
1426
+ color: var(--color-secondary);
1427
+ font-size: 0.9rem;
1428
+ font-weight: 600;
1429
+ text-transform: uppercase;
1430
+ letter-spacing: 0.5px;
1431
+ }
1432
+
1433
+ .metadata-item {
1434
+ display: flex;
1435
+ flex-direction: column;
1436
+ gap: 0.25rem;
1437
+ margin-bottom: 0.75rem;
1438
+ padding: 0.5rem;
1439
+ background: var(--color-background);
1440
+ border: 1px solid var(--color-border);
1441
+ border-radius: 6px;
1442
+ }
1443
+
1444
+ .metadata-label {
1445
+ font-size: 0.8rem;
1446
+ font-weight: 600;
1447
+ color: var(--color-secondary);
1448
+ text-transform: uppercase;
1449
+ letter-spacing: 0.3px;
1450
+ }
1451
+
1452
+ .metadata-value {
1453
+ font-size: 0.9rem;
1454
+ color: var(--color-text);
1455
+ word-break: break-all;
1456
+ line-height: 1.4;
1457
+ }
1458
+
1459
+ .source-file-display {
1460
+ font-family: monospace;
1461
+ background: var(--color-panel);
1462
+ padding: 0.5rem;
1463
+ border-radius: 4px;
1464
+ border: 1px solid var(--color-border);
1465
+ }
1466
+
1467
+ .metadata-actions {
1468
+ display: flex;
1469
+ flex-direction: column;
1470
+ gap: 0.5rem;
1471
+ }
1472
+
1473
+ .metadata-actions .btn {
1474
+ display: flex;
1475
+ align-items: center;
1476
+ gap: 0.5rem;
1477
+ justify-content: flex-start;
1478
+ font-size: 0.9rem;
1479
+ }
1480
+
1481
+ /* Light mode adjustments for modal */
1482
+ .light-mode .modal-header-enhanced {
1483
+ background: linear-gradient(135deg, rgba(240, 240, 240, 0.8) 0%, rgba(255, 255, 255, 0.9) 100%);
1484
+ }
1485
+
1486
+ .light-mode .memory-content-display {
1487
+ background: rgba(248, 248, 248, 0.8);
1488
+ }
1489
+
1490
+ .light-mode .metadata-sidebar {
1491
+ background: rgba(248, 248, 248, 0.8);
1492
+ }
1493
+
1494
+ .light-mode .metadata-item {
1495
+ background: rgba(255, 255, 255, 0.9);
1496
+ }
1497
+
1498
+ /* Responsive design for modal */
1499
+ @media (max-width: 768px) {
1500
+ .modal-body-enhanced {
1501
+ flex-direction: column;
1502
+ max-height: 80vh;
1503
+ }
1504
1171
-</html>
1505
+ .metadata-sidebar {
1506
+ min-width: unset;
1507
+ max-width: unset;
1508
+ border-left: none;
1509
+ border-top: 1px solid var(--color-border);
1510
+ }
1511
+
1512
+ .modal-header-enhanced {
1513
+ padding: 1rem;
1514
+ }
1515
+
1516
+ .memory-title {
1517
+ flex-direction: column;
1518
+ align-items: flex-start;
1519
+ gap: 0.5rem;
1520
+ }
1521
+
1522
+ .content-section-main,
1523
+ .metadata-sidebar {
1524
+ padding: 1rem;
1525
+ }
1526
+ }
1527
+ </style>
1528
+
1529
+ </template>
1530
+ </div>
1531
+</div>