main
html 396 lines 16.3 KB
Raw
1 <html>
2
3 <head>
4 <title>Memory Details</title>
5 </head>
6
7 <body>
8 <div x-data>
9 <template x-if="$store.memoryDashboardStore && $store.memoryDashboardStore.detailMemory">
10 <div class="memory-detail-container">
11 <!-- Compact Modal Header -->
12 <div class="modal-header modal-header-compact">
13 <div class="header-info">
14 <span class="area-badge"
15 :style="`background-color: ${$store.memoryDashboardStore.getAreaColor($store.memoryDashboardStore.detailMemory?.area)}`"
16 x-text="$store.memoryDashboardStore.detailMemory?.area?.toUpperCase() || 'UNKNOWN'"></span>
17 <span class="timestamp-text" x-text="$store.memoryDashboardStore.formatTimestamp($store.memoryDashboardStore.detailMemory?.timestamp, true)"></span>
18 <span class="source-text" x-text="$store.memoryDashboardStore.detailMemory?.knowledge_source ? 'Knowledge' : 'Conversation'"></span>
19 </div>
20 <div class="header-actions">
21 <!-- View Mode Buttons -->
22 <template x-if="!$store.memoryDashboardStore.editMode">
23 <div style="display: flex; gap: 0.5rem;">
24
25 <button class="btn btn-action-header copy-all" @click="$store.memoryDashboardStore.copyToClipboard($store.memoryDashboardStore.formatMemoryForCopy($store.memoryDashboardStore.detailMemory))"
26 title="Copy Complete Memory with Metadata">
27 <x-icon name="copy_all"></x-icon> All
28 </button>
29 <button class="btn btn-action-header copy-content" @click="$store.memoryDashboardStore.copyToClipboard($store.memoryDashboardStore.detailMemory?.content_full)"
30 title="Copy Content Only">
31 <x-icon name="content_copy"></x-icon> Content
32 </button>
33 <div style="width:2em"></div>
34 <button class="btn btn-action-header edit" @click="$store.memoryDashboardStore.enableEditMode()"
35 title="Edit Memory">
36 <x-icon name="edit_document"></x-icon>
37 </button>
38 <button class="btn btn-action-header delete danger" @click="$confirmClick($event, () => $store.memoryDashboardStore.deleteMemory($store.memoryDashboardStore.detailMemory))"
39 title="Delete Memory">
40 <x-icon name="delete"></x-icon>
41 </button>
42 </div>
43 </template>
44 <!-- Edit Mode Buttons -->
45 <template x-if="$store.memoryDashboardStore.editMode">
46 <div style="display: flex; gap: 0.5rem;">
47 <button class="btn btn-action-header cancel" @click="$store.memoryDashboardStore.cancelEditMode()"
48 title="Cancel Edit">
49 <x-icon name="close"></x-icon>
50 </button>
51 <button class="btn btn-action-header confirm" @click="$store.memoryDashboardStore.confirmEditMode()"
52 title="Confirm Changes">
53 <x-icon name="check"></x-icon>
54 </button>
55
56 </div>
57 </template>
58 </div>
59 </div>
60
61 <!-- Modal Body -->
62 <div class="modal-body">
63 <!-- Main Content Section -->
64 <div class="content-section-main">
65 <div class="content-block">
66 <h4>Memory Content</h4>
67 <template x-if="!$store.memoryDashboardStore.editMode">
68 <div class="memory-content-display">
69 <p x-text="$store.memoryDashboardStore.detailMemory?.content_full"></p>
70 </div>
71 </template>
72 <template x-if="$store.memoryDashboardStore.editMode">
73 <textarea class="memory-content-display" x-model="$store.memoryDashboardStore.detailMemory.content_full"></textarea>
74 </template>
75 </div>
76
77 <!-- Tags Section -->
78 <div class="content-block" x-show="$store.memoryDashboardStore.detailMemory?.tags && $store.memoryDashboardStore.detailMemory.tags.length > 0">
79 <h4>Tags</h4>
80 <div class="tags-display">
81 <template x-for="tag in $store.memoryDashboardStore.detailMemory?.tags || []" :key="tag">
82 <span class="tag-display" x-text="tag"></span>
83 </template>
84 </div>
85 </div>
86 </div>
87
88 <!-- Metadata Sidebar -->
89 <div class="metadata-sidebar no-scrollbar">
90 <h4>Metadata</h4>
91
92 <!-- Basic Info -->
93 <div class="metadata-group">
94 <div class="metadata-item">
95 <span class="metadata-label">ID:</span>
96 <span class="metadata-value" x-text="$store.memoryDashboardStore.detailMemory?.id || 'N/A'"></span>
97 </div>
98 <div class="metadata-item">
99 <span class="metadata-label">Area:</span>
100 <span class="metadata-value" x-text="$store.memoryDashboardStore.detailMemory?.area || 'N/A'"></span>
101 </div>
102 <div class="metadata-item">
103 <span class="metadata-label">Source:</span>
104 <span class="metadata-value" x-text="$store.memoryDashboardStore.detailMemory?.knowledge_source ? 'Knowledge' : 'Conversation'"></span>
105 </div>
106 </div>
107
108 <!-- Timestamps -->
109 <div class="metadata-group">
110 <h5>Timestamps</h5>
111 <div class="metadata-item">
112 <span class="metadata-label">Created:</span>
113 <span class="metadata-value" x-text="$store.memoryDashboardStore.formatTimestamp($store.memoryDashboardStore.detailMemory?.timestamp, false)"></span>
114 </div>
115 </div>
116
117 <!-- Source Information -->
118 <div class="metadata-group" x-show="$store.memoryDashboardStore.detailMemory?.source_file">
119 <h5>Source File</h5>
120 <div class="metadata-item">
121 <span class="metadata-value source-file-display" x-text="$store.memoryDashboardStore.detailMemory?.source_file"></span>
122 </div>
123 </div>
124
125 <!-- All Custom Metadata -->
126 <div class="metadata-group" x-show="$store.memoryDashboardStore.detailMemory?.metadata && Object.keys($store.memoryDashboardStore.detailMemory.metadata).length > 0">
127 <h5>Raw Metadata</h5>
128 <template x-for="[key, value] in Object.entries($store.memoryDashboardStore.detailMemory?.metadata || {})" :key="key">
129 <div class="metadata-item">
130 <span class="metadata-label" x-text="key + ':'"></span>
131 <span class="metadata-value" x-text="typeof value === 'object' ? JSON.stringify(value) : value"></span>
132 </div>
133 </template>
134 </div>
135
136 </div>
137 </div>
138 </div>
139 </template>
140 <style>
141 .modal-header-compact {
142 position: sticky;
143 padding-left: 0.8rem;
144 top: 0;
145 z-index: 100;
146 }
147
148 .header-info {
149 display: flex;
150 align-items: center;
151 gap: 0.5rem;
152 font-size: 0.9rem;
153 }
154
155 .timestamp-text,
156 .source-text {
157 color: var(--color-text);
158 opacity: 0.8;
159 padding: 0.25rem 0.5rem;
160 border-radius: var(--border-radius);
161 font-size: 0.75rem;
162 font-weight: 500;
163 border: 1px solid;
164 }
165
166 .modal-body {
167 display: flex;
168 min-height: 60vh;
169 max-height: 100%;
170 }
171
172 .content-section-main {
173 flex: 1;
174 padding: 1.5rem;
175 padding-bottom: 0;
176 overflow-y: hidden;
177 display: flex;
178 flex-direction: column;
179 }
180
181 .content-block {
182 /* margin-bottom: 3rem; */
183 display: flex;
184 flex-direction: column;
185 min-height: 0;
186 }
187
188 /* Make the first content block (Memory Content) take all available space */
189 .content-block:first-child {
190 flex: 1;
191 /* margin-bottom: 1.5rem; */
192 min-height: 0;
193 }
194
195 .content-block h4 {
196 margin: 0 0 1rem 0;
197 color: var(--color-text);
198 font-size: 1.1rem;
199 font-weight: 600;
200 /* border-bottom: 1px solid var(--color-border); */
201 /* padding-bottom: 0.5rem; */
202 }
203
204 .memory-content-display {
205 border: 1px solid var(--color-border);
206 border-radius: 8px;
207 /* padding: 1.5rem; */
208 line-height: 1.6;
209 color: var(--color-text);
210 /* Fixed height: parent container minus 1rem */
211 flex: 1;
212 min-height: 25em;
213 /* Ensure textarea uses same styling */
214 font-family: inherit;
215 font-size: inherit;
216 resize: none;
217 width: 100%;
218 box-sizing: border-box;
219 overflow: hidden;
220 display: flex;
221 flex-direction: column;
222 }
223
224 .memory-content-display p {
225 background: var(--color-panel);
226 margin: 0;
227 padding: 1.5rem;
228 white-space: pre-wrap;
229 word-break: break-word;
230 overflow-y: auto;
231 overflow-x: hidden;
232 height: 0;
233 flex-grow: 1;
234 }
235
236 textarea.memory-content-display {
237 padding: 1.5rem;
238 overflow-y: auto;
239 display: block;
240 }
241
242 .tags-display {
243 display: flex;
244 flex-wrap: wrap;
245 gap: 0.5rem;
246 background: var(--color-background);
247 padding: 0.75rem;
248 border-radius: 8px;
249 border: 1px solid var(--color-border);
250 }
251
252 .tag-display {
253 background: var(--color-primary);
254 color: white;
255 padding: 0.25rem 0.75rem;
256 border-radius: 12px;
257 font-size: 0.75rem;
258 font-weight: 500;
259 }
260
261 .metadata-sidebar {
262 min-width: 300px;
263 max-width: 350px;
264 background: var(--color-panel);
265 border-left: 1px solid var(--color-border);
266 padding: 1.5rem;
267 overflow-y: auto;
268 max-height: 50em;
269 }
270
271 /* Unified scrollbar styling for modal content */
272 .memory-content-display p::-webkit-scrollbar,
273 textarea.memory-content-display::-webkit-scrollbar {
274 width: 6px;
275 height: 6px;
276 }
277
278 .memory-content-display p::-webkit-scrollbar-track,
279 textarea.memory-content-display::-webkit-scrollbar-track {
280 background: transparent;
281 margin: 4px 0;
282 border-radius: 6px;
283 }
284
285 .memory-content-display p::-webkit-scrollbar-thumb,
286 textarea.memory-content-display::-webkit-scrollbar-thumb {
287 background-color: rgba(155, 155, 155, 0.5);
288 border-radius: 6px;
289 transition: background-color 0.2s ease;
290 }
291
292 .memory-content-display p::-webkit-scrollbar-thumb:hover,
293 textarea.memory-content-display::-webkit-scrollbar-thumb:hover {
294 background-color: rgba(155, 155, 155, 0.7);
295 }
296
297 .metadata-sidebar h4 {
298 margin: 0 0 1rem 0;
299 color: var(--color-text);
300 font-size: 1.1rem;
301 font-weight: 600;
302 }
303
304 .metadata-group {
305 margin-bottom: 1.5rem;
306 }
307
308 .metadata-group h5 {
309 margin: 0 0 0.75rem 0;
310 color: var(--color-text);
311 opacity: 0.7;
312 font-size: 0.9rem;
313 font-weight: 600;
314 text-transform: uppercase;
315 letter-spacing: 0.5px;
316 }
317
318 .metadata-item {
319 display: flex;
320 flex-direction: column;
321 gap: 0.25rem;
322 margin-bottom: 0.75rem;
323 padding: 0.5rem;
324 background: var(--color-background);
325 border: 1px solid var(--color-border);
326 border-radius: 6px;
327 }
328
329 .metadata-label {
330 font-size: 0.8rem;
331 font-weight: 600;
332 color: var(--color-text);
333 opacity: 0.7;
334 text-transform: uppercase;
335 letter-spacing: 0.3px;
336 }
337
338 .metadata-value {
339 font-size: 0.9rem;
340 color: var(--color-text);
341 word-break: break-all;
342 line-height: 1.4;
343 }
344
345 .source-file-display {
346 font-family: monospace;
347 background: var(--color-panel);
348 padding: 0.5rem;
349 border-radius: 4px;
350 border: 1px solid var(--color-border);
351 }
352
353 .memory-detail-container {
354 display: flex;
355 flex-direction: column;
356 height: 100%;
357 }
358
359 /* Responsive design for modal */
360 @media (max-width: 870px) {
361 .modal-body {
362 flex-direction: column;
363 }
364
365 .metadata-sidebar {
366 min-width: unset;
367 max-width: unset;
368 min-height: unset;
369 border-left: none;
370 border-top: 1px solid var(--color-border);
371 }
372
373 .metadata-item {
374 display: block;
375 }
376
377 .modal-header-compact {
378 padding: 0.75rem 1rem;
379 flex-wrap: wrap;
380 gap: 0.75rem;
381 }
382
383 .header-info {
384 flex-wrap: wrap;
385 }
386
387 .content-section-main,
388 .metadata-sidebar {
389 padding: 1rem;
390 }
391 }
392 </style>
393 </div>
394 </body>
395
396 </html>