mirror of
https://github.com/arcan1s/ffxivbis.git
synced 2025-04-25 09:47:18 +00:00
add some views
This commit is contained in:
parent
eea2f1b04b
commit
d5233361e5
@ -36,7 +36,7 @@ class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeou
|
|||||||
def modifyBiS: Route =
|
def modifyBiS: Route =
|
||||||
path("party" / Segment / "bis") { partyId: String =>
|
path("party" / Segment / "bis") { partyId: String =>
|
||||||
extractExecutionContext { implicit executionContext =>
|
extractExecutionContext { implicit executionContext =>
|
||||||
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
|
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
|
||||||
post {
|
post {
|
||||||
formFields("player".as[String], "piece".as[String].?, "is_tome".as[String].?, "link".as[String].?, "action".as[String]) {
|
formFields("player".as[String], "piece".as[String].?, "is_tome".as[String].?, "link".as[String].?, "action".as[String]) {
|
||||||
(player, maybePiece, maybeIsTome, maybeLink, action) =>
|
(player, maybePiece, maybeIsTome, maybeLink, action) =>
|
||||||
@ -77,7 +77,7 @@ class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeou
|
|||||||
object BiSView {
|
object BiSView {
|
||||||
import scalatags.Text.all._
|
import scalatags.Text.all._
|
||||||
|
|
||||||
def template(partyId: String, party: Seq[Player], pieces: Seq[String], error: Option[String]): String = {
|
def template(partyId: String, party: Seq[Player], pieces: Seq[String], error: Option[String]): String =
|
||||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||||
html(lang:="en",
|
html(lang:="en",
|
||||||
head(
|
head(
|
||||||
@ -86,7 +86,7 @@ object BiSView {
|
|||||||
),
|
),
|
||||||
|
|
||||||
body(
|
body(
|
||||||
h2("best in slot"),
|
h2("Best in slot"),
|
||||||
|
|
||||||
ErrorView.template(error),
|
ErrorView.template(error),
|
||||||
SearchLineView.template,
|
SearchLineView.template,
|
||||||
@ -110,13 +110,12 @@ object BiSView {
|
|||||||
input(name:="add", id:="add", `type`:="submit", value:="add")
|
input(name:="add", id:="add", `type`:="submit", value:="add")
|
||||||
),
|
),
|
||||||
|
|
||||||
table(
|
table(id:="result")(
|
||||||
tr(
|
tr(
|
||||||
th("player"),
|
th("player"),
|
||||||
th("piece"),
|
th("piece"),
|
||||||
th("is tome"),
|
th("is tome"),
|
||||||
th("")
|
th("")
|
||||||
//td(`class`:="include_search")
|
|
||||||
),
|
),
|
||||||
for (player <- party; piece <- player.bis.pieces) yield tr(
|
for (player <- party; piece <- player.bis.pieces) yield tr(
|
||||||
td(`class`:="include_search")(player.playerId.toString),
|
td(`class`:="include_search")(player.playerId.toString),
|
||||||
@ -138,5 +137,4 @@ object BiSView {
|
|||||||
script(src:="/static/table_search.js", `type`:="text/javascript")
|
script(src:="/static/table_search.js", `type`:="text/javascript")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
126
src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala
Normal file
126
src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package me.arcanis.ffxivbis.http.view
|
||||||
|
|
||||||
|
import akka.actor.ActorRef
|
||||||
|
import akka.http.scaladsl.model.StatusCodes
|
||||||
|
import akka.http.scaladsl.server.Directives._
|
||||||
|
import akka.http.scaladsl.server.Route
|
||||||
|
import akka.util.Timeout
|
||||||
|
import me.arcanis.ffxivbis.http.{Authorization, LootHelper}
|
||||||
|
import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId}
|
||||||
|
|
||||||
|
import scala.concurrent.{ExecutionContext, Future}
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
|
class LootView (override val storage: ActorRef)(implicit timeout: Timeout)
|
||||||
|
extends LootHelper(storage) with Authorization {
|
||||||
|
|
||||||
|
def route: Route = getLoot ~ modifyLoot
|
||||||
|
|
||||||
|
def getLoot: Route =
|
||||||
|
path("party" / Segment / "loot") { partyId: String =>
|
||||||
|
extractExecutionContext { implicit executionContext =>
|
||||||
|
authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
|
||||||
|
get {
|
||||||
|
complete {
|
||||||
|
loot(partyId, None).map { players =>
|
||||||
|
LootView.template(partyId, players, Piece.available, None)
|
||||||
|
}.map { text =>
|
||||||
|
(StatusCodes.OK, RootView.toHtml(text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def modifyLoot: Route =
|
||||||
|
path("party" / Segment / "loot") { partyId: String =>
|
||||||
|
extractExecutionContext { implicit executionContext =>
|
||||||
|
authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
|
||||||
|
post {
|
||||||
|
formFields("player".as[String], "piece".as[String], "is_tome".as[String].?, "action".as[String]) {
|
||||||
|
(player, maybePiece, maybeIsTome, action) =>
|
||||||
|
onComplete(modifyLootCall(partyId, player, maybePiece, maybeIsTome, action)) {
|
||||||
|
case _ => redirect(s"/party/$partyId/loot", StatusCodes.Found)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def modifyLootCall(partyId: String, player: String,
|
||||||
|
maybePiece: String, maybeIsTome: Option[String],
|
||||||
|
action: String)
|
||||||
|
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
|
||||||
|
def getPiece(playerId: PlayerId) =
|
||||||
|
Try(Piece(maybePiece, maybeIsTome.isDefined, playerId.job)).toOption
|
||||||
|
|
||||||
|
PlayerId(partyId, player) match {
|
||||||
|
case Some(playerId) => (getPiece(playerId), action) match {
|
||||||
|
case (Some(piece), "add") => addPieceLoot(playerId, piece).map(_ => ())
|
||||||
|
case (Some(piece), "remove") => removePieceLoot(playerId, piece).map(_ => ())
|
||||||
|
case _ => Future.failed(new Error(s"Could not construct piece from `$maybePiece`"))
|
||||||
|
}
|
||||||
|
case _ => Future.failed(new Error(s"Could not construct player id from `$player`"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object LootView {
|
||||||
|
import scalatags.Text.all._
|
||||||
|
|
||||||
|
def template(partyId: String, party: Seq[Player], pieces: Seq[String], error: Option[String]): String =
|
||||||
|
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||||
|
html(lang:="en",
|
||||||
|
head(
|
||||||
|
title:="Loot",
|
||||||
|
link(rel:="stylesheet", `type`:="text/css", href:="/static/styles.css")
|
||||||
|
),
|
||||||
|
|
||||||
|
body(
|
||||||
|
h2("Loot"),
|
||||||
|
|
||||||
|
ErrorView.template(error),
|
||||||
|
SearchLineView.template,
|
||||||
|
|
||||||
|
form(action:=s"/party/$partyId/loot", method:="post")(
|
||||||
|
select(name:="player", id:="player", title:="player")
|
||||||
|
(for (player <- party) yield option(player.playerId.toString)),
|
||||||
|
select(name:="piece", id:="piece", title:="piece")
|
||||||
|
(for (piece <- pieces) yield option(piece)),
|
||||||
|
input(name:="is_tome", id:="is_tome", title:="is tome", `type`:="checkbox"),
|
||||||
|
label(`for`:="is_tome")("is tome gear"),
|
||||||
|
input(name:="action", id:="action", `type`:="hidden", value:="add"),
|
||||||
|
input(name:="add", id:="add", `type`:="submit", value:="add")
|
||||||
|
),
|
||||||
|
|
||||||
|
table(id:="result")(
|
||||||
|
tr(
|
||||||
|
th("player"),
|
||||||
|
th("piece"),
|
||||||
|
th("is tome"),
|
||||||
|
th("")
|
||||||
|
),
|
||||||
|
for (player <- party; piece <- player.bis.pieces) yield tr(
|
||||||
|
td(`class`:="include_search")(player.playerId.toString),
|
||||||
|
td(`class`:="include_search")(piece.piece),
|
||||||
|
td(piece.isTomeToString),
|
||||||
|
td(
|
||||||
|
form(action:=s"/party/$partyId/loot", method:="post")(
|
||||||
|
input(name:="player", id:="player", `type`:="hidden", value:=player.playerId.toString),
|
||||||
|
input(name:="piece", id:="piece", `type`:="hidden", value:=piece.piece),
|
||||||
|
input(name:="is_tome", id:="is_tome", `type`:="hidden", value:=piece.isTomeToString),
|
||||||
|
input(name:="action", id:="action", `type`:="hidden", value:="remove"),
|
||||||
|
input(name:="remove", id:="remove", `type`:="submit", value:="x")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
ExportToCSVView.template,
|
||||||
|
script(src:="/static/table_search.js", `type`:="text/javascript")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
@ -9,9 +9,11 @@ import akka.util.Timeout
|
|||||||
class RootView(storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) {
|
class RootView(storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) {
|
||||||
|
|
||||||
private val biSView = new BiSView(storage, ariyala)
|
private val biSView = new BiSView(storage, ariyala)
|
||||||
|
private val lootView = new LootView(storage)
|
||||||
|
private val userView = new UserView(storage)
|
||||||
|
|
||||||
def route: Route =
|
def route: Route =
|
||||||
biSView.route
|
biSView.route ~ lootView.route ~ userView.route
|
||||||
}
|
}
|
||||||
|
|
||||||
object RootView {
|
object RootView {
|
||||||
|
118
src/main/scala/me/arcanis/ffxivbis/http/view/UserView.scala
Normal file
118
src/main/scala/me/arcanis/ffxivbis/http/view/UserView.scala
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package me.arcanis.ffxivbis.http.view
|
||||||
|
|
||||||
|
import akka.actor.ActorRef
|
||||||
|
import akka.http.scaladsl.model.StatusCodes
|
||||||
|
import akka.http.scaladsl.server.Directives._
|
||||||
|
import akka.http.scaladsl.server.Route
|
||||||
|
import akka.util.Timeout
|
||||||
|
import me.arcanis.ffxivbis.http.{Authorization, UserHelper}
|
||||||
|
import me.arcanis.ffxivbis.models.{Permission, User}
|
||||||
|
|
||||||
|
import scala.concurrent.{ExecutionContext, Future}
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
|
class UserView(override val storage: ActorRef)(implicit timeout: Timeout)
|
||||||
|
extends UserHelper(storage) with Authorization {
|
||||||
|
|
||||||
|
def route: Route = getUsers
|
||||||
|
|
||||||
|
def getUsers: Route =
|
||||||
|
path("party" / Segment / "users") { partyId: String =>
|
||||||
|
extractExecutionContext { implicit executionContext =>
|
||||||
|
authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ =>
|
||||||
|
get {
|
||||||
|
complete {
|
||||||
|
users(partyId).map { users =>
|
||||||
|
UserView.template(partyId, users, None)
|
||||||
|
}.map { text =>
|
||||||
|
(StatusCodes.OK, RootView.toHtml(text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def modifyUsers: Route =
|
||||||
|
path("party" / Segment / "users") { partyId: String =>
|
||||||
|
extractExecutionContext { implicit executionContext =>
|
||||||
|
authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ =>
|
||||||
|
post {
|
||||||
|
formFields("username".as[String], "password".as[String].?, "permission".as[String].?, "action".as[String]) {
|
||||||
|
(username, maybePassword, maybePermission, action) =>
|
||||||
|
onComplete(modifyUsersCall(partyId, username, maybePassword, maybePermission, action)) {
|
||||||
|
case _ => redirect(s"/party/$partyId/users", StatusCodes.Found)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def modifyUsersCall(partyId: String, username: String,
|
||||||
|
maybePassword: Option[String], maybePermission: Option[String],
|
||||||
|
action: String)
|
||||||
|
(implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
|
||||||
|
def permission: Option[Permission.Value] =
|
||||||
|
maybePermission.flatMap(p => Try(Permission.withName(p)).toOption)
|
||||||
|
|
||||||
|
action match {
|
||||||
|
case "add" => (maybePassword, permission) match {
|
||||||
|
case (Some(password), Some(permission)) => addUser(User(partyId, username, password, permission), isHashedPassword = false).map(_ => ())
|
||||||
|
case _ => Future.failed(new Error(s"Could not construct permission/password from `$maybePermission`/`$maybePassword`"))
|
||||||
|
}
|
||||||
|
case "remove" => removeUser(partyId, username).map(_ => ())
|
||||||
|
case _ => Future.failed(new Error(s"Could not perform $action"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object UserView {
|
||||||
|
import scalatags.Text.all._
|
||||||
|
|
||||||
|
def template(partyId: String, users: Seq[User], error: Option[String]) =
|
||||||
|
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
|
||||||
|
html(lang:="en",
|
||||||
|
head(
|
||||||
|
title:="Users",
|
||||||
|
link(rel:="stylesheet", `type`:="text/css", href:="/static/styles.css")
|
||||||
|
),
|
||||||
|
|
||||||
|
body(
|
||||||
|
h2("Users"),
|
||||||
|
|
||||||
|
ErrorView.template(error),
|
||||||
|
SearchLineView.template,
|
||||||
|
|
||||||
|
form(action:=s"/party/$partyId/users", method:="post")(
|
||||||
|
input(name:="username", id:="username", title:="username", placeholder:="username", `type`:="text"),
|
||||||
|
input(name:="password", id:="password", title:="password", placeholder:="password", `type`:="password"),
|
||||||
|
select(name:="permission", id:="permission", title:="permission")(option("get"), option("post")),
|
||||||
|
input(name:="action", id:="action", `type`:="hidden", value:="add"),
|
||||||
|
input(name:="add", id:="add", `type`:="submit", value:="add")
|
||||||
|
),
|
||||||
|
|
||||||
|
table(id:="result")(
|
||||||
|
tr(
|
||||||
|
th("username"),
|
||||||
|
th("permission"),
|
||||||
|
th("")
|
||||||
|
),
|
||||||
|
for (user <- users) yield tr(
|
||||||
|
td(`class`:="include_search")(user.username),
|
||||||
|
td(user.permission.toString),
|
||||||
|
td(
|
||||||
|
form(action:=s"/party/$partyId/users", method:="post")(
|
||||||
|
input(name:="username", id:="username", `type`:="hidden", value:=user.username.toString),
|
||||||
|
input(name:="action", id:="action", `type`:="hidden", value:="remove"),
|
||||||
|
input(name:="remove", id:="remove", `type`:="submit", value:="x")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
ExportToCSVView.template,
|
||||||
|
script(src:="/static/table_search.js", `type`:="text/javascript")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user