pinokiod 8.0.112 → 8.0.114

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "8.0.112",
3
+ "version": "8.0.114",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1647,16 +1647,20 @@ body[data-vault-mode="global"] .vault-explorer {
1647
1647
  }
1648
1648
  .vault-text-button:hover { color: var(--task-text); }
1649
1649
  .vault-text-button:disabled { cursor: progress; opacity: .55; }
1650
+ /* The list is the only part that grows and scrolls; every other row keeps its
1651
+ own height. Laying this out as fixed grid rows tied the footer's position to
1652
+ how many children happened to be in flow, and a status row appearing or a
1653
+ mode declaring a different count pushed the footer out of the pane, where no
1654
+ amount of scrolling could reach it. */
1650
1655
  .vault-pane {
1651
- display: grid;
1656
+ display: flex;
1652
1657
  min-width: 0;
1653
1658
  min-height: 0;
1654
- grid-template-rows: auto auto minmax(0, 1fr) auto;
1659
+ flex-direction: column;
1655
1660
  overflow: hidden;
1656
1661
  }
1657
- body[data-vault-mode="global"] .vault-pane {
1658
- grid-template-rows: auto auto auto minmax(0, 1fr) auto;
1659
- }
1662
+ .vault-pane > * { flex: 0 0 auto; }
1663
+ .vault-pane > .vault-table-wrap { min-height: 0; flex: 1 1 auto; }
1660
1664
  body.vault-page .vault-view-tabs {
1661
1665
  display: block;
1662
1666
  min-width: 0;
@@ -2192,6 +2196,10 @@ body.dark .vault-row-action .vault-text-button:hover:not(:disabled) {
2192
2196
  align-items: center;
2193
2197
  justify-content: space-between;
2194
2198
  gap: 12px;
2199
+ /* Now that it holds its own place at the bottom, it needs an edge: a short
2200
+ list leaves empty space above it, and without a rule it reads as a stray
2201
+ line of text rather than the foot of the table. */
2202
+ border-top: 1px solid var(--task-border);
2195
2203
  padding: 9px var(--vault-inline) 11px;
2196
2204
  color: var(--task-muted);
2197
2205
  font-size: 10.5px;
@@ -2380,10 +2380,13 @@ const renderTable = (items) => {
2380
2380
  state.view === "reclaimable"
2381
2381
  const sizeSortLabel = state.sizeSort === "desc" ? COPY.sort_smallest : COPY.sort_largest
2382
2382
  const sizeSortIcon = state.sizeSort === "desc" ? "fa-arrow-down-wide-short" : state.sizeSort === "asc" ? "fa-arrow-up-short-wide" : "fa-sort"
2383
- // Only where the page order is the name order: the duplicate, reclaimable
2384
- // and activity lists are paged by something else, so reordering their rows
2385
- // would only reorder the page the user happens to be on.
2386
- const sortableName = tableClass === "flat" || tableClass === "inventory"
2383
+ // Every table whose rows are paths, which is every one whose Name column
2384
+ // holds a name. Content groups are labelled with a sample path rather than an
2385
+ // identity, Trash rows are labelled with a hash, and Activity is a log kept in
2386
+ // time order, so none of the three has a name to sort by.
2387
+ const sortableName = tableClass === "flat" ||
2388
+ tableClass === "inventory" ||
2389
+ tableClass === "matches"
2387
2390
  const nameSortLabel = state.nameSort === "desc" ? COPY.sort_a_z : COPY.sort_z_a
2388
2391
  const nameSortIcon = state.nameSort === "desc"
2389
2392
  ? "fa-arrow-down-z-a"
@@ -956,6 +956,53 @@ describe("Save Space interface", () => {
956
956
  dom.window.close()
957
957
  })
958
958
 
959
+ test("name sorting is offered wherever the Name column holds a name", async () => {
960
+ const duplicate = item({
961
+ path: "/pinokio/api/app/models/duplicate.bin",
962
+ relative_path: "models/duplicate.bin",
963
+ status: "duplicate",
964
+ shareable: true,
965
+ location_count: 2
966
+ })
967
+ const base = fixture([duplicate])
968
+ base.inventory.source_counts.duplicates["app:app"] = 1
969
+ base.inventory.shareable_by_source["app:app"] = 1
970
+ const { dom } = await makePage(base)
971
+ const document = dom.window.document
972
+ const controls = () => ({
973
+ name: !!document.querySelector("[data-sort-name]"),
974
+ size: !!document.querySelector("[data-sort-size]")
975
+ })
976
+
977
+ // Rows are paths here, in either display mode.
978
+ assert.deepEqual(controls(), { name: true, size: true })
979
+ document.querySelector('[data-display-mode="files"]').click()
980
+ await waitFor(() => document.querySelector(
981
+ '[data-display-mode="files"].selected'))
982
+ assert.deepEqual(controls(), { name: true, size: true })
983
+
984
+ document.querySelector('[data-view="duplicates"]').click()
985
+ await waitFor(() => document.querySelector(
986
+ '[data-view="duplicates"].selected'))
987
+ // Duplicates in Folders is an ordinary tree of paths.
988
+ assert.deepEqual(controls(), { name: true, size: true })
989
+
990
+ document.querySelector('[data-display-mode="files"]').click()
991
+ await waitFor(() => document.querySelector(
992
+ '[data-display-mode="files"].selected'))
993
+ // Content groups are labelled with a sample path, not an identity, so
994
+ // ordering them by name would order them by an arbitrary member.
995
+ assert.deepEqual(controls(), { name: false, size: true })
996
+
997
+ document.querySelector('[data-view="activity"]').click()
998
+ await waitFor(() => document.querySelector(
999
+ '[data-view="activity"].selected'))
1000
+ // A log is kept in time order.
1001
+ assert.deepEqual(controls(), { name: false, size: false })
1002
+ await settle()
1003
+ dom.window.close()
1004
+ })
1005
+
959
1006
  test("a copy elsewhere links only when it can be pointed at", async () => {
960
1007
  const duplicate = item({
961
1008
  path: "/pinokio/api/app/models/duplicate.bin",