multiple autocomplete for kicking team members
parent
bafe8a99b7
commit
7d84de4095
|
@ -144,11 +144,9 @@ final class Team(
|
|||
}
|
||||
|
||||
def kickForm(id: String) =
|
||||
Auth { implicit ctx => me =>
|
||||
Auth { implicit ctx => _ =>
|
||||
WithOwnedTeamEnabled(id) { team =>
|
||||
env.team.memberRepo userIdsByTeam team.id map { userIds =>
|
||||
html.team.admin.kick(team, userIds.filter(me.id !=))
|
||||
}
|
||||
Ok(html.team.admin.kick(team, forms.members)).fuccess
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,8 +154,8 @@ final class Team(
|
|||
AuthBody { implicit ctx => me =>
|
||||
WithOwnedTeamEnabled(id) { team =>
|
||||
implicit val req = ctx.body
|
||||
forms.selectMember.bindFromRequest().value ?? { api.kick(team, _, me) } inject Redirect(
|
||||
routes.Team.kickForm(team.id)
|
||||
forms.members.bindFromRequest().value ?? { api.kickMembers(team, _, me).sequenceFu } inject Redirect(
|
||||
routes.Team.show(team.id)
|
||||
).flashSuccess
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@ object admin {
|
|||
views.html.base.layout(
|
||||
title = title,
|
||||
moreCss = frag(cssTag("team"), cssTag("tagify")),
|
||||
moreJs = jsModule("team.admin")
|
||||
moreJs = frag(
|
||||
jsModule("team.admin"),
|
||||
embedJsUnsafeLoadThen("""teamAdmin.initTagify('form3-leaders')""")
|
||||
)
|
||||
) {
|
||||
main(cls := "page-menu page-small")(
|
||||
bits.menu(none),
|
||||
|
@ -39,24 +42,30 @@ object admin {
|
|||
}
|
||||
}
|
||||
|
||||
def kick(t: lila.team.Team, userIds: Iterable[lila.user.User.ID])(implicit ctx: Context) = {
|
||||
def kick(t: lila.team.Team, form: Form[_])(implicit ctx: Context) = {
|
||||
|
||||
val title = s"${t.name} • ${kickSomeone.txt()}"
|
||||
|
||||
bits.layout(title = title) {
|
||||
views.html.base.layout(
|
||||
title = title,
|
||||
moreCss = frag(cssTag("team"), cssTag("tagify")),
|
||||
moreJs = frag(
|
||||
jsModule("team.admin"),
|
||||
embedJsUnsafeLoadThen("""teamAdmin.initTagify('form3-members')""")
|
||||
)
|
||||
) {
|
||||
main(cls := "page-menu page-small")(
|
||||
bits.menu(none),
|
||||
div(cls := "page-menu__content box box-pad")(
|
||||
h1(title),
|
||||
p(whoToKick()),
|
||||
br,
|
||||
br,
|
||||
postForm(cls := "kick", action := routes.Team.kick(t.id))(
|
||||
userIds.toList.sorted.map { userId =>
|
||||
button(name := "userId", cls := "button button-empty button-no-upper confirm", value := userId)(
|
||||
usernameOrId(userId)
|
||||
)
|
||||
}
|
||||
postForm(action := routes.Team.kick(t.id))(
|
||||
form3.group(form("members"), frag(whoToKick()))(
|
||||
form3.textarea(_)(rows := 2)
|
||||
),
|
||||
form3.actions(
|
||||
a(href := routes.Team.show(t.id))(trans.cancel()),
|
||||
form3.submit(trans.save())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -232,22 +232,27 @@ final class TeamApi(
|
|||
} >>-
|
||||
Bus.publish(KickFromTeam(teamId = team.id, userId = userId), "teamKick")
|
||||
|
||||
def kickMembers(team: Team, json: String, me: User) =
|
||||
parseTagifyInput(json) map (kick(team, _, me))
|
||||
|
||||
private case class TagifyUser(value: String)
|
||||
implicit private val TagifyUserReads = Json.reads[TagifyUser]
|
||||
|
||||
def setLeaders(team: Team, json: String, by: User, byMod: Boolean): Funit = {
|
||||
val leaders: Set[User.ID] = Try {
|
||||
json.trim.nonEmpty ?? {
|
||||
Json.parse(json).validate[List[TagifyUser]] match {
|
||||
case JsSuccess(users, _) =>
|
||||
users
|
||||
.map(_.value.toLowerCase.trim)
|
||||
.filter(User.lichessId !=)
|
||||
.toSet take 30
|
||||
case _ => Set.empty[User.ID]
|
||||
}
|
||||
private def parseTagifyInput(json: String) = Try {
|
||||
json.trim.nonEmpty ?? {
|
||||
Json.parse(json).validate[List[TagifyUser]] match {
|
||||
case JsSuccess(users, _) =>
|
||||
users
|
||||
.map(_.value.toLowerCase.trim)
|
||||
.filter(User.lichessId !=)
|
||||
.toSet
|
||||
case _ => Set.empty[User.ID]
|
||||
}
|
||||
} getOrElse Set.empty
|
||||
}
|
||||
} getOrElse Set.empty
|
||||
|
||||
def setLeaders(team: Team, json: String, by: User, byMod: Boolean): Funit = {
|
||||
val leaders: Set[User.ID] = parseTagifyInput(json) take 30
|
||||
for {
|
||||
ids <- memberRepo.filterUserIdsInTeam(team.id, leaders)
|
||||
previousValidLeaders <- memberRepo.filterUserIdsInTeam(team.id, team.leaders)
|
||||
|
|
|
@ -117,6 +117,10 @@ final private[team] class TeamForm(
|
|||
.map(_.name)
|
||||
.mkString(", ")
|
||||
|
||||
def members = Form(
|
||||
single("members" -> nonEmptyText)
|
||||
)
|
||||
|
||||
private def teamExists(setup: TeamSetup) =
|
||||
teamRepo.coll.exists($id(Team nameToId setup.trim.name))
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ export default rollupProject({
|
|||
teamAdmin: {
|
||||
input: 'src/teamAdmin.ts',
|
||||
output: 'team.admin',
|
||||
name: 'teamAdmin',
|
||||
},
|
||||
appeal: {
|
||||
input: 'src/appeal.ts',
|
||||
|
|
|
@ -2,8 +2,8 @@ import Tagify from '@yaireo/tagify';
|
|||
import debounce from 'debounce-promise';
|
||||
import * as xhr from 'common/xhr';
|
||||
|
||||
lichess.load.then(() => {
|
||||
const input = document.getElementById('form3-leaders') as HTMLInputElement;
|
||||
export function initTagify(id: string) {
|
||||
const input = document.getElementById(id) as HTMLInputElement;
|
||||
|
||||
const tagify = new Tagify(input, {
|
||||
pattern: /.{3,}/,
|
||||
|
@ -26,4 +26,4 @@ lichess.load.then(() => {
|
|||
tagify.loading(false).dropdown.show.call(tagify, term); // render the suggestions dropdown
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue