feat: reassign on-call days and weeks to another person
Release / test (push) Failing after 4s
Release / build (amd64, darwin) (push) Has been skipped
Release / build (amd64, linux) (push) Has been skipped
Release / build (arm64, darwin) (push) Has been skipped
Release / build (arm64, linux) (push) Has been skipped
Release / release (push) Has been skipped
Release / test (push) Failing after 4s
Release / build (amd64, darwin) (push) Has been skipped
Release / build (amd64, linux) (push) Has been skipped
Release / build (arm64, darwin) (push) Has been skipped
Release / build (arm64, linux) (push) Has been skipped
Release / release (push) Has been skipped
Assigning over a day somebody else held did nothing but flash a 409 for three seconds. The server holds one person per date and refused any that was taken, all-or-nothing, so pressing W on a week where a single day was already assigned placed none of the other six either. The only way through was d on each day first — seven delete-and-confirm cycles to move one week. The clash is already on screen, so it is found before the request rather than read back out of an error: the picker hands off to a confirmation naming who loses the days and how many there are, and accepting sends the whole selection with replace, which terdut-server v0.8.0 added. One question to move a week, and nobody's shift moves without somebody being asked. A day nobody holds still assigns with no prompt at all. Reassigning somebody to a day they already hold raises no prompt, since it takes nothing from anyone, but it does send replace: the server rejects any date that exists, so without it a harmless no-op would fail.
This commit is contained in:
@@ -178,10 +178,44 @@ func (m Model) confirmPrompt() string {
|
||||
return "Delete schedule entry? [y/N]"
|
||||
case confirmDeleteUser:
|
||||
return fmt.Sprintf("Delete user %s (cascades all API keys)? [y/N]", m.selectedUser.Username)
|
||||
case confirmReassignSchedule:
|
||||
if p := m.pendingAssign; p != nil {
|
||||
return fmt.Sprintf("%s assigned to %s. Reassign to %s? [y/N]",
|
||||
dayCount(len(p.taken), len(p.dates)), joinNames(p.holders), p.username)
|
||||
}
|
||||
return "Reassign these days? [y/N]"
|
||||
}
|
||||
return "Are you sure? [y/N]"
|
||||
}
|
||||
|
||||
// dayCount phrases how much of an assignment is being taken from somebody. A
|
||||
// single day says so plainly; a partial week says which part, because "3 of 7"
|
||||
// is the difference between taking a shift and taking somebody's whole week.
|
||||
func dayCount(taken, total int) string {
|
||||
switch {
|
||||
case total == 1:
|
||||
return "This day is"
|
||||
case taken == total:
|
||||
return fmt.Sprintf("All %d days are", total)
|
||||
default:
|
||||
return fmt.Sprintf("%d of %d days are", taken, total)
|
||||
}
|
||||
}
|
||||
|
||||
// joinNames renders a list of people as prose.
|
||||
func joinNames(names []string) string {
|
||||
switch len(names) {
|
||||
case 0:
|
||||
return "somebody else"
|
||||
case 1:
|
||||
return names[0]
|
||||
case 2:
|
||||
return names[0] + " and " + names[1]
|
||||
default:
|
||||
return strings.Join(names[:len(names)-1], ", ") + " and " + names[len(names)-1]
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dashboard ──────────────────────────────────────────────────────────────
|
||||
|
||||
func (m Model) renderDashboard() string {
|
||||
|
||||
Reference in New Issue
Block a user