Show a colour-coded team picker instead of cycling with T
T used to silently cycle Model.activeTeamID through the caller's teams with no visible list of choices. It now opens a full picker (modelled on the existing user picker) listing every team plus "All teams", each with a stable identity colour from a new six-colour theme palette. The same colour now also shows as a bullet next to "team: <name>" in the header, so the active team stays visible without opening the picker. Adds an Identity palette to the theme package (six hues, skipping the ones that already mean firing/critical), Styles.TeamColor to pick one by team id, and identity_1..6 as theme-file tokens alongside the existing twelve so a fully custom theme can still set every token.
This commit is contained in:
+53
-17
@@ -34,6 +34,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.rebuildArchivedTable()
|
||||
m.rebuildScheduleTable()
|
||||
m.rebuildUserPickerTable()
|
||||
m.rebuildTeamPickerTable()
|
||||
m.rebuildUserManageTable()
|
||||
m.detailViewport.Width = m.width
|
||||
m.detailViewport.Height = m.detailViewportHeight()
|
||||
@@ -400,6 +401,12 @@ func (m Model) routeKey(msg tea.KeyMsg) (Model, tea.Cmd) {
|
||||
m2, ourCmd := m.handleKey(msg)
|
||||
return m2, tea.Batch(tableCmd, ourCmd)
|
||||
|
||||
case modeTeamPicker:
|
||||
var tableCmd tea.Cmd
|
||||
m.teamPickerTable, tableCmd = m.teamPickerTable.Update(msg)
|
||||
m2, ourCmd := m.handleKey(msg)
|
||||
return m2, tea.Batch(tableCmd, ourCmd)
|
||||
|
||||
case modeUserCreate:
|
||||
var inputCmd tea.Cmd
|
||||
m.userFormInputs[m.userFormFocus], inputCmd = m.userFormInputs[m.userFormFocus].Update(msg)
|
||||
@@ -496,6 +503,8 @@ func (m Model) handleKey(msg tea.KeyMsg) (Model, tea.Cmd) {
|
||||
return m.handleConfirmKey(msg)
|
||||
case modeUserPicker:
|
||||
return m.handleUserPickerKey(msg)
|
||||
case modeTeamPicker:
|
||||
return m.handleTeamPickerKey(msg)
|
||||
case modeUserCreate:
|
||||
return m.handleUserCreateKey(msg)
|
||||
case modeUserNotifyEdit:
|
||||
@@ -566,7 +575,7 @@ func (m Model) handleDashboardKey(msg tea.KeyMsg) (Model, tea.Cmd) {
|
||||
if !m.connected || len(m.teams) == 0 {
|
||||
return m, nil
|
||||
}
|
||||
return m.switchTeam()
|
||||
return m.openTeamPicker()
|
||||
|
||||
case "enter":
|
||||
switch m.activeSection {
|
||||
@@ -847,22 +856,21 @@ func (m Model) openUserPicker(target pickerTarget) (Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// switchTeam steps the active team through all teams, then each of the caller's
|
||||
// teams in turn, and reloads what depends on it. Sections that are not on screen
|
||||
// are emptied rather than fetched, so they load when next opened; the incident
|
||||
// queue is the exception because it is what the caller returns to.
|
||||
func (m Model) switchTeam() (Model, tea.Cmd) {
|
||||
next := int64(0)
|
||||
if m.activeTeamID == 0 {
|
||||
next = m.teams[0].ID
|
||||
} else {
|
||||
for i, t := range m.teams {
|
||||
if t.ID == m.activeTeamID && i+1 < len(m.teams) {
|
||||
next = m.teams[i+1].ID
|
||||
}
|
||||
}
|
||||
}
|
||||
m.activeTeamID = next
|
||||
// openTeamPicker opens the full list of the caller's teams, plus "All teams",
|
||||
// for the "T" key to choose among rather than blindly cycling through them.
|
||||
// Team data is already loaded at connect time, so no fetch is needed.
|
||||
func (m Model) openTeamPicker() (Model, tea.Cmd) {
|
||||
m.mode = modeTeamPicker
|
||||
m.rebuildTeamPickerTable()
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// selectTeam sets the active team to teamID (0 meaning all teams) and reloads
|
||||
// what depends on it. Sections that are not on screen are emptied rather than
|
||||
// fetched, so they load when next opened; the incident queue is the exception
|
||||
// because it is what the caller returns to.
|
||||
func (m Model) selectTeam(teamID int64) (Model, tea.Cmd) {
|
||||
m.activeTeamID = teamID
|
||||
|
||||
m.incidents, m.alerts, m.archivedIncidents = nil, nil, nil
|
||||
m.scheduleEntries, m.scheduleDays, m.currentOnCall = nil, nil, nil
|
||||
@@ -1253,6 +1261,34 @@ func (m Model) handleUserPickerKey(msg tea.KeyMsg) (Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// ── Team picker ───────────────────────────────────────────────────────────
|
||||
|
||||
// handleTeamPickerKey reads the cursor's team off the table built by
|
||||
// rebuildTeamPickerTable, where row 0 is always "All teams" and row i (i>=1)
|
||||
// is m.teams[i-1].
|
||||
func (m Model) handleTeamPickerKey(msg tea.KeyMsg) (Model, tea.Cmd) {
|
||||
switch msg.String() {
|
||||
case "esc":
|
||||
m.mode = modeDashboard
|
||||
return m, nil
|
||||
|
||||
case "enter":
|
||||
cursor := m.teamPickerTable.Cursor()
|
||||
id := int64(0)
|
||||
if cursor > 0 {
|
||||
i := cursor - 1
|
||||
if i < 0 || i >= len(m.teams) {
|
||||
return m, nil
|
||||
}
|
||||
id = m.teams[i].ID
|
||||
}
|
||||
m, cmd := m.selectTeam(id)
|
||||
m.mode = modeDashboard
|
||||
return m, cmd
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// scheduleConflicts reports which of dates are already held by somebody other
|
||||
// than newUserID, and the distinct names holding them.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user