Rank log: inactive ranks (Guardian) count as promotions to and from, demotion when lost; Guardian is staff
This commit is contained in:
parent
611b79cdba
commit
0af93d1eab
7 changed files with 76 additions and 24 deletions
10
README.md
10
README.md
|
|
@ -79,13 +79,17 @@ environment).
|
|||
SimpleAdmin groups have no display name or colour, so those come from a site config
|
||||
(`SAW_SITE_CONFIG`, see `site.example.json`). The built-in defaults cover `#rank/owner`,
|
||||
`senioradmin`, `admin`, `trialadmin`, `mod`, `trialmod`, `helper` and `guardian`. Ranks marked
|
||||
`"supporter": true` are listed apart from staff and can't sign in unless they hold
|
||||
`@css/generic`.
|
||||
`"supporter": true` (VIPs) are listed apart from staff and don't count as staff online. Ranks
|
||||
marked `"inactive": true` (Guardian: staff who are stepping back) are listed with the staff; they
|
||||
only change how the rank log reads (see below). Nobody can sign in without `@css/generic`.
|
||||
|
||||
### Rank changes
|
||||
|
||||
Every change to a player's rank (their highest-immunity group) is recorded in `sa_rank_log` and
|
||||
listed under the public Staff page: who, from which rank to which, who changed it and when. The
|
||||
listed under the public Staff page: who, from which rank to which, who changed it and when. A
|
||||
change is a promotion or demotion by the ranks' immunity, except for inactive ranks: moving
|
||||
between an inactive rank and any other rank is a promotion either way, and losing an inactive rank
|
||||
is a demotion. The
|
||||
panel creates the table at startup (`sql/rank-log.sql`, embedded; run it by hand if the database
|
||||
user can't create tables). It logs changes made in the panel (giving, moving or removing a rank,
|
||||
and deleting a rank that people hold). Our SimpleAdmin fork (1.8.2b-zio10+) logs `css_addadmin`,
|
||||
|
|
|
|||
|
|
@ -214,6 +214,20 @@ type rankChangeView struct {
|
|||
New *rankView `json:"new,omitempty"`
|
||||
}
|
||||
|
||||
// inactiveKind overrides the stored kind (which compares immunity) for changes to or from an
|
||||
// inactive rank: moving between an inactive rank and any other rank is a promotion either way,
|
||||
// and losing an inactive rank altogether is a demotion.
|
||||
func inactiveKind(kind string, old, new *rankView) string {
|
||||
oldIn, newIn := old != nil && old.Inactive, new != nil && new.Inactive
|
||||
switch {
|
||||
case old != nil && new != nil && oldIn != newIn:
|
||||
return "promoted"
|
||||
case oldIn && new == nil:
|
||||
return "demoted"
|
||||
}
|
||||
return kind
|
||||
}
|
||||
|
||||
// publicRankChanges is the promotions and demotions list, with each rank's label and colour.
|
||||
func (s *Server) publicRankChanges(w http.ResponseWriter, r *http.Request) {
|
||||
lim, off, num := page(r)
|
||||
|
|
@ -232,11 +246,13 @@ func (s *Server) publicRankChanges(w http.ResponseWriter, r *http.Request) {
|
|||
return nil
|
||||
}
|
||||
rk := s.site.rank(g, x.groupIndex(g))
|
||||
return &rankView{Name: g, Label: rk.Label, Color: rk.Color, Supporter: rk.Supporter}
|
||||
return &rankView{Name: g, Label: rk.Label, Color: rk.Color, Supporter: rk.Supporter, Inactive: rk.Inactive}
|
||||
}
|
||||
out := make([]rankChangeView, 0, len(items))
|
||||
for _, c := range items {
|
||||
out = append(out, rankChangeView{RankChange: c, Old: view(c.OldRank), New: view(c.NewRank)})
|
||||
v := rankChangeView{RankChange: c, Old: view(c.OldRank), New: view(c.NewRank)}
|
||||
v.Kind = inactiveKind(v.Kind, v.Old, v.New)
|
||||
out = append(out, v)
|
||||
}
|
||||
writeJSON(w, http.StatusOK, newList(out, total, num))
|
||||
}
|
||||
|
|
|
|||
25
internal/web/public_test.go
Normal file
25
internal/web/public_test.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package web
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInactiveKind(t *testing.T) {
|
||||
guardian := &rankView{Name: "#rank/guardian", Inactive: true}
|
||||
mod := &rankView{Name: "#rank/mod"}
|
||||
owner := &rankView{Name: "#rank/owner"}
|
||||
for _, c := range []struct {
|
||||
kind string
|
||||
old, new *rankView
|
||||
want string
|
||||
}{
|
||||
{"demoted", owner, guardian, "promoted"},
|
||||
{"promoted", guardian, mod, "promoted"},
|
||||
{"removed", guardian, nil, "demoted"},
|
||||
{"added", nil, guardian, "added"},
|
||||
{"demoted", owner, mod, "demoted"},
|
||||
{"removed", mod, nil, "removed"},
|
||||
} {
|
||||
if got := inactiveKind(c.kind, c.old, c.new); got != c.want {
|
||||
t.Errorf("%v -> %v: got %s, want %s", c.old, c.new, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,20 +20,23 @@ type Rank struct {
|
|||
About string `json:"about"`
|
||||
// Supporter ranks (VIPs) are listed apart from staff and don't count as staff online.
|
||||
Supporter bool `json:"supporter"`
|
||||
// Inactive ranks are for staff who are stepping back. In the rank log, moving between an
|
||||
// inactive rank and any other rank is a promotion either way, and losing one is a demotion.
|
||||
Inactive bool `json:"inactive"`
|
||||
}
|
||||
|
||||
func defaultSite() Site {
|
||||
return Site{
|
||||
Title: "zio.sh",
|
||||
Ranks: map[string]Rank{
|
||||
"#rank/owner": {Label: "Owner", Color: "#fe113d", About: "Runs the server."},
|
||||
"#rank/senioradmin": {Label: "Senior admin", Color: "#ff7a45", About: "Manages the staff team and server settings."},
|
||||
"#rank/admin": {Label: "Admin", Color: "#f0a63a", About: "Handles appeals and longer bans."},
|
||||
"#rank/trialadmin": {Label: "Trial admin", Color: "#e8d25a", About: "Admins on trial."},
|
||||
"#rank/mod": {Label: "Moderator", Color: "#37c58f", About: "Keeps matches fair. Can kick, gag and issue short bans."},
|
||||
"#rank/trialmod": {Label: "Trial mod", Color: "#4fb3d9", About: "Moderators on trial."},
|
||||
"#rank/helper": {Label: "Helper", Color: "#7c8cf5", About: "Answers questions and handles chat."},
|
||||
"#rank/guardian": {Label: "Guardian", Color: "#c77dff", About: "Supporters of the server. Not staff, and can't punish anyone.", Supporter: true},
|
||||
"#rank/owner": {Label: "Owner", Color: "#fe113d", About: "Owns the server and looks after everything behind the scenes."},
|
||||
"#rank/senioradmin": {Label: "Senior Admin", Color: "#ff7a45", About: "Looks after the staff team and helps out wherever they're needed."},
|
||||
"#rank/admin": {Label: "Admin", Color: "#f0a63a", About: "Handles bans and appeals, and steps in when things get out of hand."},
|
||||
"#rank/trialadmin": {Label: "Trial Admin", Color: "#e8d25a", About: "New to the admin team and still finding their feet."},
|
||||
"#rank/mod": {Label: "Moderator", Color: "#37c58f", About: "Keeps an eye on games and deals with anyone ruining them."},
|
||||
"#rank/trialmod": {Label: "Trial Mod", Color: "#4fb3d9", About: "New to the mod team and learning how things work."},
|
||||
"#rank/helper": {Label: "Helper", Color: "#7c8cf5", About: "Happy to answer questions and help you find your way around."},
|
||||
"#rank/guardian": {Label: "Guardian", Color: "#c77dff", About: "Staff taking a break from being active, but still part of the team.", Inactive: true},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ type rankView struct {
|
|||
Label string `json:"label"`
|
||||
Color string `json:"color"`
|
||||
Supporter bool `json:"supporter,omitempty"`
|
||||
Inactive bool `json:"inactive,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Server) rankOf(x *staffIndex, steamid string) *rankView {
|
||||
|
|
@ -154,7 +155,7 @@ func (s *Server) rankOf(x *staffIndex, steamid string) *rankView {
|
|||
return &rankView{Label: "Staff", Color: "#8a91a0"}
|
||||
}
|
||||
r := s.site.rank(g, x.groupIndex(g))
|
||||
return &rankView{Name: g, Label: r.Label, Color: r.Color, Supporter: r.Supporter}
|
||||
return &rankView{Name: g, Label: r.Label, Color: r.Color, Supporter: r.Supporter, Inactive: r.Inactive}
|
||||
}
|
||||
|
||||
// isStaff is true for admins whose rank isn't a supporter rank.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"title": "zio.sh",
|
||||
"ranks": {
|
||||
"#rank/owner": { "label": "Owner", "color": "#fe113d", "about": "Runs the server." },
|
||||
"#rank/senioradmin": { "label": "Senior admin", "color": "#ff7a45", "about": "Manages the staff team and server settings." },
|
||||
"#rank/admin": { "label": "Admin", "color": "#f0a63a", "about": "Handles appeals and longer bans." },
|
||||
"#rank/trialadmin": { "label": "Trial admin", "color": "#e8d25a", "about": "Admins on trial." },
|
||||
"#rank/mod": { "label": "Moderator", "color": "#37c58f", "about": "Keeps matches fair. Can kick, gag and issue short bans." },
|
||||
"#rank/trialmod": { "label": "Trial mod", "color": "#4fb3d9", "about": "Moderators on trial." },
|
||||
"#rank/helper": { "label": "Helper", "color": "#7c8cf5", "about": "Answers questions and handles chat." },
|
||||
"#rank/guardian": { "label": "Guardian", "color": "#c77dff", "about": "Supporters of the server. Not staff, and can't punish anyone.", "supporter": true }
|
||||
"#rank/owner": { "label": "Owner", "color": "#fe113d", "about": "Owns the server and looks after everything behind the scenes." },
|
||||
"#rank/senioradmin": { "label": "Senior Admin", "color": "#ff7a45", "about": "Looks after the staff team and helps out wherever they're needed." },
|
||||
"#rank/admin": { "label": "Admin", "color": "#f0a63a", "about": "Handles bans and appeals, and steps in when things get out of hand." },
|
||||
"#rank/trialadmin": { "label": "Trial Admin", "color": "#e8d25a", "about": "New to the admin team and still finding their feet." },
|
||||
"#rank/mod": { "label": "Moderator", "color": "#37c58f", "about": "Keeps an eye on games and deals with anyone ruining them." },
|
||||
"#rank/trialmod": { "label": "Trial Mod", "color": "#4fb3d9", "about": "New to the mod team and learning how things work." },
|
||||
"#rank/helper": { "label": "Helper", "color": "#7c8cf5", "about": "Happy to answer questions and help you find your way around." },
|
||||
"#rank/guardian": { "label": "Guardian", "color": "#c77dff", "about": "Staff taking a break from being active, but still part of the team.", "inactive": true }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@
|
|||
-- and the in-game admin menu. Nothing writes it for ranks that lapse when an admin's `ends` passes.
|
||||
--
|
||||
-- kind is added, removed, promoted, demoted (compared by group immunity) or changed (same
|
||||
-- immunity). old_rank/new_rank are group names ("#rank/mod"), NULL for no rank. admin_steamid 0
|
||||
-- is Console. created is a wall-clock value in SimpleAdmin's Timezone, like its other tables.
|
||||
-- immunity). The panel overrides it when listing changes involving an inactive rank (one marked
|
||||
-- "inactive" in its site config, like Guardian): moving between an inactive rank and any other
|
||||
-- rank shows as promoted either way, and losing an inactive rank shows as demoted. old_rank/new_rank are group names ("#rank/mod"), NULL for no
|
||||
-- rank. admin_steamid 0 is Console. created is a wall-clock value in SimpleAdmin's Timezone, like
|
||||
-- its other tables.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sa_rank_log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue