fix: restrict inbox to captured artifacts
This commit is contained in:
parent
58a74acbf6
commit
2e86229350
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -16,7 +16,7 @@
|
|||
background: #13131f;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/main-4y6wyoK9.js"></script>
|
||||
<script type="module" crossorigin src="/assets/main-O6a-DCWF.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-es_E5H-H.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -2,30 +2,30 @@ package main
|
|||
|
||||
import "testing"
|
||||
|
||||
func TestListInboxNodesReturnsOnlyUnassignedRoots(t *testing.T) {
|
||||
func TestListInboxNodesReturnsOnlyCapturedArtifacts(t *testing.T) {
|
||||
app, _ := setupTestApp(t)
|
||||
|
||||
unassigned, err := app.CreateNodeFromTemplate("", "Unassigned Root", "folder.default")
|
||||
manual, err := app.CreateNodeFromTemplate("", "Manual Root", "folder.default")
|
||||
if err != nil {
|
||||
t.Fatalf("create unassigned root: %v", err)
|
||||
t.Fatalf("create manual root: %v", err)
|
||||
}
|
||||
inbox, err := app.CreateNodeFromTemplate("", "Inbox Root", "folder.default")
|
||||
legacyInbox, err := app.CreateNodeFromTemplate("", "Legacy Inbox Root", "folder.default")
|
||||
if err != nil {
|
||||
t.Fatalf("create inbox root: %v", err)
|
||||
t.Fatalf("create legacy inbox root: %v", err)
|
||||
}
|
||||
assigned, err := app.CreateNodeFromTemplate("", "Assigned Root", "folder.default")
|
||||
captured, err := app.CreateNodeFromTemplate("", "Captured Artifact", "folder.default")
|
||||
if err != nil {
|
||||
t.Fatalf("create assigned root: %v", err)
|
||||
t.Fatalf("create captured artifact: %v", err)
|
||||
}
|
||||
child, err := app.CreateNodeFromTemplate(unassigned.ID, "Nested Child", "folder.default")
|
||||
child, err := app.CreateNodeFromTemplate(captured.ID, "Nested Child", "folder.default")
|
||||
if err != nil {
|
||||
t.Fatalf("create child: %v", err)
|
||||
}
|
||||
if _, err := app.db.Exec(`UPDATE nodes SET section = 'inbox' WHERE id = ?`, inbox.ID); err != nil {
|
||||
t.Fatalf("mark inbox: %v", err)
|
||||
if _, err := app.db.Exec(`UPDATE nodes SET section = 'inbox' WHERE id = ?`, legacyInbox.ID); err != nil {
|
||||
t.Fatalf("mark legacy inbox: %v", err)
|
||||
}
|
||||
if _, err := app.db.Exec(`UPDATE nodes SET section = 'projects' WHERE id = ?`, assigned.ID); err != nil {
|
||||
t.Fatalf("mark assigned: %v", err)
|
||||
if err := app.nodes.MetaSet(captured.ID, "capture.inbox", "true"); err != nil {
|
||||
t.Fatalf("mark captured: %v", err)
|
||||
}
|
||||
|
||||
list, err := app.ListInboxNodes()
|
||||
|
|
@ -37,14 +37,14 @@ func TestListInboxNodesReturnsOnlyUnassignedRoots(t *testing.T) {
|
|||
for _, item := range list {
|
||||
got[item.ID] = true
|
||||
}
|
||||
if !got[unassigned.ID] {
|
||||
t.Fatal("unassigned root missing from inbox")
|
||||
if !got[captured.ID] {
|
||||
t.Fatal("captured artifact missing from inbox")
|
||||
}
|
||||
if !got[inbox.ID] {
|
||||
t.Fatal("section=inbox root missing from inbox")
|
||||
if got[manual.ID] {
|
||||
t.Fatal("manual root should not be in inbox")
|
||||
}
|
||||
if got[assigned.ID] {
|
||||
t.Fatal("assigned root should not be in inbox")
|
||||
if got[legacyInbox.ID] {
|
||||
t.Fatal("section=inbox root without capture metadata should not be in inbox")
|
||||
}
|
||||
if got[child.ID] {
|
||||
t.Fatal("nested child should not be in inbox")
|
||||
|
|
|
|||
|
|
@ -2004,7 +2004,6 @@
|
|||
<h2>{t('nav.inbox')}</h2>
|
||||
<p>{t('inbox.subtitle')}</p>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm" on:click={openCreateRoot}>+ {t('nav.createNode')}</button>
|
||||
</div>
|
||||
{#if inboxNodes.length === 0}
|
||||
<div class="empty-state">
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default {
|
|||
'nav.createInside': 'Create inside',
|
||||
'nav.createNode': 'Create element',
|
||||
'nav.moveToRoot': 'Move to root',
|
||||
'inbox.subtitle': 'Root items without an assigned section',
|
||||
'inbox.subtitle': 'Captured materials that still need to be assigned to cases',
|
||||
'inbox.empty': 'No unprocessed items',
|
||||
'trash.openFolder': 'Open trash folder',
|
||||
'trash.empty': 'Trash is empty',
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default {
|
|||
'nav.createNode': 'Создать элемент',
|
||||
'nav.moveToRoot': 'Переместить в корень',
|
||||
|
||||
'inbox.subtitle': 'Корневые элементы без назначенного раздела',
|
||||
'inbox.subtitle': 'Захваченные материалы, которые нужно разложить по делам',
|
||||
'inbox.empty': 'Неразобранных элементов нет',
|
||||
|
||||
'trash.openFolder': 'Открыть папку корзины',
|
||||
|
|
|
|||
|
|
@ -169,10 +169,13 @@ func (r *Repository) ListRoots(includeDeleted bool) ([]Node, error) {
|
|||
return scanNodes(rows)
|
||||
}
|
||||
|
||||
// ListInboxRoots returns active root nodes that are not assigned to a specific section.
|
||||
// ListInboxRoots returns active root capture artifacts explicitly marked for inbox.
|
||||
func (r *Repository) ListInboxRoots(includeDeleted bool) ([]Node, error) {
|
||||
q := `SELECT ` + nodeColumns + ` FROM nodes
|
||||
WHERE parent_id IS NULL AND COALESCE(section, '') IN ('', 'inbox')`
|
||||
WHERE parent_id IS NULL
|
||||
AND id IN (
|
||||
SELECT node_id FROM node_meta WHERE key = 'capture.inbox' AND value = 'true'
|
||||
)`
|
||||
if !includeDeleted {
|
||||
q += " AND deleted_at IS NULL"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,8 @@ async function runReadyScenario(cdp, url) {
|
|||
|
||||
await clickText(cdp, '.nav-item', 'Неразобранное')
|
||||
await assertText(cdp, 'Неразобранное', 'inbox: system view opens')
|
||||
await assertText(cdp, 'Inbox Smoke Item', 'inbox: unassigned item visible')
|
||||
await assertText(cdp, 'Inbox Smoke Item', 'inbox: captured item visible')
|
||||
await assertEval(cdp, `!document.querySelector('.inbox-screen')?.innerText.includes('Manual Root Item')`, 'inbox: manual root is hidden')
|
||||
await screenshot(cdp, 'inbox.png')
|
||||
await clickText(cdp, '.inbox-item-actions .btn', 'Открыть')
|
||||
await assertText(cdp, 'Inbox Smoke Item', 'inbox: item opens from list')
|
||||
|
|
@ -577,7 +578,8 @@ function wailsMockSource() {
|
|||
],
|
||||
},
|
||||
{ id: 'node-client', title: 'Smoke Client', type: 'client', section: 'clients', createdAt: now, has_children: false, children: [] },
|
||||
{ id: 'node-inbox', title: 'Inbox Smoke Item', type: 'folder', section: '', createdAt: now, has_children: false, children: [] },
|
||||
{ id: 'node-inbox', title: 'Inbox Smoke Item', type: 'folder', section: '', captureInbox: true, createdAt: now, has_children: false, children: [] },
|
||||
{ id: 'node-manual-root', title: 'Manual Root Item', type: 'folder', section: '', createdAt: now, has_children: false, children: [] },
|
||||
],
|
||||
notes: {
|
||||
'node-project': [{ id: 'note-1', title: 'Smoke note', createdAt: now }],
|
||||
|
|
@ -685,7 +687,7 @@ function wailsMockSource() {
|
|||
],
|
||||
ListWorkspaceTree: async () => clone(state.nodes),
|
||||
ListWorkspaceChildren: async (id) => clone(childrenOf(id)),
|
||||
ListInboxNodes: async () => clone(state.nodes.filter((node) => !node.parent_id && (!node.section || node.section === 'inbox'))),
|
||||
ListInboxNodes: async () => clone(state.nodes.filter((node) => !node.parent_id && node.captureInbox === true)),
|
||||
ListTrash: async () => clone({
|
||||
trashPath: '/tmp/verstak-smoke-vault/.verstak/trash',
|
||||
nodes: [{ id: 'node-trash', title: 'Trash Smoke Folder', type: 'folder', fsPath: 'Trash Smoke Folder', deletedAt: now }],
|
||||
|
|
|
|||
Loading…
Reference in New Issue