@andespindola/brainlink 0.1.0-beta.6 → 0.1.0-beta.7
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.
|
@@ -140,7 +140,7 @@ select {
|
|
|
140
140
|
|
|
141
141
|
.inspector {
|
|
142
142
|
display: grid;
|
|
143
|
-
grid-template-rows: auto auto auto
|
|
143
|
+
grid-template-rows: auto auto auto minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
|
|
144
144
|
gap: 22px;
|
|
145
145
|
min-width: 0;
|
|
146
146
|
height: 100%;
|
|
@@ -253,7 +253,7 @@ li small {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
.note-content {
|
|
256
|
-
max-height:
|
|
256
|
+
max-height: min(68svh, 760px);
|
|
257
257
|
margin: 0;
|
|
258
258
|
padding: 12px;
|
|
259
259
|
border: 1px solid var(--line);
|
|
@@ -267,6 +267,80 @@ li small {
|
|
|
267
267
|
line-height: 1.5;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
.content-dialog {
|
|
271
|
+
width: min(920px, calc(100vw - 32px));
|
|
272
|
+
max-height: calc(100svh - 32px);
|
|
273
|
+
padding: 0;
|
|
274
|
+
border: 1px solid var(--line);
|
|
275
|
+
border-radius: 8px;
|
|
276
|
+
background: var(--panel);
|
|
277
|
+
color: var(--text);
|
|
278
|
+
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.48);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.content-dialog::backdrop {
|
|
282
|
+
background: rgba(4, 7, 10, 0.72);
|
|
283
|
+
backdrop-filter: blur(4px);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.content-dialog article {
|
|
287
|
+
display: grid;
|
|
288
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
289
|
+
max-height: calc(100svh - 34px);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.content-dialog header {
|
|
293
|
+
display: flex;
|
|
294
|
+
align-items: flex-start;
|
|
295
|
+
justify-content: space-between;
|
|
296
|
+
gap: 18px;
|
|
297
|
+
padding: 22px;
|
|
298
|
+
border-bottom: 1px solid var(--line);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.content-dialog h2,
|
|
302
|
+
.content-dialog p {
|
|
303
|
+
margin: 0;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.content-dialog h2 {
|
|
307
|
+
margin-top: 6px;
|
|
308
|
+
font-size: 24px;
|
|
309
|
+
line-height: 1.15;
|
|
310
|
+
overflow-wrap: anywhere;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.content-dialog p {
|
|
314
|
+
margin-top: 8px;
|
|
315
|
+
color: var(--muted);
|
|
316
|
+
overflow-wrap: anywhere;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.content-dialog button {
|
|
320
|
+
flex: 0 0 auto;
|
|
321
|
+
height: 38px;
|
|
322
|
+
padding: 0 14px;
|
|
323
|
+
border: 1px solid var(--line);
|
|
324
|
+
border-radius: 8px;
|
|
325
|
+
background: var(--panel-strong);
|
|
326
|
+
color: var(--text);
|
|
327
|
+
cursor: pointer;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.content-dialog button:hover,
|
|
331
|
+
.content-dialog button:focus {
|
|
332
|
+
border-color: var(--accent);
|
|
333
|
+
color: var(--accent);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.content-dialog .note-content {
|
|
337
|
+
max-height: none;
|
|
338
|
+
min-height: 0;
|
|
339
|
+
border: 0;
|
|
340
|
+
border-radius: 0;
|
|
341
|
+
padding: 22px;
|
|
342
|
+
}
|
|
343
|
+
|
|
270
344
|
@media (max-width: 860px) {
|
|
271
345
|
.shell {
|
|
272
346
|
grid-template-columns: 1fr;
|
|
@@ -291,4 +365,9 @@ li small {
|
|
|
291
365
|
.agent-filter {
|
|
292
366
|
width: 100%;
|
|
293
367
|
}
|
|
368
|
+
|
|
369
|
+
.content-dialog header {
|
|
370
|
+
align-items: stretch;
|
|
371
|
+
flex-direction: column;
|
|
372
|
+
}
|
|
294
373
|
}`;
|
|
@@ -47,10 +47,6 @@ export const createClientHtml = () => `<!doctype html>
|
|
|
47
47
|
<h2>Notes</h2>
|
|
48
48
|
<ul id="notes"></ul>
|
|
49
49
|
</section>
|
|
50
|
-
<section>
|
|
51
|
-
<h2>Content</h2>
|
|
52
|
-
<pre id="content" class="note-content"></pre>
|
|
53
|
-
</section>
|
|
54
50
|
<section>
|
|
55
51
|
<h2>Outgoing</h2>
|
|
56
52
|
<ul id="outgoing"></ul>
|
|
@@ -61,6 +57,19 @@ export const createClientHtml = () => `<!doctype html>
|
|
|
61
57
|
</section>
|
|
62
58
|
</aside>
|
|
63
59
|
</main>
|
|
60
|
+
<dialog id="contentDialog" class="content-dialog" aria-labelledby="contentTitle">
|
|
61
|
+
<article>
|
|
62
|
+
<header>
|
|
63
|
+
<div>
|
|
64
|
+
<span class="eyebrow">Markdown content</span>
|
|
65
|
+
<h2 id="contentTitle">Selected note</h2>
|
|
66
|
+
<p id="contentPath"></p>
|
|
67
|
+
</div>
|
|
68
|
+
<button id="contentClose" type="button">Close</button>
|
|
69
|
+
</header>
|
|
70
|
+
<pre id="contentBody" class="note-content"></pre>
|
|
71
|
+
</article>
|
|
72
|
+
</dialog>
|
|
64
73
|
<script src="/app.js"></script>
|
|
65
74
|
</body>
|
|
66
75
|
</html>`;
|
|
@@ -31,7 +31,6 @@ const elements = {
|
|
|
31
31
|
path: byId('path'),
|
|
32
32
|
tags: byId('tags'),
|
|
33
33
|
notes: byId('notes'),
|
|
34
|
-
content: byId('content'),
|
|
35
34
|
outgoing: byId('outgoing'),
|
|
36
35
|
incoming: byId('incoming'),
|
|
37
36
|
nodeCount: byId('nodeCount'),
|
|
@@ -39,7 +38,12 @@ const elements = {
|
|
|
39
38
|
tagCount: byId('tagCount'),
|
|
40
39
|
zoomIn: byId('zoomIn'),
|
|
41
40
|
zoomOut: byId('zoomOut'),
|
|
42
|
-
reset: byId('reset')
|
|
41
|
+
reset: byId('reset'),
|
|
42
|
+
contentDialog: byId('contentDialog'),
|
|
43
|
+
contentTitle: byId('contentTitle'),
|
|
44
|
+
contentPath: byId('contentPath'),
|
|
45
|
+
contentBody: byId('contentBody'),
|
|
46
|
+
contentClose: byId('contentClose')
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
const agentQuery = () => state.agentId ? '?agent=' + encodeURIComponent(state.agentId) : ''
|
|
@@ -128,7 +132,7 @@ const encodeEntityTag = (value) => {
|
|
|
128
132
|
binary += String.fromCharCode(utf8[index])
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
return btoa(binary).
|
|
135
|
+
return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/g, '')
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
const graphSignature = graph => JSON.stringify({
|
|
@@ -278,14 +282,23 @@ const allNotesList = () => state.nodes.length
|
|
|
278
282
|
? state.nodes.map(node => '<li><button type="button" data-node-id="' + escapeHtml(node.id) + '">' + escapeHtml(node.title) + '</button><small>' + escapeHtml(node.path) + '</small></li>').join('')
|
|
279
283
|
: '<li><small>No notes indexed.</small></li>'
|
|
280
284
|
|
|
281
|
-
const
|
|
285
|
+
const openContentDialog = node => {
|
|
286
|
+
if (!node) return
|
|
287
|
+
elements.contentTitle.textContent = node.title
|
|
288
|
+
elements.contentPath.textContent = node.path
|
|
289
|
+
elements.contentBody.textContent = node.content
|
|
290
|
+
if (!elements.contentDialog.open) {
|
|
291
|
+
elements.contentDialog.showModal()
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const selectNode = (node, options = { openContent: false }) => {
|
|
282
296
|
state.selected = node
|
|
283
297
|
if (!node) {
|
|
284
298
|
elements.title.textContent = 'Graph Overview'
|
|
285
299
|
elements.path.textContent = state.nodes.length + ' notes and ' + state.graph.edges.length + ' links indexed.'
|
|
286
300
|
elements.tags.innerHTML = ''
|
|
287
301
|
elements.notes.innerHTML = allNotesList()
|
|
288
|
-
elements.content.textContent = 'Selecione uma nota no grafo ou na lista para ver o Markdown completo, backlinks e links de saida.'
|
|
289
302
|
elements.outgoing.innerHTML = '<li><small>Select a note to inspect outgoing links.</small></li>'
|
|
290
303
|
elements.incoming.innerHTML = '<li><small>Select a note to inspect backlinks.</small></li>'
|
|
291
304
|
return
|
|
@@ -311,14 +324,14 @@ const selectNode = node => {
|
|
|
311
324
|
? node.tags.map(tag => '<span>#' + escapeHtml(tag) + '</span>').join('')
|
|
312
325
|
: '<span>No tags</span>'
|
|
313
326
|
elements.notes.innerHTML = allNotesList()
|
|
314
|
-
elements.content.textContent = node.content
|
|
315
327
|
elements.outgoing.innerHTML = list(outgoing)
|
|
316
328
|
elements.incoming.innerHTML = list(incoming)
|
|
329
|
+
if (options.openContent) openContentDialog(node)
|
|
317
330
|
}
|
|
318
331
|
|
|
319
332
|
const selectNodeById = id => {
|
|
320
333
|
const node = state.nodes.find(item => item.id === id)
|
|
321
|
-
if (node) selectNode(node)
|
|
334
|
+
if (node) selectNode(node, { openContent: true })
|
|
322
335
|
}
|
|
323
336
|
|
|
324
337
|
const zoom = factor => {
|
|
@@ -344,6 +357,10 @@ const bindEvents = () => {
|
|
|
344
357
|
elements.zoomIn.addEventListener('click', () => zoom(1.18))
|
|
345
358
|
elements.zoomOut.addEventListener('click', () => zoom(0.84))
|
|
346
359
|
elements.reset.addEventListener('click', resetView)
|
|
360
|
+
elements.contentClose.addEventListener('click', () => elements.contentDialog.close())
|
|
361
|
+
elements.contentDialog.addEventListener('click', event => {
|
|
362
|
+
if (event.target === elements.contentDialog) elements.contentDialog.close()
|
|
363
|
+
})
|
|
347
364
|
;[elements.notes, elements.outgoing, elements.incoming].forEach(element => {
|
|
348
365
|
element.addEventListener('click', event => {
|
|
349
366
|
const target = event.target
|
|
@@ -384,8 +401,8 @@ const bindEvents = () => {
|
|
|
384
401
|
state.transform.y += dy
|
|
385
402
|
})
|
|
386
403
|
canvas.addEventListener('pointerup', event => {
|
|
387
|
-
if (state.pointer.dragNode && !state.pointer.moved) selectNode(state.pointer.dragNode)
|
|
388
|
-
if (!state.pointer.dragNode && !state.pointer.moved) selectNode(state.hovered)
|
|
404
|
+
if (state.pointer.dragNode && !state.pointer.moved) selectNode(state.pointer.dragNode, { openContent: true })
|
|
405
|
+
if (!state.pointer.dragNode && !state.pointer.moved) selectNode(state.hovered, { openContent: true })
|
|
389
406
|
state.pointer = { x: 0, y: 0, down: false, dragNode: null, moved: false }
|
|
390
407
|
canvas.releasePointerCapture(event.pointerId)
|
|
391
408
|
})
|
package/package.json
CHANGED