Build the welcome screen
The welcome window becomes the real thing: Xcode-style, hidden title bar with background drag, branding and actions left, recents right — rows carrying the board symbol, name, location, and the registry's cached lane/card counts (stamped at close, never a scan at welcome time), sorted by last opened. Launch failures surface row-level per 02: a failure joins its recents row as a warning caption, an unresolvable bookmark renders unavailable with Forget its one affordance, and only a failure with no row to carry it falls back to a compact list; a board opening again heals its row. New Board (Opt-Cmd-N) opens the Pages-style template chooser — shipped with the single Basic template and the m9 seams marked — flowing through the save panel into createBoard/createLane and straight into a board window. Open Recent gains its submenu with Clear Menu (byte-identical to forgetting every row, pinned by test), and File > Duplicate forks the frontmost board to a Finder-style copy sibling: pending work flushes first through the close flush's step two alone (sessions stay open — 09's stated exception), every GUID and tombstone carries (the whole-board carve-out from copies-remint), and the copy opens in its own window while the original stays put. 36 new tests. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -1192,6 +1192,13 @@ public enum WriteOperation: Sendable, Equatable, CustomStringConvertible {
|
||||
/// the edit — `updateIndex` enriches it off the document it just read — which is the name the
|
||||
/// user is still looking at when the banner appears.
|
||||
case rename(title: String?)
|
||||
|
||||
/// File ▸ Duplicate — the whole-board copy (03-board-ui.md § Welcome screen & templates). Its
|
||||
/// own case rather than a fold into `.copy`, on `.rename`'s reasoning: the user pressed
|
||||
/// *Duplicate*, and a banner telling them the app could not "copy the item" would name neither
|
||||
/// the command nor the thing. `title` is the board's display name.
|
||||
case duplicateBoard(title: String?)
|
||||
|
||||
case importAttachment(filename: String)
|
||||
case listAttachments
|
||||
case renumberChildren // order-maintenance sweep (compaction)
|
||||
@@ -1218,6 +1225,7 @@ public enum WriteOperation: Sendable, Equatable, CustomStringConvertible {
|
||||
case .style: .style(title: title)
|
||||
case .resize: .resize(title: title)
|
||||
case .rename: .rename(title: title)
|
||||
case .duplicateBoard: .duplicateBoard(title: title)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,6 +1249,7 @@ public enum WriteOperation: Sendable, Equatable, CustomStringConvertible {
|
||||
case let .style(title): Self.phrase("style", title)
|
||||
case let .resize(title): Self.phrase("resize", title)
|
||||
case let .rename(title): Self.phrase("rename", title)
|
||||
case let .duplicateBoard(title): Self.phrase("duplicate board", title)
|
||||
case let .importAttachment(filename): "import attachment '\(filename)'"
|
||||
case .listAttachments: "list attachments"
|
||||
case .renumberChildren: "renumber children"
|
||||
|
||||
Reference in New Issue
Block a user