Open task views in a sheet over the left pane

This commit is contained in:
Ian Gulliver
2026-10-21 17:00:07 -07:00
parent ccb08ab6ec
commit 193401021a
22 changed files with 698 additions and 546 deletions
+46 -18
View File
@@ -58,6 +58,8 @@ struct MainView: View {
let overlays = overlays
overlays.install { key in
ctrlGo(key, store, overlays)
} escape: {
store.closeSheet()
}
}
.onDisappear {
@@ -107,22 +109,22 @@ private struct LeftPane: View {
VStack(spacing: 0) {
HStack(spacing: 4) {
PaneTabButton(label: "Lead", active: tab == .lead) {
overlays.leftTab = .lead
pick(.lead)
}
PaneTabButton(label: "Notes", active: tab == .notes) {
overlays.leftTab = .notes
pick(.notes)
}
PaneTabButton(label: "Workflows", active: tab == .workflows) {
overlays.leftTab = .workflows
pick(.workflows)
}
PaneTabButton(label: "Status", active: tab == .status) {
overlays.leftTab = .status
pick(.status)
}
PaneTabButton(label: "Server", active: tab == .server) {
overlays.leftTab = .server
pick(.server)
}
PaneTabButton(label: "Settings", active: tab == .settings) {
overlays.leftTab = .settings
pick(.settings)
}
Spacer(minLength: 0)
HStack(spacing: 10) {
@@ -162,6 +164,18 @@ private struct LeftPane: View {
SettingsView()
}
}
.overlay {
if let sheet = store.sheet, sheet.owner != .lead {
SheetHost(sheet: sheet)
}
}
}
}
private func pick(_ tab: LeftTab) {
overlays.leftTab = tab
if store.sheet?.owner != .lead {
store.sheet = nil
}
}
}
@@ -175,12 +189,19 @@ private struct TaskPane: View {
let accent = selected.map { taskPalette[$0.color] } ?? Palette.accent
VStack(spacing: 0) {
TaskBar()
TabStrip()
tabBody
.frame(maxWidth: .infinity, maxHeight: .infinity)
VStack(spacing: 0) {
TabStrip()
TaskTabBody(tab: store.primaryTab)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.overlay {
if let sheet = store.sheet, sheet.owner == .lead {
SheetHost(sheet: sheet)
}
}
}
.environment(\.paneAccent, accent)
.environment(\.inRightPane, true)
.environment(\.inTask, true)
.onGeometryChange(for: CGRect.self) { g in
g.frame(in: .global)
} action: { frame in
@@ -192,10 +213,14 @@ private struct TaskPane: View {
overlays.paneFrame = frame
}
}
}
@ViewBuilder
private var tabBody: some View {
switch store.shownTab {
struct TaskTabBody: View {
let tab: TaskTab
@Environment(Store.self) private var store
var body: some View {
switch tab {
case .transcript:
ChatView(kind: .task(store.selectedTaskId))
.id("\(store.selectedTaskId ?? "")/\(store.selectedTaskId.flatMap { store.pickedMember($0) } ?? "")")
@@ -342,9 +367,12 @@ private struct TabStrip: View {
}
private func info() -> Info {
let tab = store.shownTab
let run = store.selectedTaskId.flatMap { store.findTask($0) }?.workflow != nil
let team = store.selectedTaskId.map { !store.team($0).isEmpty } ?? false
let tab = store.sheet.flatMap { $0.owner == .lead ? nil : $0.tab } ?? store.primaryTab
guard let taskId = store.selectedTaskId else {
return Info(order: [.project], tab: .project)
}
let run = store.findTask(taskId)?.workflow != nil
let team = !store.team(taskId).isEmpty
let order = taskTabs.filter { t in
if run {
return t == .workflow || t == .project
@@ -389,14 +417,14 @@ private struct TabStrip: View {
HStack(spacing: 4) {
ForEach(info.order.filter { kept.contains($0) }, id: \.self) { t in
PaneTabButton(label: tabLabels[t]!, active: t == info.tab) {
store.focusTab(t)
store.openTab(t)
}
}
if !hidden.isEmpty {
MoreButton {
overlays.menu = OverlayMenu(anchor: moreFrame, accent: accent, entries: hidden.map { t in
MenuEntry(id: t.rawValue, label: tabLabels[t]!) {
store.focusTab(t)
store.openTab(t)
}
})
}