pinokiod 8.0.75 → 8.0.76
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/package.json +1 -1
- package/server/public/vault.css +34 -0
- package/server/public/vault.js +8 -4
- package/test/vault-ui.test.js +62 -0
package/package.json
CHANGED
package/server/public/vault.css
CHANGED
|
@@ -1678,6 +1678,40 @@ body.vault-page .vault-view-tabs {
|
|
|
1678
1678
|
.vault-view-tabs .vault-nav-count {
|
|
1679
1679
|
font-size: 10.5px;
|
|
1680
1680
|
}
|
|
1681
|
+
.vault-view-tabs .vault-nav-row.attention {
|
|
1682
|
+
background: color-mix(in srgb, var(--vault-warning) 9%, var(--task-panel));
|
|
1683
|
+
color: var(--vault-warning);
|
|
1684
|
+
}
|
|
1685
|
+
.vault-view-tabs .vault-nav-row.attention:hover {
|
|
1686
|
+
background: color-mix(in srgb, var(--vault-warning) 14%, var(--task-panel));
|
|
1687
|
+
}
|
|
1688
|
+
.vault-view-tabs .vault-nav-row.attention.selected {
|
|
1689
|
+
border-bottom-color: var(--task-accent);
|
|
1690
|
+
}
|
|
1691
|
+
.vault-view-tabs .vault-nav-row.attention .vault-nav-name {
|
|
1692
|
+
color: var(--vault-warning);
|
|
1693
|
+
font-weight: 680;
|
|
1694
|
+
}
|
|
1695
|
+
.vault-view-tabs .vault-nav-row.attention .vault-nav-name::before {
|
|
1696
|
+
width: 6px;
|
|
1697
|
+
height: 6px;
|
|
1698
|
+
display: inline-block;
|
|
1699
|
+
margin-right: 6px;
|
|
1700
|
+
border-radius: 50%;
|
|
1701
|
+
background: var(--vault-warning);
|
|
1702
|
+
content: "";
|
|
1703
|
+
vertical-align: 1px;
|
|
1704
|
+
}
|
|
1705
|
+
.vault-view-tabs .vault-nav-row.attention .vault-nav-count {
|
|
1706
|
+
min-width: 20px;
|
|
1707
|
+
padding: 1px 5px;
|
|
1708
|
+
border-radius: 5px;
|
|
1709
|
+
background: color-mix(in srgb, var(--vault-warning) 72%, var(--task-panel));
|
|
1710
|
+
color: #241300;
|
|
1711
|
+
font-weight: 720;
|
|
1712
|
+
line-height: 1.35;
|
|
1713
|
+
text-align: center;
|
|
1714
|
+
}
|
|
1681
1715
|
.vault-pane-action-note { color: var(--task-muted); font-size: 11.5px; white-space: nowrap; }
|
|
1682
1716
|
.vault-toolbar {
|
|
1683
1717
|
display: flex;
|
package/server/public/vault.js
CHANGED
|
@@ -707,16 +707,20 @@ const eventLabels = {
|
|
|
707
707
|
}
|
|
708
708
|
const renderViews = () => {
|
|
709
709
|
const counts = state.data.inventory.counts
|
|
710
|
+
const attentionViews = new Set(["duplicates", "reclaimable"])
|
|
710
711
|
el("views-label").textContent = COPY.views
|
|
711
712
|
const views = IS_APP_MODE
|
|
712
713
|
? ["all", "duplicates", "unavailable", "shared", "tracked", "activity"]
|
|
713
714
|
: ["all", "duplicates", "unavailable", "shared", "tracked", "reclaimable", "activity"]
|
|
714
|
-
el("vault-views").innerHTML = views.map((view) =>
|
|
715
|
-
|
|
715
|
+
el("vault-views").innerHTML = views.map((view) => {
|
|
716
|
+
const needsAttention = attentionViews.has(view) && Number(counts[view]) > 0
|
|
717
|
+
return `
|
|
718
|
+
<button class="vault-nav-row ${state.view === view ? "selected" : ""} ${needsAttention ? "attention" : ""}" type="button" data-view="${view}" ${state.view === view ? 'aria-current="page"' : ""}>
|
|
716
719
|
<i class="${viewIcon[view]}"></i>
|
|
717
720
|
<span class="vault-nav-copy"><span class="vault-nav-name">${esc(viewLabel[view])}</span></span>
|
|
718
|
-
<span class="vault-nav-count ${
|
|
719
|
-
</button>`
|
|
721
|
+
<span class="vault-nav-count ${needsAttention ? "attention" : ""}">${counts[view]}</span>
|
|
722
|
+
</button>`
|
|
723
|
+
}).join("")
|
|
720
724
|
}
|
|
721
725
|
|
|
722
726
|
const renderSourceNode = (source, depth, counts) => {
|
package/test/vault-ui.test.js
CHANGED
|
@@ -548,6 +548,14 @@ describe("Save Space interface", () => {
|
|
|
548
548
|
/body\.vault-page \.vault-view-tabs\s*\{[^}]*padding:\s*0;/s)
|
|
549
549
|
assert.match(vaultCss,
|
|
550
550
|
/body\.dark\.vault-page\s*\{[^}]*--task-panel:\s*var\(--pinokio-sidebar-tabbar-bg\);/s)
|
|
551
|
+
assert.match(vaultCss,
|
|
552
|
+
/\.vault-view-tabs \.vault-nav-row\.attention\s*\{[^}]*background:/s)
|
|
553
|
+
assert.match(vaultCss,
|
|
554
|
+
/\.vault-view-tabs \.vault-nav-row\.attention \.vault-nav-name::before\s*\{[^}]*background:\s*var\(--vault-warning\);/s)
|
|
555
|
+
assert.match(vaultCss,
|
|
556
|
+
/\.vault-view-tabs \.vault-nav-row\.attention \.vault-nav-count\s*\{[^}]*background:/s)
|
|
557
|
+
assert.match(vaultCss,
|
|
558
|
+
/\.vault-view-tabs \.vault-nav-row\.attention\.selected\s*\{[^}]*border-bottom-color:\s*var\(--task-accent\);/s)
|
|
551
559
|
assert.match(vaultCss,
|
|
552
560
|
/\.vault-scan-control\s*>\s*\.vault-scan-action\s*\{[^}]*border-radius:\s*7px 0 0 7px;/s)
|
|
553
561
|
assert.match(vaultCss,
|
|
@@ -2551,6 +2559,60 @@ describe("Save Space interface", () => {
|
|
|
2551
2559
|
dom.window.close()
|
|
2552
2560
|
})
|
|
2553
2561
|
|
|
2562
|
+
test("actionable tabs highlight nonzero cleanup opportunities", async () => {
|
|
2563
|
+
const actionableStatus = fixture([
|
|
2564
|
+
item({
|
|
2565
|
+
path: "/pinokio/api/app/duplicate.bin",
|
|
2566
|
+
relative_path: "duplicate.bin",
|
|
2567
|
+
status: "duplicate",
|
|
2568
|
+
shareable: true
|
|
2569
|
+
}),
|
|
2570
|
+
item({
|
|
2571
|
+
path: "/pinokio/api/app/unused.bin",
|
|
2572
|
+
relative_path: "unused.bin",
|
|
2573
|
+
orphan: true
|
|
2574
|
+
})
|
|
2575
|
+
], {
|
|
2576
|
+
reclaimable: 4096
|
|
2577
|
+
})
|
|
2578
|
+
const { dom } = await makePage(actionableStatus)
|
|
2579
|
+
|
|
2580
|
+
for (const view of ["duplicates", "reclaimable"]) {
|
|
2581
|
+
const tab = dom.window.document.querySelector(`[data-view="${view}"]`)
|
|
2582
|
+
const count = tab.querySelector(".vault-nav-count")
|
|
2583
|
+
assert.equal(count.textContent.trim(), "1")
|
|
2584
|
+
assert.equal(tab.classList.contains("attention"), true)
|
|
2585
|
+
assert.equal(count.classList.contains("attention"), true)
|
|
2586
|
+
}
|
|
2587
|
+
dom.window.close()
|
|
2588
|
+
|
|
2589
|
+
const { dom: emptyDom } = await makePage(fixture([item()]))
|
|
2590
|
+
|
|
2591
|
+
for (const view of ["duplicates", "reclaimable"]) {
|
|
2592
|
+
const tab = emptyDom.window.document.querySelector(`[data-view="${view}"]`)
|
|
2593
|
+
const count = tab.querySelector(".vault-nav-count")
|
|
2594
|
+
assert.equal(count.textContent.trim(), "0")
|
|
2595
|
+
assert.equal(tab.classList.contains("attention"), false)
|
|
2596
|
+
assert.equal(count.classList.contains("attention"), false)
|
|
2597
|
+
}
|
|
2598
|
+
emptyDom.window.close()
|
|
2599
|
+
|
|
2600
|
+
const appStatus = fixture([item({
|
|
2601
|
+
status: "duplicate",
|
|
2602
|
+
shareable: true
|
|
2603
|
+
})])
|
|
2604
|
+
const { dom: appDom } = await makePage(appStatus, {
|
|
2605
|
+
appMode: true,
|
|
2606
|
+
scopeId: "app:app"
|
|
2607
|
+
})
|
|
2608
|
+
|
|
2609
|
+
assert.equal(appDom.window.document.querySelector(
|
|
2610
|
+
'[data-view="duplicates"]').classList.contains("attention"), true)
|
|
2611
|
+
assert.equal(appDom.window.document.querySelector(
|
|
2612
|
+
'[data-view="reclaimable"]'), null)
|
|
2613
|
+
appDom.window.close()
|
|
2614
|
+
})
|
|
2615
|
+
|
|
2554
2616
|
test("app setup remains visible during global scan progress", async () => {
|
|
2555
2617
|
let progressRequests = 0
|
|
2556
2618
|
const status = fixture([], {
|