The sidebar's Actions section retires — Delete and Reveal in Finder move to the card window's toolbar
Actions is gone from the trailing sidebar. Its two rows land on the card
window's toolbar instead: Delete Card is a new default item (trash SF
Symbol), and Reveal in Finder joins the customizable catalog. The sidebar's
final order is now Style, Details, Attachments — no fourth section.
Delete Card is a push button gated by the same read-only predicate the
sidebar button carried, and it fires the identical write
(BoardStore.deleteCard(_:)) — same bracket, same stamps, no confirmation,
matching the delete flow exactly: recovery is the board's trash lane, so
there is nothing here for an alert to guard. It sits behind a trailing
flexibleSpace in the default set, apart from the four creation/view items
ahead of it, the HIG separation Mail.app's own toolbar Delete models —
one-click, no-confirm, recoverable by trash.
Reveal in Finder is catalog-only: it already had a menu-bar twin with no
default chord (File ▸ Reveal in Finder / RevealInFinderCommand), so nothing
was unreachable before this — the toolbar item is Customize's shortcut to
the same computation (CardAttachments.revealURLs), not a new path.
Delete Card needed a menu-row twin of its own before it could sit on the
toolbar at all ("toolbars are pure enhancement: every function they host
already has a menu item + shortcut" — 03-board-ui.md ▸ Toolbar). File ▸
Delete Card is that row: distinctly titled from the board-scope File ▸
Delete (whose title 11-command-nexus.md calls out as the ⌘⌫ chord's
singleton), and deliberately chord-less — an enabled delete-key equivalent
in the card window would steal delete-to-line-start from its text surfaces,
the same reason the board's own ⌘⌫ was never extended here in the first
place. A new small handle, CardWindowActions, carries the wiring through the
focus system the way CardAttachments and CardPrintSubject already do for
their own single-purpose seams — kept separate from CardAttachments on
purpose, since a delete has nothing to do with the attachments section that
type is scoped to.
CardToolbarTests grows the BoardToolbarTests split (defaults vs. catalog,
now that they differ) plus two new suites: Delete Card firing the wired
write under the lock, and Reveal in Finder's enablement mirroring the menu
row's own card-window computation.
05-card-window.md's Actions section and 11-command-nexus.md's File-menu
inventory are now stale; both amendments are owed and tracked on the card's
own thread rather than made here.
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -256,75 +256,3 @@ struct CardStyleSection: View {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
/// The sidebar's **Actions** section, at the bottom of the stack (05-card-window.md ▸ Actions):
|
||||
/// **Delete** — moves the card to the trash — and **Reveal in Finder** — the card's folder.
|
||||
///
|
||||
/// ### Delete writes; the window's dismissal is not its business
|
||||
///
|
||||
/// The button calls `BoardStore.deleteCard`, which is the ⌫ delete exactly (same write op, same
|
||||
/// bracket, same stamps). It does not close this window: the card's move into `.trash/` rounds back through
|
||||
/// the watcher and `CardWindowHost.cardWindowFate` takes the window down, which is the same path a
|
||||
/// delete from the board — or from an agent — already takes. Dismissing from here as well would be a
|
||||
/// second rule able to disagree with the first, and 05's own wording is a sequence rather than a
|
||||
/// pair ("moves the card to the trash; the window then dismisses itself").
|
||||
///
|
||||
/// Recovery is the board's trash column, which is why this needs no confirmation: the card is still
|
||||
/// there to drag out or cut and paste back (03-board-ui.md § Trash — there is no Put Back), and 03
|
||||
/// reserves the alert for the purge that isn't recoverable.
|
||||
///
|
||||
/// ### Reveal is not edit-shaped
|
||||
///
|
||||
/// So it stays enabled under the read-only lock, where Delete does not — inspection is a read (04 ▸
|
||||
/// The trash's posture, shared by the trash row's own Reveal). What it reveals comes from
|
||||
/// `CardAttachments.revealURLs`, the same rule File ▸ Reveal in Finder's card-window scope answers
|
||||
/// through: this button is that rule's card-folder branch by construction, since it is the *card's*
|
||||
/// action rather than the attachment list's.
|
||||
struct CardActionsSection: View {
|
||||
|
||||
let store: BoardStore
|
||||
let cardID: ItemID
|
||||
/// The card's own folder — `nil` only where the window has no board to build it from, which is a
|
||||
/// window on its way out.
|
||||
let cardFolder: URL?
|
||||
|
||||
private var pointSize: CGFloat { CardWindowMetrics.bodyPointSize }
|
||||
|
||||
private var revealURLs: [URL] {
|
||||
CardAttachments.revealURLs(cardFolder: cardFolder, selectedURL: nil, isSectionFocused: false)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: CardWindowMetrics.sidebarRowSpacing(bodyPointSize: pointSize)) {
|
||||
CardSidebarSectionHeader(title: "Actions")
|
||||
|
||||
// Delete above Reveal, which is the order 05 lists them in. Destructive styling, per 05
|
||||
// — the one control in this window that takes the card away. Disabled under the
|
||||
// read-only lock like every other mutation (02-architecture.md's every-entry-point
|
||||
// predicate); that is the attachments section's `isEditable`, read from the store
|
||||
// directly because there is no handle to route it through here and nothing else in this
|
||||
// section that would want one.
|
||||
Button(role: .destructive) {
|
||||
store.deleteCard(cardID)
|
||||
} label: {
|
||||
// The width is the *label's*, not the button's: a bordered button sizes to its label,
|
||||
// so a frame around the button would centre a small pill in a wide row instead of
|
||||
// filling it. Both rows do it, so the two are one column rather than two widths.
|
||||
Text("Delete").frame(maxWidth: .infinity)
|
||||
}
|
||||
.tint(.red)
|
||||
.disabled(store.isReadOnly)
|
||||
|
||||
Button {
|
||||
NSWorkspace.shared.activateFileViewerSelecting(revealURLs)
|
||||
} label: {
|
||||
Text("Reveal in Finder").frame(maxWidth: .infinity)
|
||||
}
|
||||
.disabled(revealURLs.isEmpty)
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user