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:
+34
-6
@@ -55,11 +55,30 @@ struct KanbanApp: App {
|
||||
}
|
||||
.defaultLaunchBehavior(shouldRestoreAtLaunch ? .suppressed : .automatic)
|
||||
.restorationBehavior(.disabled)
|
||||
.windowResizability(.contentSize)
|
||||
// "Welcome: resizable, no title bar (background drag)" (03-board-ui.md § Welcome screen &
|
||||
// templates). `.contentMinSize` rather than `.contentSize`, because the view states a
|
||||
// *minimum* and the recents list is meant to take whatever space the user gives it; the
|
||||
// hidden title bar is why `WelcomeView` carries a `WindowDragGesture`.
|
||||
.windowResizability(.contentMinSize)
|
||||
.defaultSize(width: 820, height: 500)
|
||||
.windowStyle(.hiddenTitleBar)
|
||||
// Its automatic Window-menu item is replaced by the explicit command below, so the title is
|
||||
// the one 11-command-nexus.md names rather than whatever the scene happens to be called.
|
||||
.commandsRemoved()
|
||||
|
||||
// The template chooser (09-templates.md), reached from File ▸ New Board… ⌥⌘N and from
|
||||
// welcome's own button. A `Window` for welcome's reason — there is one of it, ever — and
|
||||
// suppressed at launch, since ⌥⌘N is the only thing that ever asks for it.
|
||||
Window("New Board", id: WindowID.templateChooser) {
|
||||
TemplateChooserView()
|
||||
.environment(appModel)
|
||||
.captureWindowActions(into: appModel)
|
||||
}
|
||||
.defaultLaunchBehavior(.suppressed)
|
||||
.restorationBehavior(.disabled)
|
||||
.windowResizability(.contentSize)
|
||||
.commandsRemoved()
|
||||
|
||||
Window("", id: WindowID.restoreBootstrap) {
|
||||
RestoreBootstrapView()
|
||||
.environment(appModel)
|
||||
@@ -107,13 +126,15 @@ struct KanbanApp: App {
|
||||
/// changing one silently breaks every remap of it.
|
||||
@CommandsBuilder
|
||||
private var menuCommands: some Commands {
|
||||
// The File group, in 11-command-nexus.md's own row order: New Card, New Lane, (New Board…,
|
||||
// still owed), Open…, (Open Recent, still owed), Board Info, (Duplicate / Save as Template /
|
||||
// Reveal in Finder, still owed), then the trash trio and Empty Trash…. Every one of them
|
||||
// validates against the frontmost board through the focus system, so each is simply
|
||||
// absent-of-effect when no board is in front.
|
||||
// The File group, in 11-command-nexus.md's own row order: New Card, New Lane, New Board…,
|
||||
// Open…, Open Recent ▸, Board Info, Duplicate, (Save as Template, still owed — 09),
|
||||
// Reveal in Finder, then the trash trio and Empty Trash…. The board-scoped ones validate
|
||||
// against the frontmost board through the focus system, so each is simply absent-of-effect
|
||||
// when no board is in front; New Board… and Open Recent are available everywhere, including
|
||||
// with no window at all.
|
||||
CommandGroup(after: .newItem) {
|
||||
BoardCreationCommands()
|
||||
NewBoardCommand(appModel: appModel)
|
||||
|
||||
Divider()
|
||||
|
||||
@@ -122,12 +143,19 @@ struct KanbanApp: App {
|
||||
}
|
||||
.keyboardShortcut("o", modifiers: .command)
|
||||
|
||||
OpenRecentMenu(appModel: appModel)
|
||||
|
||||
Divider()
|
||||
|
||||
BoardInfoCommand()
|
||||
|
||||
Divider()
|
||||
|
||||
DuplicateBoardCommand(appModel: appModel)
|
||||
RevealInFinderCommand()
|
||||
|
||||
Divider()
|
||||
|
||||
TrashCommands()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user