From 9d0a65a516e32f9aceaf0f9584348e87b2871817 Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Fri, 7 Feb 2020 01:42:39 +0100 Subject: [PATCH] Add tooltips to users, add CSS --- allianceauth/authentication/admin.py | 66 +++++++++++++++---- .../static/authentication/css/admin.css | 23 +++++++ .../services/modules/discord/admin.py | 4 +- .../discord/static/services/discord/admin.css | 2 +- 4 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 allianceauth/authentication/static/authentication/css/admin.css diff --git a/allianceauth/authentication/admin.py b/allianceauth/authentication/admin.py index df8c71be..34231ca8 100644 --- a/allianceauth/authentication/admin.py +++ b/allianceauth/authentication/admin.py @@ -18,6 +18,7 @@ from allianceauth.authentication.models import State, get_guest_state,\ CharacterOwnership, UserProfile, OwnershipRecord from allianceauth.hooks import get_hooks from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo +from allianceauth.eveonline.tasks import update_character if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS: _has_auto_groups = True @@ -26,6 +27,10 @@ else: _has_auto_groups = False +_USERS_MAX_GROUPS = 5 +_USERS_MAX_CHARACTERS = 3 + + def make_service_hooks_update_groups_action(service): """ Make a admin action for the given service @@ -164,13 +169,54 @@ class MainAllianceFilter(admin.SimpleListFilter): .filter(profile__main_character__alliance_id=self.value()) +def update_main_character_model(modeladmin, request, queryset): + tasks_count = 0 + for obj in queryset: + if obj.profile.main_character: + update_character.delay(obj.profile.main_character.character_id) + tasks_count += 1 + + modeladmin.message_user( + request, + 'Update from ESI started for {} characters'.format(tasks_count) + ) + +update_main_character_model.short_description = \ + 'Update main character model from ESI' + +def list_2_html_w_tooltips(my_items: list, max_items: int) -> str: + """converts list of strings into HTML with cutoff and tooltip when > max""" + items_truncated_str = ', '.join(my_items[:max_items]) + if len(my_items) <= max_items: + return items_truncated_str + else: + items_truncated_str += ' (...)' + items_all_str = ', '.join(my_items) + return format_html( + '{}', + items_all_str, + items_truncated_str + ) + class UserAdmin(BaseUserAdmin): """ Extending Django's UserAdmin model """ + + class Media: + css = { + "all": ("authentication/css/admin.css",) + } + def get_actions(self, request): actions = super(BaseUserAdmin, self).get_actions(request) + actions[update_main_character_model.__name__] = ( + update_main_character_model, + update_main_character_model.__name__, + update_main_character_model.short_description + ) + for hook in get_hooks('services_hook'): svc = hook() # Check update_groups is redefined/overloaded @@ -209,10 +255,8 @@ class UserAdmin(BaseUserAdmin): list_filter = ( 'profile__state', - RealGroupsFilter, - #'profile__main_character__corporation_name', - MainCorporationsFilter, - #'profile__main_character__alliance_name', + RealGroupsFilter, + MainCorporationsFilter, MainAllianceFilter, 'is_active', 'date_joined', @@ -221,14 +265,13 @@ class UserAdmin(BaseUserAdmin): ) search_fields = ( 'username', - 'character_ownerships__character__character_name', - 'groups__name' + 'character_ownerships__character__character_name' ) def _profile_pic(self, obj): if obj.profile.main_character: return format_html( - '', + '', obj.profile.main_character.portrait_url(size=32) ) else: @@ -275,12 +318,13 @@ class UserAdmin(BaseUserAdmin): def _characters(self, obj): - return [ + my_characters = [ x.character.character_name for x in CharacterOwnership.objects\ .filter(user=obj)\ .order_by('character__character_name') - ] + ] + return list_2_html_w_tooltips(my_characters, _USERS_MAX_CHARACTERS) _characters.short_description = 'characters' @@ -303,8 +347,8 @@ class UserAdmin(BaseUserAdmin): .order_by('name') ] - return ', '.join(my_groups) - + return list_2_html_w_tooltips(my_groups, _USERS_MAX_GROUPS) + _groups.short_description = 'groups' diff --git a/allianceauth/authentication/static/authentication/css/admin.css b/allianceauth/authentication/static/authentication/css/admin.css new file mode 100644 index 00000000..4408ea6e --- /dev/null +++ b/allianceauth/authentication/static/authentication/css/admin.css @@ -0,0 +1,23 @@ +/* +CSS for allianceauth admin site +*/ + +.img-circle { border-radius: 50%; } +.column-_profile_pic { width: 50px; } + +/* tooltip */ +.tooltip { + position: relative ; +} +.tooltip:hover::after { + content: attr(data-tooltip) ; + position: absolute ; + top: 1.1em ; + left: 1em ; + min-width: 200px ; + border: 1px #808080 solid ; + padding: 8px ; + color: black ; + background-color: rgb(255, 255, 204) ; + z-index: 1 ; +} \ No newline at end of file diff --git a/allianceauth/services/modules/discord/admin.py b/allianceauth/services/modules/discord/admin.py index 778e4d5d..67122cb1 100644 --- a/allianceauth/services/modules/discord/admin.py +++ b/allianceauth/services/modules/discord/admin.py @@ -12,10 +12,9 @@ class MainCorporationsFilter(admin.SimpleListFilter): title = 'corporation' parameter_name = 'main_corporations' - def lookups(self, request, model_admin): + def lookups(self, request, model_admin): qs = EveCharacter.objects\ .exclude(userprofile=None)\ - .exclude(userprofile__user__discord=None)\ .values('corporation_id', 'corporation_name')\ .distinct()\ .order_by(Lower('corporation_name')) @@ -40,7 +39,6 @@ class MainAllianceFilter(admin.SimpleListFilter): qs = EveCharacter.objects\ .exclude(alliance_id=None)\ .exclude(userprofile=None)\ - .exclude(userprofile__user__discord=None)\ .values('alliance_id', 'alliance_name')\ .distinct()\ .order_by(Lower('alliance_name')) diff --git a/allianceauth/services/modules/discord/static/services/discord/admin.css b/allianceauth/services/modules/discord/static/services/discord/admin.css index 55a52f35..72fedd99 100644 --- a/allianceauth/services/modules/discord/static/services/discord/admin.css +++ b/allianceauth/services/modules/discord/static/services/discord/admin.css @@ -1,5 +1,5 @@ /* -CSS for allianceauth services admin site +CSS for allianceauth admin site */ .img-circle { border-radius: 50%; }