mods list
parent
f7a81574c2
commit
de6ba687cd
|
@ -208,6 +208,10 @@ final class Mod(
|
|||
modLogApi.recent map { html.mod.log(_) }
|
||||
}
|
||||
|
||||
def table = Secure(_.ModLog) { implicit ctx => _ =>
|
||||
modApi.allMods map { html.mod.table(_) }
|
||||
}
|
||||
|
||||
private def communications(username: String, priv: Boolean) =
|
||||
Secure { perms =>
|
||||
if (priv) perms.ViewPrivateComms else perms.Shadowban
|
||||
|
|
|
@ -34,6 +34,8 @@ object menu {
|
|||
"Chat Panic: ",
|
||||
strong(if (isChatPanicEnabled) "ON" else "OFF")
|
||||
),
|
||||
isGranted(_.Admin) option
|
||||
a(cls := active.active("mods"), href := routes.Mod.table)("Mods"),
|
||||
isGranted(_.Settings) option
|
||||
a(cls := active.active("setting"), href := routes.Dev.settings)("Settings"),
|
||||
isGranted(_.Cli) option
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package views.html.mod
|
||||
|
||||
import controllers.routes
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
|
||||
object table {
|
||||
|
||||
private val dataSort = attr("data-sort")
|
||||
|
||||
def apply(users: List[lila.user.User])(implicit ctx: Context) = {
|
||||
|
||||
val title = "All mods"
|
||||
|
||||
views.html.base.layout(
|
||||
title = title,
|
||||
moreCss = cssTag("mod.misc")
|
||||
) {
|
||||
main(cls := "page-menu")(
|
||||
views.html.mod.menu("mods"),
|
||||
div(id := "mod_table", cls := "page-menu__content box")(
|
||||
h1(title),
|
||||
st.table(cls := "slist slist-pad sortable")(
|
||||
thead(
|
||||
tr(
|
||||
th("Mod"),
|
||||
th("Permissions"),
|
||||
th("Last seen at")
|
||||
)
|
||||
),
|
||||
tbody(
|
||||
users.map { user =>
|
||||
tr(
|
||||
td(userLink(user)),
|
||||
td(a(href := routes.Mod.permissions(user.username))(
|
||||
lila.security.Permission(user.roles).map(_.name) mkString ", "
|
||||
)),
|
||||
td(dataSort := user.seenAt.map(_.getMillis.toString))(user.seenAt.map(momentFromNowOnce)),
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -378,6 +378,7 @@ POST /mod/:username/rankban/:v controllers.Mod.rankban(username: String,
|
|||
POST /mod/:username/reportban/:v controllers.Mod.reportban(username: String, v: Boolean)
|
||||
POST /mod/:username/impersonate controllers.Mod.impersonate(username: String)
|
||||
GET /mod/log controllers.Mod.log
|
||||
GET /mod/table controllers.Mod.table
|
||||
POST /mod/:username/refreshUserAssess controllers.Mod.refreshUserAssess(username: String)
|
||||
POST /mod/:username/email controllers.Mod.setEmail(username: String)
|
||||
POST /mod/:username/notify-slack controllers.Mod.notifySlack(username: String)
|
||||
|
|
|
@ -170,6 +170,12 @@ final class ModApi(
|
|||
userRepo.setRankban(sus.user.id, v) >>- logApi.rankban(mod, sus, v)
|
||||
}
|
||||
|
||||
def allMods =
|
||||
userRepo.userIdsWithRoles(Permission.modPermissions.view.map(_.dbKey).toList) flatMap
|
||||
userRepo.enabledByIds dmap {
|
||||
_.sortBy(_.timeNoSee)
|
||||
}
|
||||
|
||||
private def withUser[A](username: String)(op: User => Fu[A]): Fu[A] =
|
||||
userRepo named username orFail s"[mod] missing user $username" flatMap op
|
||||
}
|
||||
|
|
|
@ -214,9 +214,13 @@ object Permission {
|
|||
)
|
||||
)
|
||||
|
||||
lazy val all: List[Permission] = categorized.flatMap {
|
||||
private lazy val all: Set[Permission] = categorized.flatMap {
|
||||
case (_, perms) => perms
|
||||
}
|
||||
}.toSet
|
||||
|
||||
private lazy val nonModPermissions: Set[Permission] = Set(Beta, Prismic, Coach, Teacher, Developer, Verified)
|
||||
|
||||
lazy val modPermissions: Set[Permission] = all diff nonModPermissions
|
||||
|
||||
lazy val allByDbKey: Map[String, Permission] = all.view map { p =>
|
||||
(p.dbKey, p)
|
||||
|
|
|
@ -67,9 +67,7 @@ case class User(
|
|||
|
||||
lazy val seenRecently: Boolean = timeNoSee < User.seenRecently
|
||||
|
||||
def timeNoSee: Duration = seenAt.fold[Duration](Duration.Inf) { s =>
|
||||
(nowMillis - s.getMillis).millis
|
||||
}
|
||||
def timeNoSee: Duration = (nowMillis - (seenAt | createdAt).getMillis).millis
|
||||
|
||||
def everLoggedIn = seenAt.??(createdAt !=)
|
||||
|
||||
|
|
|
@ -50,3 +50,7 @@
|
|||
margin: 0 .5em;
|
||||
}
|
||||
}
|
||||
|
||||
.slist thead {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -83,13 +83,8 @@ $(function() {
|
|||
};
|
||||
|
||||
tablesort.extend('number', function(item) {
|
||||
return item.match(/^[-+]?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // Prefixed currency
|
||||
item.match(/^[-+]?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // Suffixed currency
|
||||
item.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
|
||||
return item.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
|
||||
}, function(a, b) {
|
||||
a = cleanNumber(a);
|
||||
b = cleanNumber(b);
|
||||
|
||||
return compareNumber(b, a);
|
||||
return compareNumber(cleanNumber(b), cleanNumber(a));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -100,14 +100,9 @@ function userMod($zone) {
|
|||
};
|
||||
|
||||
tablesort.extend('number', function(item) {
|
||||
return item.match(/^-?[£\x24Û¢´€]?\d+\s*([,.]\d{0,2})/) || // Prefixed currency
|
||||
item.match(/^-?\d+\s*([,.]\d{0,2})?[£\x24Û¢´€]/) || // Suffixed currency
|
||||
item.match(/^-?(\d)*-?([,.]){0,1}-?(\d)+([E,e][-+][\d]+)?%?$/); // Number
|
||||
return item.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
|
||||
}, function(a, b) {
|
||||
a = cleanNumber(a);
|
||||
b = cleanNumber(b);
|
||||
|
||||
return compareNumber(b, a);
|
||||
return compareNumber(cleanNumber(b), cleanNumber(a));
|
||||
});
|
||||
}());
|
||||
|
||||
|
|
Loading…
Reference in New Issue