diff --git a/bemani/data/mysql/user.py b/bemani/data/mysql/user.py index 6d82916..b4af3fc 100644 --- a/bemani/data/mysql/user.py +++ b/bemani/data/mysql/user.py @@ -330,7 +330,7 @@ class UserData(BaseData): Returns: A list of User objects representing all users. """ - sql = "SELECT id, username, email, admin FROM user" + sql = "SELECT id, username, email, admin, (SELECT COUNT(id) FROM card WHERE card.userid = user.id) AS linked_cards FROM user" cursor = self.execute(sql) return [ User( @@ -338,6 +338,7 @@ class UserData(BaseData): result["username"], result["email"], result["admin"] == 1, + result["linked_cards"], ) for result in cursor.mappings() ] diff --git a/bemani/data/types.py b/bemani/data/types.py index 821eb83..83f3e86 100644 --- a/bemani/data/types.py +++ b/bemani/data/types.py @@ -15,7 +15,14 @@ class User: more cards, or swap out a card for a new one. """ - def __init__(self, userid: UserID, username: Optional[str], email: Optional[str], admin: bool) -> None: + def __init__( + self, + userid: UserID, + username: Optional[str], + email: Optional[str], + admin: bool, + linked_cards: Optional[int] = None, + ) -> None: """ Initialize the user object. @@ -25,14 +32,17 @@ class User: the web UI. email - An optional string, set if the user has claimed their account on the web UI. + admin - Whether this user is an admin or not. + linked_cards - The count of cards linked to this account. Not always provided. """ self.id = userid self.username = username self.email = email self.admin = admin + self.linked_cards = linked_cards def __repr__(self) -> str: - return f"User(userid={self.id}, username={self.username}, email={self.email}, admin={self.admin})" + return f"User(userid={self.id}, username={self.username}, email={self.email}, admin={self.admin}, linked_cards={self.linked_cards})" class Achievement: diff --git a/bemani/frontend/admin/admin.py b/bemani/frontend/admin/admin.py index 6d947d0..3b7f123 100644 --- a/bemani/frontend/admin/admin.py +++ b/bemani/frontend/admin/admin.py @@ -99,6 +99,7 @@ def format_user(user: User) -> Dict[str, Any]: "username": user.username, "email": user.email, "admin": user.admin, + "linked_cards": user.linked_cards, } diff --git a/bemani/frontend/static/controllers/admin/cards.react.js b/bemani/frontend/static/controllers/admin/cards.react.js index 16d0ae4..b836104 100644 --- a/bemani/frontend/static/controllers/admin/cards.react.js +++ b/bemani/frontend/static/controllers/admin/cards.react.js @@ -39,7 +39,10 @@ var card_management = createReactClass({ animation: 'none', closeAnimation: 'none', title: 'Delete Card', - content: 'Are you sure you want to delete this card?', + content: ( + 'Are you sure you want to delete this card? Doing so will remove the card from the ' + + 'user account but will not delete the account itself.' + ), buttons: { Delete: { btnClass: 'delete', @@ -93,12 +96,12 @@ var card_management = createReactClass({ return ( <> - + ); }, diff --git a/bemani/frontend/static/controllers/admin/users.react.js b/bemani/frontend/static/controllers/admin/users.react.js index 1b5f5dc..9340c0d 100644 --- a/bemani/frontend/static/controllers/admin/users.react.js +++ b/bemani/frontend/static/controllers/admin/users.react.js @@ -41,8 +41,8 @@ var card_management = createReactClass({ }, sortUsername: function(a, b) { - var au = a.username ? a.username : ''; - var bu = b.username ? b.username : ''; + var au = a.username ? a.username : '\u10FFFF'; + var bu = b.username ? b.username : '\u10FFFF'; return au.localeCompare(bu); }, @@ -53,11 +53,23 @@ var card_management = createReactClass({ }, sortEmail: function(a, b) { - var ae = a.email ? a.email : ''; - var be = b.email ? b.email : ''; + var ae = a.email ? a.email : '\u10FFFF'; + var be = b.email ? b.email : '\u10FFFF'; return ae.localeCompare(be); }, + renderLinkedCards: function(user) { + return user.linked_cards ? + {user.linked_cards} : + none; + }, + + sortLinkedCards: function(a, b) { + var ac = a.linked_cards ? a.linked_cards : 0; + var bc = b.linked_cards ? b.linked_cards : 0; + return ac - bc; + }, + renderEditButton: function(user) { return (