The lane and card lists give up their pickers — rank order is the only order below the boards

The sort control stays on the board list alone; lanes and cards return
to the arrangement the ranks state, long-press reorder now ungated
because the rows always show the order a drag would rewrite.
ItemSortOrder leaves with the pickers that needed it.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-08-08 13:41:09 -04:00
parent 2d919b8131
commit 28abaac2d9
4 changed files with 16 additions and 169 deletions
-56
View File
@@ -1,56 +0,0 @@
import Foundation
/// How the lane and card lists order their rows. Raw values are persisted (`AppStorage`), so
/// they are API. `.manual` is the board's own arrangement the rank order the loader already
/// delivered and sorting here is display-only: it never rewrites ranks on disk.
enum ItemSortOrder: String, CaseIterable, Sendable {
case manual
case name
case recent
}
extension ItemSortOrder {
/// Orders `items` for display without touching the manual arrangement they arrived in.
///
/// **`.manual` is a no-op** `items` is already in the loader's rank order, so this returns it
/// unchanged.
///
/// **`.name` sorts by `title`**, case/diacritic-insensitive (`localizedStandardCompare`). Callers
/// pass the row's own display title the "Untitled Lane"/"Untitled Card" fallback already
/// applied so there is no separate nil case to sort here.
///
/// **`.recent` sorts by `modified` descending, with `nil` last.** Both sorts tie-break the same
/// way: Swift's `sort` is not a stable sort, so ties equal titles, equal or absent dates keep
/// the incoming order via each item's original offset, exactly as `BoardSortOrder.sorted` does.
nonisolated func sorted<Item>(
_ items: [Item],
title: (Item) -> String,
modified: (Item) -> Date?
) -> [Item] {
switch self {
case .manual:
return items
case .name:
return items.enumerated().sorted { lhs, rhs in
let comparison = title(lhs.element).localizedStandardCompare(title(rhs.element))
if comparison != .orderedSame { return comparison == .orderedAscending }
return lhs.offset < rhs.offset
}.map(\.element)
case .recent:
return items.enumerated().sorted { lhs, rhs in
switch (modified(lhs.element), modified(rhs.element)) {
case let (l?, r?) where l != r:
return l > r
case (nil, .some):
return false
case (.some, nil):
return true
default:
return lhs.offset < rhs.offset
}
}.map(\.element)
}
}
}