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:
+59
-19
@@ -630,7 +630,7 @@ func TestAlertDetail_JumpToIncident(t *testing.T) {
|
||||
|
||||
// A refresh underneath a prompt would move the ground under the user.
|
||||
func TestRefreshTick_SkipsModalStates(t *testing.T) {
|
||||
modal := []mode{modeNote, modeSnooze, modeConfirm, modeUserPicker, modeUserCreate}
|
||||
modal := []mode{modeNote, modeSnooze, modeConfirm, modeUserPicker, modeTeamPicker, modeUserCreate}
|
||||
for _, md := range modal {
|
||||
m := sized()
|
||||
m.mode = md
|
||||
@@ -782,32 +782,38 @@ func TestConnected_DefaultTeamFromConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwitchTeam_CyclesAllThenEachTeam(t *testing.T) {
|
||||
func TestTeamPicker_Opens(t *testing.T) {
|
||||
m := sized()
|
||||
m.teams = twoTeams()
|
||||
var seen []int64
|
||||
for i := 0; i < 4; i++ {
|
||||
var cmd tea.Cmd
|
||||
m, cmd = press(t, m, "T")
|
||||
if cmd == nil {
|
||||
t.Fatal("switching team should reload")
|
||||
}
|
||||
seen = append(seen, m.activeTeamID)
|
||||
m, cmd := press(t, m, "T")
|
||||
if m.mode != modeTeamPicker {
|
||||
t.Fatalf("T should open the team picker, got mode %v", m.mode)
|
||||
}
|
||||
want := []int64{1, 2, 0, 1}
|
||||
for i := range want {
|
||||
if seen[i] != want[i] {
|
||||
t.Fatalf("expected the cycle %v, got %v", want, seen)
|
||||
}
|
||||
if cmd != nil {
|
||||
t.Error("opening the picker should not itself trigger a reload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwitchTeam_ClearsRowsFromTheOtherTeam(t *testing.T) {
|
||||
// Row 0 of the picker table is always "All teams"; row i (i>=1) is
|
||||
// m.teams[i-1] — see rebuildTeamPickerTable.
|
||||
func TestTeamPicker_SelectTeamClearsRowsFromTheOtherTeam(t *testing.T) {
|
||||
m := sized()
|
||||
m.teams = twoTeams()
|
||||
m.incidents = []api.Incident{{ID: 1, Title: "old", TeamName: "Ops"}}
|
||||
m.rebuildIncidentTable()
|
||||
|
||||
m, _ = press(t, m, "T")
|
||||
m.teamPickerTable.SetCursor(1) // twoTeams()[0] is Ops
|
||||
m, cmd := press(t, m, "enter")
|
||||
if cmd == nil {
|
||||
t.Fatal("selecting a team should reload")
|
||||
}
|
||||
if m.mode != modeDashboard {
|
||||
t.Fatalf("enter should close the picker, got mode %v", m.mode)
|
||||
}
|
||||
if m.activeTeamID != 1 {
|
||||
t.Fatalf("expected team 1 (Ops) active, got %d", m.activeTeamID)
|
||||
}
|
||||
if len(m.incidents) != 0 {
|
||||
t.Errorf("the previous team's incidents must not linger, got %d", len(m.incidents))
|
||||
}
|
||||
@@ -816,10 +822,44 @@ func TestSwitchTeam_ClearsRowsFromTheOtherTeam(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwitchTeam_NoTeamsDoesNothing(t *testing.T) {
|
||||
func TestTeamPicker_SelectAllTeams(t *testing.T) {
|
||||
m := sized()
|
||||
m.teams = twoTeams()
|
||||
m.activeTeamID = 1
|
||||
|
||||
m, _ = press(t, m, "T")
|
||||
m.teamPickerTable.SetCursor(0) // "All teams"
|
||||
m, cmd := press(t, m, "enter")
|
||||
if cmd == nil {
|
||||
t.Fatal("selecting all teams should reload")
|
||||
}
|
||||
if m.activeTeamID != 0 {
|
||||
t.Fatalf("expected all teams (0), got %d", m.activeTeamID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTeamPicker_EscCancelsWithoutChangingTeam(t *testing.T) {
|
||||
m := sized()
|
||||
m.teams = twoTeams()
|
||||
m.activeTeamID = 1
|
||||
|
||||
m, _ = press(t, m, "T")
|
||||
m, cmd := press(t, m, "esc")
|
||||
if cmd != nil {
|
||||
t.Error("cancelling should not reload")
|
||||
}
|
||||
if m.mode != modeDashboard {
|
||||
t.Fatalf("esc should close the picker, got mode %v", m.mode)
|
||||
}
|
||||
if m.activeTeamID != 1 {
|
||||
t.Fatalf("cancelling must not change the active team, got %d", m.activeTeamID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTeamPicker_NoTeamsDoesNothing(t *testing.T) {
|
||||
m, cmd := press(t, sized(), "T")
|
||||
if cmd != nil || m.activeTeamID != 0 {
|
||||
t.Errorf("without teams T has nothing to switch to")
|
||||
if cmd != nil || m.mode == modeTeamPicker {
|
||||
t.Errorf("without teams T has nothing to open")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user