BS5 Theme

This commit is contained in:
Aaron Kable 2023-10-07 08:20:22 +00:00 committed by Ariel Rin
parent 567d97f38a
commit 2e78aa5f26
161 changed files with 3198 additions and 1655 deletions

View File

@ -1,5 +1,30 @@
from django.apps import AppConfig from django.apps import AppConfig
from django.core.checks import Warning, Error, register
class AllianceAuthConfig(AppConfig): class AllianceAuthConfig(AppConfig):
name = 'allianceauth' name = 'allianceauth'
@register()
def check_settings(app_configs, **kwargs):
from django.conf import settings
errors = []
if hasattr(settings, "SITE_URL"):
if settings.SITE_URL[-1] == "/":
errors.append(Warning(
"'SITE_URL' Has a trailing slash. This may lead to incorrect links being generated by Auth."))
else:
errors.append(Error(
"No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules."))
if hasattr(settings, "CSRF_TRUSTED_ORIGINS"):
if hasattr(settings, "SITE_URL"):
if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS:
errors.append(Warning(
"'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified."))
else:
errors.append(Error(
"No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified"))
return errors

View File

@ -0,0 +1,45 @@
from allianceauth.hooks import DashboardItemHook
from allianceauth import hooks
from .views import dashboard_characters, dashboard_groups, dashboard_admin
class UserCharactersHook(DashboardItemHook):
def __init__(self):
DashboardItemHook.__init__(
self,
dashboard_characters,
5
)
class UserGroupsHook(DashboardItemHook):
def __init__(self):
DashboardItemHook.__init__(
self,
dashboard_groups,
5
)
class AdminHook(DashboardItemHook):
def __init__(self):
DashboardItemHook.__init__(
self,
dashboard_admin,
0
)
@hooks.register('dashboard_hook')
def register_character_hook():
return UserCharactersHook()
@hooks.register('dashboard_hook')
def register_groups_hook():
return UserGroupsHook()
@hooks.register('dashboard_hook')
def register_admin_hook():
return AdminHook()

View File

@ -31,6 +31,7 @@ class UserSettingsMiddleware(MiddlewareMixin):
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
# AA v3 NIGHT_MODE
# Set our Night mode flag from the DB # Set our Night mode flag from the DB
# Null = hasnt been set by the user ever, dont act. # Null = hasnt been set by the user ever, dont act.
# #
@ -42,4 +43,11 @@ class UserSettingsMiddleware(MiddlewareMixin):
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
# AA v4 Themes
try:
if request.user.profile.theme is not None:
request.session["THEME"] = request.user.profile.theme
except Exception as e:
logger.exception(e)
return response return response

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0.10 on 2023-10-07 07:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0021_alter_userprofile_language'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='theme',
field=models.CharField(blank=True, help_text='Bootstrap 5 Themes from https://bootswatch.com/ or Community Apps', max_length=200, null=True, verbose_name='Theme'),
),
]

View File

@ -101,6 +101,13 @@ class UserProfile(models.Model):
_("Night Mode"), _("Night Mode"),
blank=True, blank=True,
null=True) null=True)
theme = models.CharField(
_("Theme"),
max_length=200,
blank=True,
null=True,
help_text="Bootstrap 5 Themes from https://bootswatch.com/ or Community Apps"
)
def assign_state(self, state=None, commit=True): def assign_state(self, state=None, commit=True):
if not state: if not state:

View File

@ -0,0 +1,41 @@
{% load i18n %}
<div class="col-12 col-xl-8 align-self-stretch p-2">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<h4 class="ms-auto me-auto">
{% translate "Characters" %}
</h4>
</div>
<div class="card-body">
<div style="height: 300px;overflow:-moz-scrollbars-vertical;overflow-y:auto;">
<div class="d-flex">
<a href="{% url 'authentication:add_character' %}" class="btn btn-primary flex-fill m-1" title="{% translate 'Add Character' %}"><span class="d-md-inline m-2">{% translate 'Add Character' %}</span></a>
<a href="{% url 'authentication:change_main_character' %}" class="btn btn-primary flex-fill m-1" title="{% translate 'Change Main' %}"></span><span class="d-md-inline m-2">{% translate 'Change Main' %}</span></a>
</div>
<table class="table" style="--bs-table-bg: transparent;">
<thead>
<tr>
<th class="text-center"></th>
<th class="text-center">{% translate "Name" %}</th>
<th class="text-center">{% translate "Corp" %}</th>
<th class="text-center">{% translate "Alliance" %}</th>
</tr>
</thead>
<tbody>
{% for char in characters %}
<tr>
<td class="text-center"><img class="ra-avatar rounded-circle" src="{{ char.portrait_url_32 }}">
</td>
<td class="text-center">{{ char.character_name }}</td>
<td class="text-center">{{ char.corporation_name }}</td>
<td class="text-center">{{ char.alliance_name|default_if_none:"" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,20 @@
{% load i18n %}
<div class="col-12 col-xl-4 align-self-stretch p-2">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title text-center">{% translate "Membership" %}</h4>
<div class="card-body">
<div style="height: 300px;overflow:-moz-scrollbars-vertical;overflow-y:auto;">
<h6 class="text-center">{% translate "State:" %} {{ request.user.profile.state }}</h6>
<table class="table" style="--bs-table-bg: transparent;">
{% for group in groups %}
<tr>
<td class="text-center">{{ group.name }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,190 +1,15 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Dashboard" %}{% endblock %} {% block page_title %}{% translate "Dashboard" %}{% endblock %}
{% block header_nav_brand %}
{% translate "Dashboard" %}
{% endblock %}
{% block content %} {% block content %}
<h1 class="page-header text-center">{% translate "Dashboard" %}</h1> <div class="d-flex justify-content-around align-self-center flex-wrap">
{% if user.is_staff %} {% for dash in views %}
{% include 'allianceauth/admin-status/include.html' %} {{ dash | safe }}
{% endif %}
<div class="col-sm-12">
<div class="row vertical-flexbox-row2">
<div class="col-sm-6 text-center">
<div class="panel panel-primary" style="height:100%">
<div class="panel-heading">
<h3 class="panel-title">
{% blocktranslate with state=request.user.profile.state %}
Main Character (State: {{ state }})
{% endblocktranslate %}
</h3>
</div>
<div class="panel-body">
{% if request.user.profile.main_character %}
{% with request.user.profile.main_character as main %}
<div class="hidden-xs">
<div class="col-lg-4 col-sm-2">
<table class="table">
<tr>
<td class="text-center">
<img class="ra-avatar" src="{{ main.portrait_url_128 }}" alt="{{ main.character_name }}">
</td>
</tr>
<tr>
<td class="text-center">{{ main.character_name }}</td>
</tr>
</table>
</div>
<div class="col-lg-4 col-sm-2">
<table class="table">
<tr>
<td class="text-center">
<img class="ra-avatar" src="{{ main.corporation_logo_url_128 }}" alt="{{ main.corporation_name }}">
</td>
</tr>
<tr>
<td class="text-center">{{ main.corporation_name }}</td>
</tr>
</table>
</div>
<div class="col-lg-4 col-sm-2">
{% if main.alliance_id %}
<table class="table">
<tr>
<td class="text-center">
<img class="ra-avatar" src="{{ main.alliance_logo_url_128 }}" alt="{{ main.alliance_name }}">
</td>
</tr>
<tr>
<td class="text-center">{{ main.alliance_name }}</td>
<tr>
</table>
{% elif main.faction_id %}
<table class="table">
<tr>
<td class="text-center">
<img class="ra-avatar" src="{{ main.faction_logo_url_128 }}" alt="{{ main.faction_name }}">
</td>
</tr>
<tr>
<td class="text-center">{{ main.faction_name }}</td>
<tr>
</table>
{% endif %}
</div>
</div>
<div class="table visible-xs-block">
<p>
<img class="ra-avatar" src="{{ main.portrait_url_64 }}" alt="{{ main.corporation_name }}">
<img class="ra-avatar" src="{{ main.corporation_logo_url_64 }}" alt="{{ main.corporation_name }}">
{% if main.alliance_id %}
<img class="ra-avatar" src="{{ main.alliance_logo_url_64 }}" alt="{{ main.alliance_name }}">
{% endif %}
{% if main.faction_id %}
<img class="ra-avatar" src="{{ main.faction_logo_url_64 }}" alt="{{ main.faction_name }}">
{% endif %}
</p>
<p>
<strong>{{ main.character_name }}</strong><br>
{{ main.corporation_name }}<br>
{% if main.alliance_id %}
{{ main.alliance_name }}<br>
{% endif %}
{% if main.faction_id %}
{{ main.faction_name }}
{% endif %}
</p>
</div>
{% endwith %}
{% else %}
<div class="alert alert-danger" role="alert">
{% translate "No main character set." %}
</div>
{% endif %}
<div class="clearfix"></div>
<div class="row">
<div class="col-sm-6">
<p>
<a href="{% url 'authentication:add_character' %}" class="btn btn-block btn-info"
title="Add Character">{% translate 'Add Character' %}</a>
</p>
</div>
<div class="col-sm-6">
<p>
<a href="{% url 'authentication:change_main_character' %}" class="btn btn-block btn-info"
title="Change Main Character">{% translate "Change Main" %}</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 text-center">
<div class="panel panel-success" style="height:100%">
<div class="panel-heading">
<h3 class="panel-title">{% translate "Group Memberships" %}</h3>
</div>
<div class="panel-body">
<div style="height: 240px;overflow-y:auto;">
<table class="table table-aa">
{% for group in groups %}
<tr>
<td>{{ group.name }}</td>
</tr>
{% endfor %} {% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title text-center" style="text-align: center">
{% translate 'Characters' %}
</h3>
</div>
<div class="panel-body">
<table class="table table-aa hidden-xs">
<thead>
<tr>
<th class="text-center"></th>
<th class="text-center">{% translate 'Name' %}</th>
<th class="text-center">{% translate 'Corp' %}</th>
<th class="text-center">{% translate 'Alliance' %}</th>
</tr>
</thead>
<tbody>
{% for char in characters %}
<tr>
<td class="text-center">
<img class="ra-avatar img-circle" src="{{ char.portrait_url_32 }}" alt="{{ char.character_name }}">
</td>
<td class="text-center">{{ char.character_name }}</td>
<td class="text-center">{{ char.corporation_name }}</td>
<td class="text-center">{{ char.alliance_name|default:"" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table table-aa visible-xs-block" style="width: 100%">
<tbody>
{% for char in characters %}
<tr>
<td class="text-center" style="vertical-align: middle">
<img class="ra-avatar img-circle" src="{{ char.portrait_url_32 }}" alt="{{ char.character_name }}">
</td>
<td class="text-center" style="vertical-align: middle; width: 100%">
<strong>{{ char.character_name }}</strong><br>
{{ char.corporation_name }}<br>
{{ char.alliance_name|default:"" }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,7 +1,7 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Dashboard" %}{% endblock %} {% block page_title %}{% translate "Dashboard" %}{% endblock page_title %}
{% block content %} {% block content %}
<h1 class="page-header text-center">{% translate "Token Management" %}</h1> <h1 class="page-header text-center">{% translate "Token Management" %}</h1>
@ -10,7 +10,7 @@
<thead> <thead>
<tr> <tr>
<th>{% translate "Scopes" %}</th> <th>{% translate "Scopes" %}</th>
<th class="text-right">{% translate "Actions" %}</th> <th class="text-end">{% translate "Actions" %}</th>
<th>{% translate "Character" %}</th> <th>{% translate "Character" %}</th>
</tr> </tr>
@ -18,24 +18,24 @@
<tbody> <tbody>
{% for t in tokens %} {% for t in tokens %}
<tr> <tr>
<td styl="white-space:initial;">{% for s in t.scopes.all %}<span class="label label-default">{{s.name}}</span> {% endfor %}</td> <td styl="white-space:initial;">{% for s in t.scopes.all %}<span class="badge badge-secondar">{{ s.name }}</span> {% endfor %}</td>
<td nowrap class="text-right"><a href="{% url 'authentication:token_delete' t.id %}" class="btn btn-danger"><i class="fas fa-trash"></i></a> <a href="{% url 'authentication:token_refresh' t.id %}" class="btn btn-success"><i class="fas fa-sync-alt"></i></a></td> <td nowrap class="text-end"><a href="{% url 'authentication:token_delete' t.id %}" class="btn btn-danger"><i class="fas fa-trash"></i></a> <a href="{% url 'authentication:token_refresh' t.id %}" class="btn btn-success"><i class="fas fa-sync-alt"></i></a></td>
<td>{{t.character_name}}</td> <td>{{ t.character_name }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://community.eveonline.com/support/third-party-applications/ where possible."|urlize %} {% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://community.eveonline.com/support/third-party-applications/ where possible."|urlize %}
</div> </div>
{% endblock %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include "bundles/datatables-js-bs5.html" %}
{% endblock %} {% endblock extra_javascript %}
{% block extra_css %} {% block extra_css %}
{% include 'bundles/datatables-css.html' %} {% include "bundles/datatables-css-bs5.html" %}
{% endblock %} {% endblock extra_css %}
{% block extra_script %} {% block extra_script %}
$(document).ready(function(){ $(document).ready(function(){
@ -59,4 +59,4 @@
"stateSave": true, "stateSave": true,
}); });
}); });
{% endblock %} {% endblock extra_script %}

View File

@ -7,6 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="">
<!-- TODO Bundle all the site specific stuff up into its own template for easy overide -->
<meta property="og:title" content="{{ SITE_NAME }}"> <meta property="og:title" content="{{ SITE_NAME }}">
<meta property="og:image" content="{{ SITE_URL }}{% static 'allianceauth/icons/apple-touch-icon.png' %}"> <meta property="og:image" content="{{ SITE_URL }}{% static 'allianceauth/icons/apple-touch-icon.png' %}">
<meta property="og:description" content="Alliance Auth - An auth system for EVE Online to help in-game organizations manage online service access."> <meta property="og:description" content="Alliance Auth - An auth system for EVE Online to help in-game organizations manage online service access.">

View File

@ -1,4 +1,5 @@
import logging import logging
from allianceauth.hooks import get_hooks
from django_registration.backends.activation.views import ( from django_registration.backends.activation.views import (
REGISTRATION_SALT, ActivationView as BaseActivationView, REGISTRATION_SALT, ActivationView as BaseActivationView,
@ -42,23 +43,51 @@ def index(request):
return redirect('authentication:dashboard') return redirect('authentication:dashboard')
@login_required def dashboard_groups(request):
def dashboard(request):
groups = request.user.groups.all() groups = request.user.groups.all()
if _has_auto_groups: if _has_auto_groups:
groups = groups\ groups = groups\
.filter(managedalliancegroup__isnull=True)\ .filter(managedalliancegroup__isnull=True)\
.filter(managedcorpgroup__isnull=True) .filter(managedcorpgroup__isnull=True)
groups = groups.order_by('name') groups = groups.order_by('name')
context = {
'groups': groups,
}
return render_to_string('authentication/dashboard.groups.html', context=context, request=request)
def dashboard_characters(request):
characters = EveCharacter.objects\ characters = EveCharacter.objects\
.filter(character_ownership__user=request.user)\ .filter(character_ownership__user=request.user)\
.select_related()\ .select_related()\
.order_by('character_name') .order_by('character_name')
context = { context = {
'groups': groups,
'characters': characters 'characters': characters
} }
return render_to_string('authentication/dashboard.characters.html', context=context, request=request)
def dashboard_admin(request):
if request.user.is_superuser:
return render_to_string('allianceauth/admin-status/include.html', request=request)
else:
return ""
@login_required
def dashboard(request):
_dash_items = list()
hooks = get_hooks('dashboard_hook')
items = [fn() for fn in hooks]
items.sort(key=lambda i: i.order)
for item in items:
_dash_items.append(item.render(request))
context = {
'views': _dash_items,
}
return render(request, 'authentication/dashboard.html', context) return render(request, 'authentication/dashboard.html', context)

View File

@ -1,5 +1,5 @@
from django.conf import settings from django.conf import settings
from .views import NightModeRedirectView from .views import NightModeRedirectView, ThemeRedirectView
def auth_settings(request): def auth_settings(request):

View File

@ -1,4 +1,5 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.menu.hooks import MenuItemHook
from allianceauth.services.hooks import UrlHook
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.corputils import urls from allianceauth.corputils import urls

View File

@ -1,6 +1,8 @@
{% extends 'allianceauth/base.html' %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Corporation Member Data" %}{% endblock %} {% block page_title %}
{% translate "Corporation Member Data" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Corporation Member Data" %}</h1> <h1 class="page-header text-center">{% translate "Corporation Member Data" %}</h1>
@ -26,12 +28,13 @@
</ul> </ul>
<form class="navbar-form navbar-right" role="search" action="{% url 'corputils:search' %}" method="GET"> <form class="navbar-form navbar-right" role="search" action="{% url 'corputils:search' %}" method="GET">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" name="search_string" placeholder="{% if search_string %}{{ search_string }}{% else %}{% translate "Search all corporations..." %}{% endif %}"> <input type="text" class="form-control" name="search_string" placeholder="{% if search_string %}{{ search_string }}{% else %}{% translate 'Search all corporations...' %}{% endif %}">
</div> </div>
</form> </form>
</div> </div>
</nav> </nav>
{% block member_data %}{% endblock %} {% block member_data %}
{% endblock member_data %}
</div> </div>
</div> </div>
{% endblock %} {% endblock content %}

View File

@ -87,7 +87,7 @@
<td class="text-center" style="width:30%">{{ alt.corporation_name }}</td> <td class="text-center" style="width:30%">{{ alt.corporation_name }}</td>
<td class="text-center" style="width:30%">{{ alt.alliance_name }}</td> <td class="text-center" style="width:30%">{{ alt.alliance_name }}</td>
<td class="text-center" style="width:5%"> <td class="text-center" style="width:5%">
<a href="https://zkillboard.com/character/{{ alt.character_id }}/" class="label label-danger" target="_blank"> <a href="https://zkillboard.com/character/{{ alt.character_id }}/" class="badge badge-danger" target="_blank">
{% translate "Killboard" %} {% translate "Killboard" %}
</a> </a>
</td> </td>
@ -122,7 +122,7 @@
<td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member }}"></td> <td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member }}"></td>
<td class="text-center">{{ member }}</td> <td class="text-center">{{ member }}</td>
<td class="text-center"> <td class="text-center">
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% translate "Killboard" %}</a> <a href="https://zkillboard.com/character/{{ member.character_id }}/" class="badge badge-danger" target="_blank">{% translate "Killboard" %}</a>
</td> </td>
<td class="text-center">{{ member.character_ownership.user.profile.main_character.character_name }}</td> <td class="text-center">{{ member.character_ownership.user.profile.main_character.character_name }}</td>
<td class="text-center">{{ member.character_ownership.user.profile.main_character.corporation_name }}</td> <td class="text-center">{{ member.character_ownership.user.profile.main_character.corporation_name }}</td>
@ -134,7 +134,7 @@
<td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member.character_name }}"></td> <td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member.character_name }}"></td>
<td class="text-center">{{ member.character_name }}</td> <td class="text-center">{{ member.character_name }}</td>
<td class="text-center"> <td class="text-center">
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% translate "Killboard" %}</a> <a href="https://zkillboard.com/character/{{ member.character_id }}/" class="badge badge-danger" target="_blank">{% translate "Killboard" %}</a>
</td> </td>
<td class="text-center"></td> <td class="text-center"></td>
<td class="text-center"></td> <td class="text-center"></td>
@ -163,7 +163,7 @@
<td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member.character_name }}"></td> <td><img src="{{ member.portrait_url }}" class="img-circle" alt="{{ member.character_name }}"></td>
<td class="text-center">{{ member.character_name }}</td> <td class="text-center">{{ member.character_name }}</td>
<td class="text-center"> <td class="text-center">
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank"> <a href="https://zkillboard.com/character/{{ member.character_id }}/" class="badge badge-danger" target="_blank">
{% translate "Killboard" %} {% translate "Killboard" %}
</a> </a>
</td> </td>

View File

@ -24,7 +24,7 @@
<td class="text-center"><img src="{{ result.1.portrait_url }}" class="img-circle" alt="{{ result.1.character_name }}"></td> <td class="text-center"><img src="{{ result.1.portrait_url }}" class="img-circle" alt="{{ result.1.character_name }}"></td>
<td class="text-center">{{ result.1.character_name }}</td> <td class="text-center">{{ result.1.character_name }}</td>
<td class="text-center">{{ result.0.corp.corporation_name }}</td> <td class="text-center">{{ result.0.corp.corporation_name }}</td>
<td class="text-center"><a href="https://zkillboard.com/character/{{ result.1.character_id }}/" class="label label-danger" target="_blank">{% translate "Killboard" %}</a></td> <td class="text-center"><a href="https://zkillboard.com/character/{{ result.1.character_id }}/" class="badge badge-danger" target="_blank">{% translate "Killboard" %}</a></td>
<td class="text-center">{{ result.1.main_character.character_name }}</td> <td class="text-center">{{ result.1.main_character.character_name }}</td>
<td class="text-center">{{ result.1.main_character.corporation_name }}</td> <td class="text-center">{{ result.1.main_character.corporation_name }}</td>
<td class="text-center">{{ result.1.main_character.alliance_name }}</td> <td class="text-center">{{ result.1.main_character.alliance_name }}</td>

View File

@ -8,10 +8,10 @@ Needs to be called with a context containing three objects:
--> -->
{% extends 'allianceauth/base.html' %} {% extends "allianceauth/base-bs5.html" %}
{% load evelinks %} {% load evelinks %}
{% block page_title %}Evelinks examples{% endblock %} {% block page_title %}Evelinks Examples{% endblock page_title %}
{% block content %} {% block content %}
@ -25,33 +25,32 @@ Needs to be called with a context containing three objects:
<div class="col-md-4"> <div class="col-md-4">
<h3>evewho</h3> <h3>evewho</h3>
<p><a href="{{ my_character|evewho_character_url}}">character from character object</a></p> <p><a href="{{ my_character|evewho_character_url }}">character from character object</a></p>
<p><a href="{{ my_corporation|evewho_corporation_url}}">corporation form corporation object</a></p> <p><a href="{{ my_corporation|evewho_corporation_url }}">corporation form corporation object</a></p>
<p><a href="{{ my_character|evewho_corporation_url}}">corporation from charachter object</a></p> <p><a href="{{ my_character|evewho_corporation_url }}">corporation from charachter object</a></p>
<p><a href="{{ my_alliance|evewho_alliance_url}}">alliance from alliance object</a></p> <p><a href="{{ my_alliance|evewho_alliance_url }}">alliance from alliance object</a></p>
<p><a href="{{ my_character|evewho_alliance_url}}">alliance from character object</a></p> <p><a href="{{ my_character|evewho_alliance_url }}">alliance from character object</a></p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h3>dotlan</h3> <h3>dotlan</h3>
<p><a href="{{ my_character|dotlan_corporation_url}}">corporation form character object</a></p> <p><a href="{{ my_character|dotlan_corporation_url }}">corporation form character object</a></p>
<p><a href="{{ my_corporation|dotlan_corporation_url}}">corporation form corporation object</a></p> <p><a href="{{ my_corporation|dotlan_corporation_url }}">corporation form corporation object</a></p>
<p><a href="{{ my_character|dotlan_alliance_url}}">alliance from character object</a></p> <p><a href="{{ my_character|dotlan_alliance_url }}">alliance from character object</a></p>
<p><a href="{{ my_alliance|dotlan_alliance_url}}">alliance from alliance object</a></p> <p><a href="{{ my_alliance|dotlan_alliance_url }}">alliance from alliance object</a></p>
<p><a href="{{ 'Black Rise'|dotlan_region_url}}">region from name string</a></p> <p><a href="{{ 'Black Rise'|dotlan_region_url }}">region from name string</a></p>
<p><a href="{{ 'Tama'|dotlan_solar_system_url}}">solar system from name string</a></p> <p><a href="{{ 'Tama'|dotlan_solar_system_url }}">solar system from name string</a></p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h3>zkillboard</h3> <h3>zkillboard</h3>
<p><a href="{{ my_character|zkillboard_character_url}}">character from character object</a></p> <p><a href="{{ my_character|zkillboard_character_url }}">character from character object</a></p>
<p><a href="{{ my_character|zkillboard_corporation_url}}">corporation from character object</a></p> <p><a href="{{ my_character|zkillboard_corporation_url }}">corporation from character object</a></p>
<p><a href="{{ my_corporation|zkillboard_corporation_url}}">corporation form corporation object</a></p> <p><a href="{{ my_corporation|zkillboard_corporation_url }}">corporation form corporation object</a></p>
<p><a href="{{ my_character|zkillboard_alliance_url}}">alliance from character object</a></p> <p><a href="{{ my_character|zkillboard_alliance_url }}">alliance from character object</a></p>
<p><a href="{{ my_alliance|zkillboard_alliance_url}}">alliance from alliance object</a></p> <p><a href="{{ my_alliance|zkillboard_alliance_url }}">alliance from alliance object</a></p>
<p><a href="{{ 10000069|zkillboard_region_url}}">region from ID</a></p> <p><a href="{{ 10000069|zkillboard_region_url }}">region from ID</a></p>
<p><a href="{{ 30002813|zkillboard_solar_system_url}}">solar sytem from ID</a></p> <p><a href="{{ 30002813|zkillboard_solar_system_url }}">solar sytem from ID</a></p>
</div>
</div> </div>
</div> </div>
@ -60,25 +59,23 @@ Needs to be called with a context containing three objects:
<div class="rows"> <div class="rows">
<div class="col-md-4"> <div class="col-md-4">
<p>character from ID: <img src="{{ my_character.character_id|character_portrait_url:128}}"></p> <p>character from ID: <img src="{{ my_character.character_id|character_portrait_url:128 }}"></p>
<p>character from character object: <img src="{{ my_character|character_portrait_url:128}}"></p> <p>character from character object: <img src="{{ my_character|character_portrait_url:128 }}"></p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<p>corporation from ID: <img src="{{ my_character.corporation_id|corporation_logo_url:128}}"></p> <p>corporation from ID: <img src="{{ my_character.corporation_id|corporation_logo_url:128 }}"></p>
<p>corporation from character object: <img src="{{ my_character|corporation_logo_url:128}}"></p> <p>corporation from character object: <img src="{{ my_character|corporation_logo_url:128 }}"></p>
<p>corporation from corporation object: <img src="{{ my_corporation|corporation_logo_url:128}}"></p> <p>corporation from corporation object: <img src="{{ my_corporation|corporation_logo_url:128 }}"></p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<p>alliance from ID: <img src="{{ my_character.alliance_id|alliance_logo_url:128}}"></p> <p>alliance from ID: <img src="{{ my_character.alliance_id|alliance_logo_url:128 }}"></p>
<p>alliance from character object: <img src="{{ my_character|alliance_logo_url:128}}"></p> <p>alliance from character object: <img src="{{ my_character|alliance_logo_url:128 }}"></p>
<p>alliance from alliance object: <img src="{{ my_alliance|alliance_logo_url:128}}"></p> <p>alliance from alliance object: <img src="{{ my_alliance|alliance_logo_url:128 }}"></p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock content %}

View File

@ -1,7 +1,8 @@
from allianceauth.menu.hooks import MenuItemHook
from . import urls from . import urls
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import UrlHook
@hooks.register('menu_item_hook') @hooks.register('menu_item_hook')

View File

@ -1,9 +1,10 @@
{% extends 'allianceauth/base.html' %} {% extends 'allianceauth/base-bs5.html' %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Fleet Participation" %}{% endblock %} {% block page_title %}
{% translate "Fleet Participation" %}
{% endblock %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Character not found!" %}</h1> <h1 class="page-header text-center">{% translate "Character not found!" %}</h1>
<div class="col-lg-12 container" id="example"> <div class="col-lg-12 container" id="example">
<div class="row"> <div class="row">
@ -23,5 +24,5 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,31 +1,31 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load bootstrap %} {% load bootstrap %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Create Fatlink" %}{% endblock page_title %} {% translate "Create Fatlink" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Create Fleet Operation" %}</h1> <h1 class="page-header text-center">{% translate "Create Fleet Operation" %}</h1>
<div class="container-fluid"> <div class="container-fluid">
{% if badrequest %} {% if badrequest %}
<div class="alert alert-danger" role="alert">{% translate "Bad request!" %}</div> <div class="alert alert-danger" role="alert">{% translate "Bad request!" %}</div>
{% endif %} {% endif %}
{% for message in errormessages %} {% for message in errormessages %}<div class="alert alert-danger" role="alert">{{ message }}</div>{% endfor %}
<div class="alert alert-danger" role="alert">{{ message }}</div> <div class="col-md-4 offset-md-4">
{% endfor %}
<div class="col-md-4 col-md-offset-4">
<div class="row"> <div class="row">
<form class="form-signin" role="form" action="" method="POST"> <form class="form-signin" role="form" action="" method="POST">
{% csrf_token %} {% csrf_token %}
{{ form|bootstrap }} {{ form|bootstrap }}
<br> <br/>
<button class="btn btn-lg btn-primary btn-block" type="submit" name="submit_fat">{% translate "Create fatlink" %}</button> <button class="btn btn-lg btn-primary btn-block"
type="submit"
name="submit_fat">
{% translate "Create fatlink" %}
</button>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -1,11 +1,11 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Fatlink view" %}{% endblock page_title %} {% block page_title %}{% translate "Fatlink view" %}{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Edit fatlink" %} "{{ fatlink }}" <h1 class="page-header text-center">{% translate "Edit fatlink" %} "{{ fatlink }}"
<div class="text-right"> <div class="text-end">
<form> <form>
<button type="submit" onclick="return confirm('Are you sure?')" class="btn btn-danger" name="deletefat" value="True"> <button type="submit" onclick="return confirm('Are you sure?')" class="btn btn-danger" name="deletefat" value="True">
{% translate "Delete fat" %} {% translate "Delete fat" %}

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Personal fatlink statistics" %}{% endblock page_title %} {% block page_title %}{% translate "Personal fatlink statistics" %}{% endblock page_title %}
@ -7,7 +7,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} <h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
{% if char_id %} {% if char_id %}
<div class="text-right"> <div class="text-end">
<a href="{% url 'fatlink:user_statistics_month' char_id previous_month|date:'Y' previous_month|date:'m' %}" class="btn btn-info">{% translate "Previous month" %}</a> <a href="{% url 'fatlink:user_statistics_month' char_id previous_month|date:'Y' previous_month|date:'m' %}" class="btn btn-info">{% translate "Previous month" %}</a>
<a href="{% url 'fatlink:user_statistics_month' char_id next_month|date:'Y' next_month|date:'m' %}" class="btn btn-info">{% translate "Next month" %}</a> <a href="{% url 'fatlink:user_statistics_month' char_id next_month|date:'Y' next_month|date:'m' %}" class="btn btn-info">{% translate "Next month" %}</a>
</div> </div>
@ -51,7 +51,7 @@
</tr> </tr>
{% for link in created_fats %} {% for link in created_fats %}
<tr> <tr>
<td class="text-center"><a href="{% url 'fatlink:click' link.hash %}" class="label label-primary">{{ link.fleet }}</a></td> <td class="text-center"><a href="{% url 'fatlink:click' link.hash %}" class="badge badge-primary">{{ link.fleet }}</a></td>
<td class="text-center">{{ link.creator.username }}</td> <td class="text-center">{{ link.creator.username }}</td>
<td class="text-center">{{ link.fatdatetime }}</td> <td class="text-center">{{ link.fatdatetime }}</td>
<td class="text-center">{{ link.duration }}</td> <td class="text-center">{{ link.duration }}</td>

View File

@ -1,30 +1,29 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Personal fatlink statistics" %}{% endblock page_title %} {% translate "Personal fatlink statistics" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ year }}{% endblocktranslate %} <h1 class="page-header text-center">
<div class="text-right"> {% blocktranslate %}Participation data statistics for {{ year }}{% endblocktranslate %}
<a href="{% url 'fatlink:personal_statistics_year' previous_year %}" class="btn btn-info">{% translate "Previous year" %}</a> <div class="text-end">
<a href="{% url "fatlink:personal_statistics_year" previous_year %}" class="btn btn-info"><i class="fa-solid fa-chevron-left"></i> {% translate "Previous year" %}</a>
{% if next_year %} {% if next_year %}
<a href="{% url 'fatlink:personal_statistics_year' next_year %}" class="btn btn-info">{% translate "Next year" %}</a> <a href="{% url "fatlink:personal_statistics_year" next_year %}" class="btn btn-info">{% translate "Next year" %} <i class="fa-solid fa-chevron-right"></i></a>
{% endif %} {% endif %}
</div> </div>
</h1> </h1>
<div class="col-lg-2 col-lg-offset-5"> <div class="col-lg-2 offset-lg-5">
<table class="table table-responsive"> <table class="table table-responsive">
<tr> <tr>
<th class="col-md-2 text-center">{% translate "Month" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Month" %}</th>
<th class="col-md-2 text-center">{% translate "Fats" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Fats" %}</th>
</tr> </tr>
{% for monthnr, month, n_fats in monthlystats %} {% for monthnr, month, n_fats in monthlystats %}
<tr> <tr>
<td class="text-center"> <td class="text-center">
<a href="{% url 'fatlink:personal_statistics_month' year monthnr %}"> <a href="{% url 'fatlink:personal_statistics_month' year monthnr %}">{{ month }}</a>
{{ month }}
</a>
</td> </td>
<td class="text-center">{{ n_fats }}</td> <td class="text-center">{{ n_fats }}</td>
</tr> </tr>

View File

@ -1,27 +1,30 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Fatlink Corp Statistics" %}{% endblock page_title %} {% translate "Fatlink Corp Statistics" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} <h1 class="page-header text-center">
<div class="text-right"> {% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
<a href="{% url 'fatlink:statistics_corp_month' corpid previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a> <div class="text-end">
<a href="{% url "fatlink:statistics_corp_month" corpid previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a>
{% if next_month %} {% if next_month %}
<a href="{% url 'fatlink:statistics_corp_month' corpid next_month|date:"Y" next_month|date:"m" %}" class="btn btn-info">{% translate "Next month" %}</a> <a href="{% url "fatlink:statistics_corp_month" corpid next_month|date:"Y" next_month|date:"m" %}" class="btn btn-info">{% translate "Next month" %}</a>
{% endif %} {% endif %}
</div> </div>
</h1> </h1>
{% if fatStats %} {% if fatStats %}
<table class="table table-responsive"> <div class="table-responsive">
<table class="table table-striped">
<tr> <tr>
<th class="col-md-1"></th> <th scope="col" class="col-md-1"></th>
<th class="col-md-2 text-center">{% translate "Main Character" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Main Character" %}</th>
<th class="col-md-2 text-center">{% translate "Characters" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Characters" %}</th>
<th class="col-md-2 text-center">{% translate "Fats" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Fats" %}</th>
<th class="col-md-2 text-center">{% translate "Average fats" %} <th scope="col" class="col-md-2 text-center">
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i> {% translate "Average fats" %}
<i class="fa-solid fa-question" rel="tooltip" title="Fats / Characters"></i>
</th> </th>
</tr> </tr>
{% for memberStat in fatStats %} {% for memberStat in fatStats %}
@ -36,11 +39,12 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
{% endif %} {% endif %}
</div> </div>
{% endblock content %} {% endblock content %}
{% block extra_script %} {% block extra_script %}
$(document).ready(function () { $(document).ready(function () {
$("[rel=tooltip]").tooltip(); $("[rel=tooltip]").tooltip();
}); });
{% endblock extra_script %} {% endblock extra_script %}

View File

@ -1,36 +1,41 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Fatlink statistics" %}{% endblock page_title %} {% translate "Fatlink Statistics" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %} <h1 class="page-header text-center">
<div class="text-right"> {% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
<a href="{% url 'fatlink:statistics_month' previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a> <div class="text-end">
<a href="{% url "fatlink:statistics_month" previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a>
{% if next_month %} {% if next_month %}
<a href="{% url 'fatlink:statistics_month' next_month|date:"Y" next_month|date:"m" %}" class="btn btn-info">{% translate "Next month" %}</a> <a href="{% url 'fatlink:statistics_month' next_month|date:"Y" next_month|date:"m" %}" wclass="btn btn-info">{% translate "Next month" %}</a>
{% endif %} {% endif %}
</div> </div>
</h1> </h1>
{% if fatStats %} {% if fatStats %}
<table class="table table-responsive"> <div class="table-responsive">
<table class="table table-striped">
<tr> <tr>
<th class="col-md-1"></th> <th scope="col" class="col-md-1"></th>
<th class="col-md-2 text-center">{% translate "Ticker" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Ticker" %}</th>
<th class="col-md-5 text-center">{% translate "Corp" %}</th> <th scope="col" class="col-md-5 text-center">{% translate "Corp" %}</th>
<th class="col-md-2 text-center">{% translate "Members" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Members" %}</th>
<th class="col-md-2 text-center">{% translate "Fats" %}</th> <th scope="col" class="col-md-2 text-center">{% translate "Fats" %}</th>
<th class="col-md-2 text-center">{% translate "Average fats" %} <th scope="col" class="col-md-2 text-center">
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i> {% translate "Average fats" %}
<i class="fa-solid fa-question" rel="tooltip" title="Fats / Characters"></i>
</th> </th>
</tr> </tr>
{% for corpStat in fatStats %} {% for corpStat in fatStats %}
<tr> <tr>
<td> <td>
<img src="{{ corpStat.corp.logo_url_32 }}" class="ra-avatar img-responsive" alt="{{ corpStat.corp.corporation_name }}"> <img src="{{ corpStat.corp.logo_url_32 }}" class="ra-avatar img-responsive" alt="{{ corpStat.corp.corporation_name }}"/>
</td>
<td class="text-center">
<a href="{% url 'fatlink:statistics_corp' corpStat.corp.corporation_id %}">[{{ corpStat.corp.corporation_ticker }}]</a>
</td> </td>
<td class="text-center"><a href="{% url 'fatlink:statistics_corp' corpStat.corp.corporation_id %}">[{{ corpStat.corp.corporation_ticker }}]</a></td>
<td class="text-center">{{ corpStat.corp.corporation_name }}</td> <td class="text-center">{{ corpStat.corp.corporation_name }}</td>
<td class="text-center">{{ corpStat.corp.member_count }}</td> <td class="text-center">{{ corpStat.corp.member_count }}</td>
<td class="text-center">{{ corpStat.n_fats }}</td> <td class="text-center">{{ corpStat.n_fats }}</td>
@ -38,11 +43,12 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
{% endif %} {% endif %}
</div> </div>
{% endblock content %} {% endblock content %}
{% block extra_script %} {% block extra_script %}
$(document).ready(function () { $(document).ready(function () {
$("[rel=tooltip]").tooltip(); $("[rel=tooltip]").tooltip();
}); });
{% endblock extra_script %} {% endblock extra_script %}

View File

@ -1,39 +1,41 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Fatlink view" %}{% endblock page_title %} {% translate "Fatlink view" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Participation data" %}</h1> <h1 class="page-header text-center">{% translate "Participation data" %}</h1>
<table class="table"> <div class="table-responsive">
<table class="table table-striped">
<tr> <tr>
<th class="col-md-11"> <th class="col-md-10">
<h4><b>{% translate "Most recent clicked fatlinks" %}</b> <h4>
<b>{% translate "Most recent clicked fatlinks" %}</b>
</h4> </h4>
</th> </th>
<th class="col-md-1"> <th class="col-md-2 align-self-end">
<a href="{% url 'fatlink:personal_statistics' %}" class="btn btn-info"> <a href="{% url 'fatlink:personal_statistics' %}" class="btn btn-info"><i class="fa-solid fa-circle-info fa-fw"></i>{% translate "Personal statistics" %}</a>
{% translate "Personal statistics" %}
</a>
</th> </th>
</tr> </tr>
</table> </table>
</div>
{% if fats %} {% if fats %}
<table class="table table-responsive"> <div class="table-responsive">
<table class="table table-striped">
<tr> <tr>
<th class="text-center">{% translate "Fleet" %}</th> <th scope="col" class="text-center">{% translate "Fleet" %}</th>
<th class="text-center">{% translate "Character" %}</th> <th scope="col" class="text-center">{% translate "Character" %}</th>
<th class="text-center">{% translate "System" %}</th> <th scope="col" class="text-center">{% translate "System" %}</th>
<th class="text-center">{% translate "Ship" %}</th> <th scope="col" class="text-center">{% translate "Ship" %}</th>
<th class="text-center">{% translate "Eve Time" %}</th> <th scope="col" class="text-center">{% translate "Eve Time" %}</th>
</tr> </tr>
{% for fat in fats %} {% for fat in fats %}
<tr> <tr>
<td class="text-center">{{ fat.fatlink.fleet }}</td> <td class="text-center">{{ fat.fatlink.fleet }}</td>
<td class="text-center">{{ fat.character.character_name }}</td> <td class="text-center">{{ fat.character.character_name }}</td>
{% if fat.station != "No Station" %} {% if fat.station != "No Station" %}
<td class="text-center">{% blocktranslate %}Docked in {% endblocktranslate %}{{ fat.system }}</td> <td class="text-center">{% translate "Docked in" %} {{ fat.system }}</td>
{% else %} {% else %}
<td class="text-center">{{ fat.system }}</td> <td class="text-center">{{ fat.system }}</td>
{% endif %} {% endif %}
@ -42,57 +44,63 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
{% else %} {% else %}
<div class="alert alert-warning text-center">{% translate "No fleet activity on record." %}</div> <div class="alert alert-warning text-center">{% translate "No fleet activity on record." %}</div>
{% endif %} {% endif %}
{% if perms.auth.fleetactivitytracking %}
{% if perms.auth.fleetactivitytracking%} <div class="table-responsive">
<table class="table"> <table class="table table-striped">
<tr> <tr>
<th class="col-md-10"> <th class="col-md-8">
<h4><b>{% translate "Most recent fatlinks" %}</b> <h4>
<b>{% translate "Most recent fatlinks" %}</b>
</h4> </h4>
</th> </th>
<th class="col-md-1"> <th class="col-md-2 align-self-end">
<a href="{% url 'fatlink:statistics' %}" class="btn btn-info"> <a href="{% url 'fatlink:statistics' %}" class="btn btn-info"><i class="fa-solid fa-eye fa-fw"></i> {% translate "View statistics" %}</a>
{% translate "View statistics" %}
</a>
</th> </th>
<th class="col-md-1"> <th class="col-md-2 align-self-end">
<a href="{% url 'fatlink:create' %}" class="btn btn-success"> <a href="{% url 'fatlink:create' %}" class="btn btn-success"><i class="fa-solid fa-plus fa-fw"></i> {% translate "Create fatlink" %}</a>
{% translate "Create fatlink" %}
</a>
</th> </th>
</tr> </tr>
</table> </table>
</div>
{% if fatlinks %} {% if fatlinks %}
<table class="table"> <div class="table-responsive">
<table class="table table-striped">
<tr> <tr>
<th class="text-center">{% translate "Name" %}</th> <th scope="col" class="text-center">{% translate "Name" %}</th>
<th class="text-center">{% translate "Creator" %}</th> <th scope="col" class="text-center">{% translate "Creator" %}</th>
<th class="text-center">{% translate "Fleet" %}</th> <th scope="col" class="text-center">{% translate "Fleet" %}</th>
<th class="text-center">{% translate "Eve Time" %}</th> <th scope="col" class="text-center">{% translate "Eve Time" %}</th>
<th class="text-center">{% translate "Duration" %}</th> <th scope="col" class="text-center">{% translate "Duration" %}</th>
<th class="text-center">{% translate "Edit" %}</th> <th scope="col" class="text-center">{% translate "Edit" %}</th>
</tr> </tr>
{% for link in fatlinks %} {% for link in fatlinks %}
<tr> <tr>
<td class="text-center"><a href="{% url 'fatlink:click' link.hash %}" class="label label-primary">{{ link.fleet }}</a></td> <td class="text-center">
<a href="{% url 'fatlink:click' link.hash %}" class="badge badge-primary">{{ link.fleet }}</a>
</td>
<td class="text-center">{{ link.creator.username }}</td> <td class="text-center">{{ link.creator.username }}</td>
<td class="text-center">{{ link.fleet }}</td> <td class="text-center">{{ link.fleet }}</td>
<td class="text-center">{{ link.fatdatetime }}</td> <td class="text-center">{{ link.fatdatetime }}</td>
<td class="text-center">{{ link.duration }}</td> <td class="text-center">
{{ link.duration }}
</td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'fatlink:modify' link.hash %}" class="btn btn-info"> <a href="{% url 'fatlink:modify' link.hash %}" class="btn btn-info">
<span class="glyphicon glyphicon-edit"></span> <i class="fa-solid fa-pen-to-square fa-fw"></i>
</a> </a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
{% else %} {% else %}
<div class="alert alert-warning text-center">{% translate "No created fatlinks on record." %}</div> <div class="alert alert-warning text-center">
{% translate "No created fatlinks on record." %}
</div>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>

View File

@ -1,6 +1,7 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth.menu.hooks import MenuItemHook
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import UrlHook
from allianceauth import hooks from allianceauth import hooks
from . import urls from . import urls
@ -33,11 +34,43 @@ class GroupManagementMenuItem(MenuItemHook):
return "" return ""
"""
<li class="d-flex m-2 p-2 pt-0 pb-0 mt-0 mb-0">
<i class="fas fa-users fa-fw align-self-center me-2"></i>
<a class="nav-link flex-fill align-self-center {% navactive request 'groupmanagement:groups' %}" href="{% url 'groupmanagement:groups' %}">
{% translate "Groups" %}
</a>
</li>
"""
class GroupsMenuItem(MenuItemHook):
def __init__(self):
MenuItemHook.__init__(
self,
text=_("Groups"),
classes="fas fa-user fa-fw",
url_name="groupmanagement:groups",
order=25,
navactive=[
"groupmanagement:groups", # group list view
],
)
def render(self, request):
return MenuItemHook.render(self, request)
@hooks.register("menu_item_hook") @hooks.register("menu_item_hook")
def register_menu(): def register_manager_menu():
return GroupManagementMenuItem() return GroupManagementMenuItem()
@hooks.register("menu_item_hook")
def register_groups_menu():
return GroupsMenuItem()
@hooks.register("url_hook") @hooks.register("url_hook")
def register_urls(): def register_urls():
return UrlHook(urls, "group", r"^groups/") return UrlHook(urls, "group", r"^groups/")

View File

@ -1,30 +1,22 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% load navactive %}
{% block page_title %}{{ group }} {% translate "Audit Log" %}{% endblock page_title %} {% block page_title %}{{ group }} {% translate "Audit Log" %}{% endblock page_title %}
{% block header_nav_brand %}{% translate "Audit Log" %} - {{ group.name }}{% endblock header_nav_brand %}
{% block header_nav_collapse_left %}
<li class="nav-item ">
<a class="nav-link {% navactive request 'groupmanagement:management' %}" href="{% url 'groupmanagement:management' %}">{% translate "Back" %}</a>
</li>
{% endblock %}
{% block content %} {% block content %}
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{{ group }} - {% translate "Audit Log" %}
</div>
<div class="panel-body">
<p>
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
{% translate "Back" %}
</a>
</p>
{% if entries %} {% if entries %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped" id="log-entries"> <table class="table table-striped" id="log-entries">
<thead> <thead>
<tr>
<th scope="col">{% translate "Date/Time" %}</th> <th scope="col">{% translate "Date/Time" %}</th>
<th scope="col">{% translate "Requestor" %}</th> <th scope="col">{% translate "Requestor" %}</th>
<th scope="col">{% translate "Character" %}</th> <th scope="col">{% translate "Character" %}</th>
@ -32,7 +24,6 @@
<th scope="col">{% translate "Type" %}</th> <th scope="col">{% translate "Type" %}</th>
<th scope="col">{% translate "Action" %}</th> <th scope="col">{% translate "Action" %}</th>
<th scope="col">{% translate "Actor" %}</th> <th scope="col">{% translate "Actor" %}</th>
</tr>
</thead> </thead>
<tbody> <tbody>
@ -67,19 +58,16 @@
{% translate "No entries found for this group." %} {% translate "No entries found for this group." %}
</div> </div>
{% endif %} {% endif %}
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include 'bundles/datatables-js-bs5.html' %}
{% include 'bundles/moment-js.html' with locale=True %} {% include 'bundles/moment-js.html' with locale=True %}
{% include 'bundles/filterdropdown-js.html' %} {% include 'bundles/filterdropdown-js.html' %}
{% endblock %} {% endblock %}
{% block extra_css %} {% block extra_css %}
{% include 'bundles/datatables-css.html' %} {% include 'bundles/datatables-css-bs5.html' %}
{% endblock %} {% endblock %}
{% block extra_script %} {% block extra_script %}

View File

@ -1,26 +1,19 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% load evelinks %} {% load evelinks %}
{% load navactive %}
{% block page_title %}{% translate "Group Members" %}{% endblock page_title %} {% block page_title %}{% translate "Group Members" %}{% endblock page_title %}
{% block header_nav_brand %}{% translate "Group Members" %} - {{ group.name }}{% endblock header_nav_brand %}
{% block header_nav_collapse_left %}
<li class="nav-item ">
<a class="nav-link {% navactive request 'groupmanagement:management' %}" href="{% url 'groupmanagement:management' %}">{% translate "Back" %}</a>
</li>
{% endblock %}
{% block content %} {% block content %}
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{{ group.name }} - {% translate 'Members' %}
</div>
<div class="panel-body">
<p>
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
{% translate "Back" %}
</a>
</p>
{% if group.user_set %} {% if group.user_set %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-aa" id="tab_group_members"> <table class="table table-aa" id="tab_group_members">
@ -36,7 +29,7 @@
{% for member in members %} {% for member in members %}
<tr> <tr>
<td> <td>
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;" alt="{{ member.main_char.character_name }}"> <img src="{{ member.main_char|character_portrait_url:32 }}" class="rounded-circle" style="margin-right: 1rem;">
{% if member.main_char %} {% if member.main_char %}
<a href="{{ member.main_char|evewho_character_url }}" target="_blank"> <a href="{{ member.main_char|evewho_character_url }}" target="_blank">
{{ member.main_char.character_name }} {{ member.main_char.character_name }}
@ -46,7 +39,7 @@
{% endif %} {% endif %}
{% if member.is_leader %} {% if member.is_leader %}
<i class="fas fa-star" title="{% translate "Group leader" %}" style="margin-left: 1rem;"></i>&nbsp; <i class="fa-solid fa-star"> title="{% translate "Group leader" %}" style="margin-left: 1rem;"></i>&nbsp;
{% endif %} {% endif %}
</td> </td>
@ -60,10 +53,9 @@
{% translate "(unknown)" %} {% translate "(unknown)" %}
{% endif %} {% endif %}
</td> </td>
<td class="text-end">
<td class="text-right">
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger" title="{% translate "Remove from group" %}"> <a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger" title="{% translate "Remove from group" %}">
<i class="glyphicon glyphicon-remove"></i> <i class="fa-solid fa-xmark"></i>
</a> </a>
</td> </td>
</tr> </tr>
@ -72,7 +64,7 @@
</table> </table>
<p class="text-muted"> <p class="text-muted">
<i class="fas fa-star"></i>: {% translate "Group leader" %} <i class="fa-solid fa-star"></i>: {% translate "Group leader" %}
</p> </p>
</div> </div>
{% else %} {% else %}
@ -80,18 +72,15 @@
{% translate "No group members to list." %} {% translate "No group members to list." %}
</div> </div>
{% endif %} {% endif %}
</div>
</div>
</div>
{% endblock content %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include 'bundles/datatables-js-bs5.html' %}
{% endblock %} {% endblock %}
{% block extra_css %} {% block extra_css %}
{% include 'bundles/datatables-css.html' %} {% include 'bundles/datatables-css-bs5.html' %}
{% endblock %} {% endblock %}
{% block extra_script %} {% block extra_script %}

View File

@ -1,20 +1,20 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% load navactive %}
{% block page_title %}{% translate "Groups Membership" %}{% endblock page_title %} {% block page_title %}{% translate "Groups Membership" %}{% endblock page_title %}
{% block header_nav_brand %}{% translate "Groups Membership" %}{% endblock header_nav_brand %}
{% block extra_css %}{% endblock extra_css %} {% block extra_css %}{% endblock extra_css %}
{% block header_nav_collapse_left %}
<li class="nav-item ">
<a class="nav-link {% navactive request 'groupmanagement:management' %}" href="{% url 'groupmanagement:management' %}">{% translate "Join/Leave Requests" %}</a>
</li>
{% endblock header_nav_collapse_left %}
{% block content %} {% block content %}
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{% translate "Groups" %}
</div>
<div class="panel-body">
{% if groups %} {% if groups %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-aa"> <table class="table table-aa">
@ -23,12 +23,12 @@
<th>{% translate "Name" %}</th> <th>{% translate "Name" %}</th>
<th>{% translate "Description" %}</th> <th>{% translate "Description" %}</th>
<th>{% translate "Status" %}</th> <th>{% translate "Status" %}</th>
<th style="white-space: nowrap;">{% translate "Member Count" %}</th> <th style="white-space: nowrap;" class="text-center">{% translate "Member Count" %}</th>
<th style="min-width: 170px;"></th> <th style="min-width: 170px;"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody class="align-middle">
{% for group in groups %} {% for group in groups %}
<tr> <tr>
<td> <td>
@ -39,29 +39,30 @@
<td> <td>
{% if group.authgroup.hidden %} {% if group.authgroup.hidden %}
<span class="label label-info">{% translate "Hidden" %}</span> <span class="badge bg-info">{% translate "Hidden" %}</span>
{% elif group.authgroup.open %} {% endif %}
<span class="label label-success">{% translate "Open" %}</span> {% if group.authgroup.open %}
<span class="badge bg-success">{% translate "Open" %}</span>
{% else %} {% else %}
<span class="label label-default">{% translate "Requestable" %}</span> <span class="badge bg-secondary">{% translate "Requestable" %}</span>
{% endif %} {% endif %}
</td> </td>
<td class="text-right"> <td class="text-center">
{{ group.num_members }} {{ group.num_members }}
</td> </td>
<td class="text-right"> <td class="text-end">
<a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% translate "View Members" %}"> <a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% translate "View Members" %}">
<i class="glyphicon glyphicon-eye-open"></i> <i class="far fa-eye"></i>
</a> </a>
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% translate "Audit Members" %}"> <a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% translate "Audit Members" %}">
<i class="glyphicon glyphicon-list-alt"></i> <i class="far fa-list-alt"></i>
</a> </a>
<a id="clipboard-copy" data-clipboard-text="{{ SITE_URL }}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% translate "Copy Direct Join Link" %}"> <a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% translate "Copy Direct Join Link" %}">
<i class="glyphicon glyphicon-copy"></i> <i class="far fa-clipboard"></i>
</a> </a>
</td> </td>
</tr> </tr>
@ -74,15 +75,12 @@
{% translate "No groups to list." %} {% translate "No groups to list." %}
</div> </div>
{% endif %} {% endif %}
</div>
</div>
</div>
{% endblock content %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/clipboard-js.html' %} {% include "bundles/clipboard-js.html" %}
<script> <script>
new ClipboardJS('#clipboard-copy'); new ClipboardJS('#clipboard-copy');
</script> </script>
{% endblock %} {% endblock extra_javascript %}

View File

@ -1,29 +1,48 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Available Groups" %}{% endblock page_title %} {% block page_title %}{% translate "Available Groups" %}{% endblock page_title %}
{% block extra_css %}{% endblock extra_css %} {% block header_nav_brand %}{% translate "Available Groups" %}{% endblock header_nav_brand %}
{% if manager_perms %}
{% block header_nav_collapse_left %}
<li class="nav-item">
<a class="nav-link" href="{% url 'groupmanagement:management' %}">{% translate "Group Management" %}
{% if req_count %}
<span class="badge bg-secondary">{{ req_count }}</span>
{% endif %}
</a>
</li>
{% endblock %}
{% endif %}
{% block content %} {% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Available Groups" %}</h1>
{% if groups %} {% if groups %}
<table class="table table-aa"> <table class="table" id="groupsTable" >
<thead> <thead>
<tr> <tr>
<th>{% translate "Name" %}</th> <th>{% translate "Name" %}</th>
<th>{% translate "Description" %}</th> <th>{% translate "Description" %}</th>
<th>{% translate "Leaders" %}<span class="m-1 fw-lighter badge bg-primary">User</span><span class="m-1 fw-lighter badge bg-secondary ">Group</span></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody class>
{% for g in groups %} {% for g in groups %}
<tr> <tr>
<td>{{ g.group.name }}</td> <td>{{ g.group.name }}</td>
<td>{{ g.group.authgroup.description|linebreaks|urlize }}</td> <td>{{ g.group.authgroup.description|linebreaks|urlize }}</td>
<td class="text-right"> <td style="max-width: 30%;">
{% if g.group in user.groups.all %} {% if g.group.authgroup.group_leaders.all.count %}
{% for leader in g.group.authgroup.group_leaders.all %}{% if leader.profile.main_character %}<span class="m-1 badge bg-primary">{{leader.profile.main_character}}</span>{% endif %}{% endfor %}
{% endif %}
{% if g.group.authgroup.group_leaders.all.count %}
{% for group in g.group.authgroup.group_leader_groups.all %}<span class="badge bg-secondary">{{group.name}}</span>{% endfor %}
{% endif %}
</td>
<td class="text-end">
{% if g.group in user_groups %}
{% if not g.request %} {% if not g.request %}
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger"> <a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
{% translate "Leave" %} {% translate "Leave" %}
@ -53,10 +72,25 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
<div class="alert alert-warning text-center"> <div class="alert alert-warning text-center">
{% translate "No groups available." %} {% translate "No groups available." %}
</div> </div>
{% endif %} {% endif %}
</div>
{% endblock content %} {% endblock content %}
{% block extra_javascript %}
{% include 'bundles/datatables-js-bs5.html' %}
{% endblock %}
{% block extra_css %}
{% include 'bundles/datatables-css-bs5.html' %}
{% endblock %}
{% block extra_script %}
$(document).ready(function () {
$('#groupsTable').DataTable();
});
{% endblock extra_script %}

View File

@ -1,51 +1,46 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% load evelinks %} {% load evelinks %}
{% load navactive %}
{% block page_title %}{% translate "Groups Management" %}{% endblock page_title %} {% block page_title %}{% translate "Groups Management" %}{% endblock page_title %}
{% block header_nav_brand %}{% translate "Groups Management" %}{% endblock header_nav_brand %}
{% block extra_css %} {% block extra_css %}
<style>
.nav-tabs > li.active > a {
background-color: rgb(236, 240, 241) !important;
color: rgb(44, 62, 80);
}
</style>
{% endblock extra_css %} {% endblock extra_css %}
{% block content %} {% block header_nav_collapse_left %}
<div class="col-lg-12"> <li class="active">
<br> <a class="nav-link active" id="add-tab" data-bs-toggle="tab" data-bs-target="#add" type="button" role="tab" aria-controls="addd" aria-selected="true">
{% include 'groupmanagement/menu.html' %}
<ul class="nav nav-tabs">
<li class="active">
<a data-toggle="tab" href="#add">
{% translate "Join Requests" %} {% translate "Join Requests" %}
{% if acceptrequests %} {% if acceptrequests %}
<span class="badge">{{ acceptrequests|length }}</span> <span class="badge bg-secondary">{{ acceptrequests|length }}</span>
{% endif %} {% endif %}
</a> </a>
</li> </li>
{% if not auto_leave %} {% if not auto_leave %}
<li> <li>
<a data-toggle="tab" href="#leave"> <a class="nav-link" id="leave-tab" data-bs-toggle="tab" data-bs-target="#leave" type="button" role="tab" aria-controls="leave" aria-selected="false">
{% translate "Leave Requests" %} {% translate "Leave Requests" %}
{% if leaverequests %} {% if leaverequests %}
<span class="badge">{{ leaverequests|length }}</span> <span class="badge bg-secondary">{{ leaverequests|length }}</span>
{% endif %} {% endif %}
</a> </a>
</li> </li>
{% endif %} {% endif %}
</ul> <li class="nav-item ">
<a class="nav-link {% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}" href="{% url 'groupmanagement:membership' %}">{% translate "Group Membership" %}</a>
</li>
<div class="panel panel-default panel-tabs-aa"> {% endblock %}
<div class="panel-body">
<div class="tab-content">
{% block content %}
<div class="tab-content">
<div id="add" class="tab-pane active"> <div id="add" class="tab-pane active">
{% if acceptrequests %} {% if acceptrequests %}
<div class="table-responsive"> <div class="table-responsive">
@ -59,11 +54,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody class="align-middle">
{% for acceptrequest in acceptrequests %} {% for acceptrequest in acceptrequests %}
<tr> <tr>
<td> <td>
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;" alt="{{ acceptrequest.main_char.character_name }}"> <img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="rounded-circle" style="margin-right: 1rem;">
{% if acceptrequest.main_char %} {% if acceptrequest.main_char %}
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank"> <a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
{{ acceptrequest.main_char.character_name }} {{ acceptrequest.main_char.character_name }}
@ -83,7 +78,7 @@
{% endif %} {% endif %}
</td> </td>
<td>{{ acceptrequest.group.name }}</td> <td>{{ acceptrequest.group.name }}</td>
<td class="text-right"> <td class="text-end">
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success"> <a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
{% translate "Accept" %} {% translate "Accept" %}
</a> </a>
@ -116,11 +111,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody class="align-middle">
{% for leaverequest in leaverequests %} {% for leaverequest in leaverequests %}
<tr> <tr>
<td> <td>
<img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;" alt="{{ leaverequest.main_char.character_name }}"> <img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="rounded-circle" style="margin-right: 1rem;">
{% if leaverequest.main_char %} {% if leaverequest.main_char %}
<a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank"> <a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank">
{{ leaverequest.main_char.character_name }} {{ leaverequest.main_char.character_name }}
@ -140,7 +135,7 @@
{% endif %} {% endif %}
</td> </td>
<td>{{ leaverequest.group.name }}</td> <td>{{ leaverequest.group.name }}</td>
<td class="text-right"> <td class="text-end">
<a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success"> <a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success">
{% translate "Accept" %} {% translate "Accept" %}
</a> </a>
@ -159,8 +154,5 @@
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div>
</div>
</div>
{% endblock content %} {% endblock content %}

View File

@ -1,27 +1,10 @@
{% load i18n %} {% load i18n %}
{% load navactive %} {% load navactive %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">{% translate "Toggle navigation" %}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'groupmanagement:management' %}">{% translate "Group Management" %}</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <li class="nav-item ">
<ul class="nav navbar-nav"> <a class="nav-link {% navactive request 'groupmanagement:management' %}" href="{% url 'groupmanagement:management' %}">{% translate "Group Requests" %}</a>
<li class="{% navactive request 'groupmanagement:management' %}"> </li>
<a href="{% url 'groupmanagement:management' %}">{% translate "Group Requests" %}</a> <li class="nav-item ">
</li> <a class="nav-link {% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}" href="{% url 'groupmanagement:membership' %}">{% translate "Group Membership" %}</a>
<li class="{% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}"> </li>
<a href="{% url 'groupmanagement:membership' %}">{% translate "Group Membership" %}</a>
</li>
</ul>
</div>
</div>
</nav>

View File

@ -87,7 +87,7 @@ def group_membership_audit(request, group_id):
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404("Group does not exist") raise Http404("Group does not exist")
render_items = {'group': group.name} render_items = {'group': group}
entries = RequestLog.objects.filter(group=group).order_by('-date') entries = RequestLog.objects.filter(group=group).order_by('-date')
render_items['entries'] = entries render_items['entries'] = entries
@ -311,8 +311,10 @@ def groups_view(request):
groups_qs = GroupManager.get_joinable_groups_for_user( groups_qs = GroupManager.get_joinable_groups_for_user(
request.user, include_hidden=False request.user, include_hidden=False
) )
groups_qs = groups_qs.order_by('name') groups_qs = groups_qs.order_by('name').select_related("authgroup").prefetch_related('authgroup__group_leaders', 'authgroup__group_leaders__profile__main_character', 'authgroup__group_leader_groups')
groups = [] groups = []
## TODO see about making this faster
for group in groups_qs: for group in groups_qs:
group_request = GroupRequest.objects\ group_request = GroupRequest.objects\
.filter(user=request.user)\ .filter(user=request.user)\
@ -322,7 +324,14 @@ def groups_view(request):
'request': group_request[0] if group_request else None 'request': group_request[0] if group_request else None
}) })
context = {'groups': groups} count = 0
perms = GroupManager.can_manage_groups(request.user)
if perms:
count = GroupManager.pending_requests_count_for_user(request.user)
user_groups_list = list(request.user.groups.all())
context = {'groups': groups, "manager_perms": perms, "req_count":count, "user_groups": user_groups_list}
return render(request, 'groupmanagement/groups.html', context=context) return render(request, 'groupmanagement/groups.html', context=context)

View File

@ -91,7 +91,7 @@ def get_app_modules():
def get_app_submodules(module_name): def get_app_submodules(module_name):
""" """pyt
Get a specific sub module of the app Get a specific sub module of the app
:param module_name: module name to get :param module_name: module name to get
:return: name, module tuple :return: name, module tuple
@ -122,3 +122,17 @@ def get_hooks(name):
""" """
register_all_hooks() register_all_hooks()
return _hooks.get(name, []) return _hooks.get(name, [])
class DashboardItemHook:
def __init__(self, view_function, order:int=10):
self.view_function = view_function
self.order = order
def render(self, request):
try:
logger.debug(f"Rendering {self.view_function} to dashboard")
return self.view_function(request)
except Exception as e:
logger.exception("Rendering {self.view_function} Failed!")
return ""

View File

@ -1,7 +1,8 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.menu.hooks import MenuItemHook
from allianceauth.services.hooks import UrlHook
from . import urls from . import urls
from .models import Application from .models import Application

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Choose a Corp" %}{% endblock page_title %} {% block page_title %}{% translate "Choose a Corp" %}{% endblock page_title %}

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %} {% block page_title %}{% translate "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}

View File

@ -8,7 +8,7 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Personal Applications" %} <h1 class="page-header text-center">{% translate "Personal Applications" %}
<div class="text-right"> <div class="text-end">
{% if create %} {% if create %}
<a href="{% url 'hrapplications:create_view' %}"> <a href="{% url 'hrapplications:create_view' %}">
<button type="button" class="btn btn-success">{% translate "Create Application" %}</button> <button type="button" class="btn btn-success">{% translate "Create Application" %}</button>
@ -33,11 +33,11 @@
<td class="text-center">{{ personal_app.form.corp.corporation_name }}</td> <td class="text-center">{{ personal_app.form.corp.corporation_name }}</td>
<td class="text-center"> <td class="text-center">
{% if personal_app.approved == None %} {% if personal_app.approved == None %}
<div class="label label-warning">{% translate "Pending" %}</div> <div class="badge badge-warning">{% translate "Pending" %}</div>
{% elif personal_app.approved == True %} {% elif personal_app.approved == True %}
<div class="label label-success">{% translate "Approved" %}</div> <div class="badge badge-success">{% translate "Approved" %}</div>
{% else %} {% else %}
<div class="label label-danger">{% translate "Rejected" %}</div> <div class="badge badge-danger">{% translate "Rejected" %}</div>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
@ -58,7 +58,7 @@
{% endif %} {% endif %}
{% if perms.auth.human_resources %} {% if perms.auth.human_resources %}
<h1 class="page-header text-center">{% translate "Application Management" %} <h1 class="page-header text-center">{% translate "Application Management" %}
<div class="text-right"> <div class="text-end">
<!-- Button trigger modal --> <!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal"> <button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal">
{% translate "Search Applications" %} {% translate "Search Applications" %}
@ -91,14 +91,14 @@
<td class="text-center"> <td class="text-center">
{% if app.approved == None %} {% if app.approved == None %}
{% if app.reviewer_str %} {% if app.reviewer_str %}
<div class="label label-info">{% translate "Reviewer:" %} {{ app.reviewer_str }}</div> <div class="badge badge-info">{% translate "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %} {% else %}
<div class="label label-warning">{% translate "Pending" %}</div> <div class="badge badge-warning">{% translate "Pending" %}</div>
{% endif %} {% endif %}
{% elif app.approved == True %} {% elif app.approved == True %}
<div class="label label-success">{% translate "Approved" %}</div> <div class="badge badge-success">{% translate "Approved" %}</div>
{% else %} {% else %}
<div class="label label-danger">{% translate "Rejected" %}</div> <div class="badge badge-danger">{% translate "Rejected" %}</div>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
@ -135,14 +135,14 @@
<td class="text-center"> <td class="text-center">
{% if app.approved == None %} {% if app.approved == None %}
{% if app.reviewer_str %} {% if app.reviewer_str %}
<div class="label label-info">{% translate "Reviewer:" %} {{ app.reviewer_str }}</div> <div class="badge badge-info">{% translate "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %} {% else %}
<div class="label label-warning">{% translate "Pending" %}</div> <div class="badge badge-warning">{% translate "Pending" %}</div>
{% endif %} {% endif %}
{% elif app.approved == True %} {% elif app.approved == True %}
<div class="label label-success">{% translate "Approved" %}</div> <div class="badge badge-success">{% translate "Approved" %}</div>
{% else %} {% else %}
<div class="label label-danger">{% translate "Rejected" %}</div> <div class="badge badge-danger">{% translate "Rejected" %}</div>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">

View File

@ -9,7 +9,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
{% if perms.auth.human_resources %} {% if perms.auth.human_resources %}
<h1 class="page-header text-center">{% translate "Application Search Results" %} <h1 class="page-header text-center">{% translate "Application Search Results" %}
<div class="text-right"> <div class="text-end">
<!-- Button trigger modal --> <!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal"> <button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal">
{% translate "Search Applications" %} {% translate "Search Applications" %}
@ -34,11 +34,11 @@
<td class="text-center">{{ app.form.corp }}</td> <td class="text-center">{{ app.form.corp }}</td>
<td class="text-center"> <td class="text-center">
{% if app.approved == None %} {% if app.approved == None %}
<div class="label label-warning">{% translate "Pending" %}</div> <div class="badge badge-warning">{% translate "Pending" %}</div>
{% elif app.approved == True %} {% elif app.approved == True %}
<div class="label label-success">{% translate "Approved" %}</div> <div class="badge badge-success">{% translate "Approved" %}</div>
{% else %} {% else %}
<div class="label label-danger">{% translate "Rejected" %}</div> <div class="badge badge-danger">{% translate "Rejected" %}</div>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">

View File

View File

@ -0,0 +1,9 @@
from django.contrib import admin
from . import models
@admin.register(models.MenuItem)
class MenuItemAdmin(admin.ModelAdmin):
list_display = ['text', 'hide', 'parent', 'url', 'icon_classes', 'rank']
ordering = ('rank',)

19
allianceauth/menu/apps.py Normal file
View File

@ -0,0 +1,19 @@
import logging
from django.apps import AppConfig
from django.db.utils import ProgrammingError, OperationalError
logger = logging.getLogger(__name__)
class MenuConfig(AppConfig):
name = "allianceauth.menu"
label = "menu"
def ready(self):
try:
logger.debug("Syncing MenuItem Hooks")
from allianceauth.menu.providers import MenuItem
MenuItem.sync_hook_models()
except (ProgrammingError, OperationalError):
logger.warning("Migrations not completed for MenuItems")

View File

@ -0,0 +1,42 @@
from django.template.loader import render_to_string
from typing import List, Optional
class MenuItemHook:
"""
Auth Hook for generating Side Menu Items
"""
def __init__(self, text: str, classes: List[str], url_name: str, order: Optional[int] = None, navactive: List = list([])):
"""
:param text: The text shown as menu item, e.g. usually the name of the app.
:type text: str
:param classes: The classes that should be applied to the menu item icon
:type classes: List[str]
:param url_name: The name of the Django URL to use
:type url_name: str
:param order: An integer which specifies the order of the menu item, lowest to highest. Community apps are free to use any order above `1000`. Numbers below are served for Auth.
:type order: Optional[int], optional
:param navactive: A list of views or namespaces the link should be highlighted on. See [django-navhelper](https://github.com/geelweb/django-navhelper#navactive) for usage. Defaults to the supplied `url_name`.
:type navactive: List, optional
"""
self.text = text
self.classes = classes
self.url_name = url_name
self.template = 'public/menuitem.html'
self.order = order if order is not None else 9999
# count is an integer shown next to the menu item as badge when count != None
# apps need to set the count in their child class, e.g. in render() method
self.count = None
navactive = navactive or []
navactive.append(url_name)
self.navactive = navactive
def render(self, request):
return render_to_string(self.template,
{'item': self},
request=request)

View File

@ -0,0 +1,28 @@
# Generated by Django 4.0.2 on 2022-08-28 14:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='MenuItem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hook_function', models.CharField(max_length=500)),
('icon_classes', models.CharField(max_length=150)),
('text', models.CharField(max_length=150)),
('url', models.CharField(blank=True, default=None, max_length=2048, null=True)),
('rank', models.IntegerField(default=1000)),
('hide', models.BooleanField(default=False)),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='menu.menuitem')),
],
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 4.0.2 on 2022-08-28 14:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('menu', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='menuitem',
name='hook_function',
field=models.CharField(blank=True, default=None, max_length=500, null=True),
),
migrations.AlterField(
model_name='menuitem',
name='icon_classes',
field=models.CharField(blank=True, default=None, max_length=150, null=True),
),
migrations.AlterField(
model_name='menuitem',
name='text',
field=models.CharField(blank=True, default=None, max_length=150, null=True),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.0.8 on 2023-02-05 07:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('menu', '0002_alter_menuitem_hook_function_and_more'),
]
operations = [
migrations.AddIndex(
model_name='menuitem',
index=models.Index(fields=['rank'], name='menu_menuit_rank_e880ab_idx'),
),
]

View File

@ -0,0 +1,39 @@
# Generated by Django 4.0.10 on 2023-07-16 11:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('menu', '0003_menuitem_menu_menuit_rank_e880ab_idx'),
]
operations = [
migrations.AlterField(
model_name='menuitem',
name='hide',
field=models.BooleanField(default=False, help_text='Hide this menu item. If this item is a header all items under it will be hidden too.'),
),
migrations.AlterField(
model_name='menuitem',
name='icon_classes',
field=models.CharField(blank=True, default=None, help_text='Font Awesome classes to show as icon on menu', max_length=150, null=True),
),
migrations.AlterField(
model_name='menuitem',
name='parent',
field=models.ForeignKey(blank=True, help_text='Parent Header. (Optional)', null=True, on_delete=django.db.models.deletion.SET_NULL, to='menu.menuitem'),
),
migrations.AlterField(
model_name='menuitem',
name='rank',
field=models.IntegerField(default=1000, help_text='Order of the menu. Lowest First.'),
),
migrations.AlterField(
model_name='menuitem',
name='text',
field=models.CharField(blank=True, default=None, help_text='Text to show on menu', max_length=150, null=True),
),
]

View File

174
allianceauth/menu/models.py Normal file
View File

@ -0,0 +1,174 @@
import logging
from allianceauth.hooks import get_hooks
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.template.loader import render_to_string
logger = logging.getLogger(__name__)
class MenuItem(models.Model):
# Auto Generated model from an auth_hook
hook_function = models.CharField(
max_length=500, default=None, null=True, blank=True)
# User Made Model
icon_classes = models.CharField(
max_length=150, default=None, null=True, blank=True, help_text="Font Awesome classes to show as icon on menu")
text = models.CharField(
max_length=150, default=None, null=True, blank=True, help_text="Text to show on menu")
url = models.CharField(max_length=2048, default=None,
null=True, blank=True)
# Put it under a header?
parent = models.ForeignKey(
'self', on_delete=models.SET_NULL, null=True, blank=True, help_text="Parent Header. (Optional)")
# Put it where? lowest first
rank = models.IntegerField(default=1000, help_text="Order of the menu. Lowest First.")
# Hide it fully? Hiding a parent will hide all it's children
hide = models.BooleanField(default=False, help_text="Hide this menu item. If this item is a header all items under it will be hidden too.")
class Meta:
indexes = [
models.Index(fields=['rank', ]),
]
def __str__(self) -> str:
return self.text
@property
def classes(self): # Helper function to make this model closer to the hook functions
return self.icon_classes
@staticmethod
def hook_to_name(mh):
return f"{mh.__class__.__module__}.{mh.__class__.__name__}"
@staticmethod
def sync_hook_models():
# TODO define aa way for hooks to predefine a "parent" to create a sub menu from modules
menu_hooks = get_hooks('menu_item_hook')
hook_functions = []
for hook in menu_hooks:
mh = hook()
cls = MenuItem.hook_to_name(mh)
try:
# if it exists update the text only
# Users can adjust ranks so lets not change it if they have.
mi = MenuItem.objects.get(hook_function=cls)
mi.text = getattr(mh, "text", mh.__class__.__name__)
mi.save()
except MenuItem.DoesNotExist:
# This is a new hook, Make the database model.
MenuItem.objects.create(
hook_function=cls,
rank=getattr(mh, "order", 500),
text=getattr(mh, "text", mh.__class__.__name__)
)
hook_functions.append(cls)
# Get rid of any legacy hooks from modules removed
MenuItem.objects.filter(hook_function__isnull=False).exclude(
hook_function__in=hook_functions).delete()
@classmethod
def filter_items(cls, menu_item: dict):
"""
filter any items with no valid children from a menu
"""
count_items = len(menu_item['items'])
if count_items: # if we have children confirm we can see them
for i in menu_item['items']:
if len(i['render']) == 0:
count_items -= 1
if count_items == 0: # no children left dont render header
return False
return True
else:
return True
@classmethod
def render_menu(cls, request):
"""
Return the sorted side menu items with any items the user can't see removed.
"""
# Override all the items to the bs5 theme
template = "menu/menu-item-bs5.html"
# TODO discuss permissions for user defined links
# Turn all the hooks into functions
menu_hooks = get_hooks('menu_item_hook')
items = {}
for fn in menu_hooks:
f = fn()
items[cls.hook_to_name(f)] = f
menu_items = MenuItem.objects.all().order_by("rank")
menu = {}
for mi in menu_items:
if mi.hide:
# hidden item, skip it completely
continue
try:
_cnt = 0
_render = None
if mi.hook_function:
# This is a module hook, so we need to render it as the developer intended
# TODO add a new attribute for apps that want to override it in the new theme
items[mi.hook_function].template = template
_render = items[mi.hook_function].render(request)
_cnt = items[mi.hook_function].count
else:
# This is a user defined menu item so we render it with defaults.
_render = render_to_string(template,
{'item': mi},
request=request)
parent = mi.id
if mi.parent_id: # Set it if present
parent = mi.parent_id
if parent not in menu: # this will cause the menu headers to be out of order
menu[parent] = {"items": [],
"count": 0,
"render": None,
"text": "None",
"rank": 9999,
}
_mi = {
"count": _cnt,
"render": _render,
"text": mi.text,
"rank": mi.rank,
"classes": (mi.icon_classes if mi.icon_classes != "" else "fas fa-folder"),
"hide": mi.hide
}
if parent != mi.id:
# this is a sub item
menu[parent]["items"].append(_mi)
if _cnt:
#add its count to the header count
menu[parent]["count"] += _cnt
else:
if len(menu[parent]["items"]):
# this is a top folder dont update the count.
del(_mi["count"])
menu[parent].update(_mi)
except Exception as e:
logger.exception(e)
# reset to list
menu = list(menu.values())
# sort the menu list as the parents may be out of order.
menu.sort(key=lambda i: i['rank'])
# ensure no empty groups
menu = filter(cls.filter_items, menu)
return menu

View File

@ -0,0 +1,10 @@
from django.template.loader import render_to_string
from allianceauth.hooks import get_hooks
from .models import MenuItem
class MenuProvider():
def __init__(self) -> None:
pass

View File

@ -0,0 +1,7 @@
{% for data in menu_items %}
{% if data.items|length > 0 %}
{% include "menu/menu-item-bs5.html" with item=data %}
{% else %}
{{ data.render }}
{% endif %}
{% endfor %}

View File

@ -0,0 +1,32 @@
{% load i18n %}
{% load navactive %}
{% if not item.hide %}
<li class="d-flex flex-wrap m-2 p-2 pt-0 pb-0 mt-0 mb-0 me-0 pe-0">
<i class="nav-link {{ item.classes }} fa-fw align-self-center me-3 {% if item.navactive %}{% navactive request item.navactive|join:' ' %}{% endif %}" {% if item.items|length %} type="button" data-bs-toggle="collapse" data-bs-target="#id-{{ item.text|slugify }}" aria-expanded="false" aria-controls="" {% endif %}></i>
<a class="nav-link flex-fill align-self-center" {% if item.items|length %} type="button" data-bs-toggle="collapse" data-bs-target="#id-{{ item.text|slugify }}" aria-expanded="false" aria-controls="" {% endif %}
href="{% if item.url_name %}{% url item.url_name %}{% else %}{{ item.url }}{% endif %}">
{% translate item.text %}
</a>
{% if item.count >= 1 %}
<span class="badge bg-primary rounded-pill m-2 align-self-center {% if item.items|length == 0 %}me-4{% endif %}">
{{ item.count }}
</span>
{% elif item.url %}
<span class="pill m-2 me-4 align-self-center fas fa-external-link-alt"></span>
{% endif %}
{% if item.items|length > 0 %}
<span class="pill m-2 me-4 align-self-center fas fa-solid fa-chevron-down"
type="button"
data-bs-toggle="collapse"
data-bs-target="#id-{{ item.text|slugify }}"
aria-expanded="false"
aria-controls=""></span>
<!--<hr class="m-0 w-100">-->
<ul class="collapse ps-1 w-100 border-start rounded-start border-light border-3" id="id-{{ item.text|slugify }}">
{% for sub_item in item.items %}
{{ sub_item.render }}
{% endfor %}
</ul>
{% endif %}
</li>
{% endif %}

View File

@ -0,0 +1,19 @@
{% load i18n %}
{% load navactive %}
{% load auth_notifications %}
<li class="nav-item {% navactive request 'notifications:' %}"
id="menu_item_notifications">
<a class="nav-link"
href="{% url 'notifications:list' %}">
<span class="fa">
{% with unread_count=request.user|user_unread_notification_count %}
<i
class="fas fa-bell{% if unread_count %} text-danger{% endif %}"
></i>
{% endwith %}
</span>
<span class="d-lg-none d-md-inline m-2">
{% translate "Notifications" %}
</span>
</a>
</li>

View File

@ -0,0 +1,51 @@
{% load i18n %}
{% load evelinks %}
{% load theme_tags %}
<div style="z-index:5;" class="w100 d-flex flex-column justify-content-center align-items-center text-center pb-2">
{% if request.user.profile.main_character %}
{% with request.user.profile.main_character as main %}
<div class="p-2 position-relative m-2">
<img class="rounded-circle" src="{{ main.character_id|character_portrait_url:64 }}" alt="{{ main.character_name }}"/>
<img class="rounded-circle position-absolute bottom-0 start-0" src="{{ main.corporation_logo_url_32 }}" alt="{{ main.corporation_name }}"/>
{% if main.alliance_id %}
<img class="rounded-circle position-absolute bottom-0 end-0" src="{{ main.alliance_logo_url_32 }}" alt="{{ main.alliance_name }}"/>
{% elif main.faction_id %}
<img class="rounded-circle position-absolute bottom-0 end-0" src="{{ main.faction_logo_url_32 }}" alt="{{ main.faction_name }}"/>
{% endif %}
</div>
<h5>{{ main.character_name }}</h5>
{% endwith %}
{% else %}
<img class="rounded-circle m-2" src="{{ 1|character_portrait_url:32 }}" alt="{% translate 'No Main Character!' %}"/>
<h5>{% translate "No Main Character!" %}</h5>
{% endif %}
{% if user.is_authenticated %}
{% theme_select %}
{% endif %}
<div class="btn-group m-2">
<button type="button" class="btn btn-secondary p-1">
{% include "public/lang_select.html" %}
</button>
{% if user.is_superuser %}
<a role="button" class="btn btn btn-secondary d-flex"
href="{% url 'admin:index' %}"
bs-data-toggle="button">
<span class="align-self-center">{% translate "Admin" %}</span>
</a>
{% endif %}
</div>
<div class="btn-group m-2">
<a role="button" class="btn btn-info" href="{% url 'authentication:token_management' %}" alt="Token Management"><i class="fa-solid fa-user-lock fa-fw"></i></a>
{% if user.is_superuser %}
<a role="button" class="btn btn-info" href="https://allianceauth.readthedocs.io/" alt="Alliance Auth Documentation"><i class="fa-solid fa-book fa-fw"></i></a>
<a role="button" class="btn btn-info" href="https://discord.gg/fjnHAmk" alt="Alliance Auth Discord"><i class="fa-brands fa-discord fa-fw"></i></a>
<a role="button" class="btn btn-info" href="https://gitlab.com/allianceauth/allianceauth" alt="Alliance Auth Git"><i class="fa-brands fa-gitlab fa-fw"></i></a>
{% endif %}
{% if user.is_authenticated %}
<a role="button" class="btn btn-danger" href="{% url 'logout' %}" alt="{% translate 'Sign Out' %}"><i class="fa-solid fa-right-from-bracket fa-fw"></i></a>
{% else %}
<a role="button" class="btn btn-success" href="{% url 'authentication:login' %}" alt="{% translate 'Sign In' %}"> <i class="fa-solid fa-right-to-bracket fa-fw"></i></a>
{% endif %}
</div>
</div>

View File

@ -0,0 +1,21 @@
{% load i18n %}
{% load navactive %}
{% load menu_items %}
<div class="col-auto px-0 " >
<div class="collapse collapse-horizontal" tabindex="-1" id="sidebar" >
<div style="width: 350px;">
<div class="nav-padding navbar-dark bg-dark text-light px-0 d-flex flex-column overflow-hidden vh-100 auth-logo" >
<ul style="z-index:5;" id="sidebar-menu" class="navbar-nav flex-column mb-auto overflow-auto pt-2">
<li class="d-flex flex-wrap m-2 p-2 pt-0 pb-0 mt-0 mb-0 me-0 pe-0">
<i class="nav-link fas fa-tachometer-alt fa-fw align-self-center me-3 {% navactive request 'authentication:dashboard' %}"></i>
<a class="nav-link flex-fill align-self-center" href="{% url 'authentication:dashboard' %}">
{% translate "Dashboard" %}
</a>
</li>
{% sorted_menu_items %}
</ul>
{% include 'menu/menu-user.html' %}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
from django import template
from allianceauth.hooks import get_hooks
from allianceauth.menu.models import MenuItem
from ..providers import MenuProvider
register = template.Library()
def process_menu_items(hooks, request):
_menu_items = list()
items = [fn() for fn in hooks]
items.sort(key=lambda i: i.order)
for item in items:
_menu_items.append(item.render(request))
return _menu_items
@register.inclusion_tag('public/menublock.html', takes_context=True)
def menu_items(context):
request = context['request']
return {
'menu_items': process_menu_items(get_hooks('menu_item_hook'), request),
}
@register.inclusion_tag('menu/menu-block.html', takes_context=True)
def sorted_menu_items(context):
request = context['request']
manu_items = MenuItem.render_menu(request)
return {
'menu_items':manu_items
}

View File

@ -1,37 +1,47 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Notifications" %}{% endblock %} {% block page_title %}
{% translate "Notifications" %}
{% endblock page_title %}
{% block header_nav_brand %}
{% translate "Notifications" %}
{% endblock header_nav_brand %}
{% block header_nav_collapse_left %}
<li class="nav-item">
<a class="nav-link active" id="unread-tab" data-bs-toggle="tab" data-bs-target="#unread" type="button" role="tab" aria-controls="unread" aria-selected="true">
{% translate "Unread" %}
<span class="badge bg-secondary">{{ unread|length }}</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" id="read-tab" data-bs-toggle="tab" data-bs-target="#read" type="button" role="tab" aria-controls="read" aria-selected="false">
{% translate "Read" %}
<span class="badge bg-secondary">{{ read|length }}</span>
</a>
</li>
{% endblock %}
{% block header_nav_collapse_right %}
<li class="nav-item">
<a href="{% url 'notifications:mark_all_read' %}" class="nav-link">
<i class="fas fa-check-double"></i>
</a>
</li>
<li class="nav-item">
<a href="{% url 'notifications:delete_all_read' %}" class="nav-link">
<i class="fas fa-trash"></i>
</a>
</li>
{% endblock %}
{% block content %} {% block content %}
<h1 class="page-header text-center">{% translate "Notifications" %}</h1>
<div class="panel panel-default">
<div class="panel-heading clearfix">
<ul class="nav nav-pills navbar-left">
<li class="active"><a data-toggle="tab" href="#unread">{% translate "Unread" %}<b>({{ unread|length }})</b></a></li>
<li><a data-toggle="tab" href="#read">{% translate "Read" %} <b>({{ read|length }})</b></a></li>
</ul>
<div class="nav navbar-nav navbar-right" style="margin-right: 0;">
<a href="{% url 'notifications:mark_all_read' %}" class="btn btn-warning">{% translate "Mark All Read" %}</a>
<a href="{% url 'notifications:delete_all_read' %}" class="btn btn-danger">{% translate "Delete All Read" %}</a>
</div>
</div>
<div class="panel-body">
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="unread">
<div id="unread" class="tab-pane fade in active">
{% include "notifications/list_partial.html" with notifications=unread %} {% include "notifications/list_partial.html" with notifications=unread %}
</div> </div>
<div id="read" class="tab-pane fade"> <div id="read" class="tab-pane fade">
{% include "notifications/list_partial.html" with notifications=read %} {% include "notifications/list_partial.html" with notifications=read %}
</div> </div>
</div>
</div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,8 +1,7 @@
{% load i18n %} {% load i18n %}
{% if notifications %} {% if notifications %}
<div class="table-responsive"> <table class="table table-striped">
<table class="table table-condensed table-hover table-striped">
<tr> <tr>
<th class="text-center">{% translate "Timestamp" %}</th> <th class="text-center">{% translate "Timestamp" %}</th>
<th class="text-center">{% translate "Title" %}</th> <th class="text-center">{% translate "Title" %}</th>
@ -14,16 +13,15 @@
<td class="text-center">{{ notif.title }}</td> <td class="text-center">{{ notif.title }}</td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'notifications:view' notif.id %}" class="btn btn-primary" title="View"> <a href="{% url 'notifications:view' notif.id %}" class="btn btn-primary" title="View">
<span class="glyphicon glyphicon-eye-open"></span> <span class="fas fa-eye"></span>
</a> </a>
<a href="{% url 'notifications:remove' notif.id %}" class="btn btn-danger" title="Remove"> <a href="{% url 'notifications:remove' notif.id %}" class="btn btn-danger" title="Remove">
<span class="glyphicon glyphicon-remove"></span> <span class="fas fa-trash"></span>
</a> </a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
{% else %} {% else %}
<div class="alert alert-default text-center">{% translate "No notifications." %}</div> <div class="alert alert-default text-center">{% translate "No notifications." %}</div>
{% endif %} {% endif %}

View File

@ -6,7 +6,7 @@
{% block content %} {% block content %}
<h1 class="page-header text-center"> <h1 class="page-header text-center">
{% translate "View Notification" %} {% translate "View Notification" %}
<div class="text-right"> <div class="text-end">
<a href="{% url 'notifications:list' %}" class="btn btn-primary btn-lg"> <a href="{% url 'notifications:list' %}" class="btn btn-primary btn-lg">
<span class="glyphicon glyphicon-arrow-left"></span> <span class="glyphicon glyphicon-arrow-left"></span>
</a> </a>

View File

@ -1,4 +1,6 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.menu.hooks import MenuItemHook
from allianceauth.optimer.views import dashboard_ops
from allianceauth.services.hooks import UrlHook
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from . import urls from . import urls
@ -27,3 +29,17 @@ def register_menu():
@hooks.register('url_hook') @hooks.register('url_hook')
def register_url(): def register_url():
return UrlHook(urls, 'optimer', r'^optimer/') return UrlHook(urls, 'optimer', r'^optimer/')
class NextOpsHook(hooks.DashboardItemHook):
def __init__(self): #TODO add the view permms so if they cant see it is not rendered
hooks.DashboardItemHook.__init__(
self,
dashboard_ops,
6
)
@hooks.register('dashboard_hook')
def register_groups_hook():
return NextOpsHook()

View File

@ -0,0 +1,38 @@
{% load i18n %}
{% load evelinks %}
<div class="col-12 col-xl-6 align-self-stretch p-2">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title text-center">{% translate "Upcoming Fleets" %}</h4>
<div class="card-body">
<div style="height: 300px;overflow:-moz-scrollbars-vertical;overflow-y:auto;">
<table class="table" style="--bs-table-bg: transparent;">
<thead>
<th class="text-center">{% translate "Operation" %}</th>
<th class="text-center">{% translate "Type" %}</th>
<th class="text-center">{% translate "Form Up System" %}</th>
<th class="text-center">{% translate "Start Time" %}</th>
</thead>
<tbody>
{% for ops in timers %}
<tr>
<td class="text-center">
{{ ops.operation_name }}
</td>
<td class="text-center">
({{ ops.type }})
</td>
<td class="text-center">
<a href="{{ ops.system|dotlan_solar_system_url }}">{{ ops.system }}</a>
</td>
<td class="text-center" nowrap>{{ ops.start | date:"Y-m-d H:i" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -16,7 +16,7 @@
<th>{% translate "FC" %}</th> <th>{% translate "FC" %}</th>
{% if perms.auth.optimer_management %} {% if perms.auth.optimer_management %}
{# <th>{% translate "Creator" %}</th>#} {# <th>{% translate "Creator" %}</th>#}
<th class="text-right" style="width: 150px;">{% translate "Action" %}</th> <th class="text-end" style="width: 150px;">{% translate "Action" %}</th>
{% endif %} {% endif %}
</tr> </tr>
</thead> </thead>
@ -40,7 +40,7 @@
<td>{{ ops.fc }}</td> <td>{{ ops.fc }}</td>
{% if perms.auth.optimer_management %} {% if perms.auth.optimer_management %}
{# <td>{{ ops.eve_character }}</td>#} {# <td>{{ ops.eve_character }}</td>#}
<td class="text-right"> <td class="text-end">
<a href="{% url 'optimer:remove' ops.id %}" class="btn btn-danger"> <a href="{% url 'optimer:remove' ops.id %}" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a> </a>

View File

@ -8,7 +8,7 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">{% translate "Fleet Operation Timers" %} <h1 class="page-header text-center">{% translate "Fleet Operation Timers" %}
<div class="text-right"> <div class="text-end">
{% if perms.auth.optimer_management %} {% if perms.auth.optimer_management %}
<a href="{% url 'optimer:add' %}" class="btn btn-success">{% translate "Create Operation" %}</a> <a href="{% url 'optimer:add' %}" class="btn btn-success">{% translate "Create Operation" %}</a>
{% endif %} {% endif %}
@ -16,10 +16,10 @@
</h1> </h1>
<div class="col-lg-12 text-center row"> <div class="col-lg-12 text-center row">
<div class="label label-info text-left"> <div class="badge badge-info text-start">
<b>{% translate "Current Eve Time:" %} </b> <b>{% translate "Current Eve Time:" %} </b>
</div> </div>
<strong class="label label-info text-left" id="current-time"></strong> <strong class="badge badge-info text-start" id="current-time"></strong>
<br> <br>
</div> </div>

View File

@ -5,10 +5,11 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.template.loader import render_to_string
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .form import OpForm
from .form import OpForm
from .models import OpTimer, OpTimerType from .models import OpTimer, OpTimerType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -137,3 +138,15 @@ def edit_optimer(request, optimer_id):
} }
form = OpForm(initial=data, data_list=OpTimerType.objects.all()) form = OpForm(initial=data, data_list=OpTimerType.objects.all())
return render(request, 'optimer/update.html', context={'form': form}) return render(request, 'optimer/update.html', context={'form': form})
def dashboard_ops(request):
base_query = OpTimer.objects.select_related('eve_character', 'type')
timers = base_query.filter(start__gte=timezone.now())[:5]
if timers.count():
context = {
'timers': timers,
}
return render_to_string('optimer/dashboard.ops.html', context=context, request=request)
else:
return ""

View File

@ -1,7 +1,8 @@
from allianceauth.menu.hooks import MenuItemHook
from . import urls from . import urls
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import UrlHook
class PermissionsTool(MenuItemHook): class PermissionsTool(MenuItemHook):

View File

@ -1,39 +1,39 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{{ permission.permission.codename }} - {% translate "Permissions Audit" %}{% endblock page_title %} {{ permission.permission.codename }} - {% translate "Permissions Audit" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div> <div>
<h1 class="page-header">{% translate "Permissions Audit" %}: {{ permission.permission.codename }}</h1> <h1 class="page-header">{% translate "Permissions Audit" %}: {{ permission.permission.codename }}</h1>
<p> <p>
<a href="{% url 'permissions_tool:overview' %}" class="btn btn-default"> <a href="{% url 'permissions_tool:overview' %}" class="btn btn-primary">
<i class="glyphicon glyphicon-chevron-left"></i> {% translate "Back" %} <i class="fa-solid fa-chevron-left"></i> {% translate "Back" %}
</a> </a>
</p> </p>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped" id="tab_permissions_audit"> <table class="table table-striped" id="tab_permissions_audit">
<thead> <thead>
<tr> <tr>
<th>{% translate "Group" %}</th> <th scope="col">{% translate "Group" %}</th>
<th></th> <th scope="col"></th>
<th>{% translate "User / Character" %}</th> <th scope="col">{% translate "User / Character" %}</th>
<th>{% translate "Organization" %}</th> <th scope="col">{% translate "Organization" %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in permission.users %} {% for user in permission.users %}
{% include 'permissions_tool/audit_row.html' with type="User" name="Permission granted directlty" %} {% include "permissions_tool/audit_row.html" with type="User" name="Permission granted directly" %}
{% endfor %} {% endfor %}
{% for group in permission.groups %} {% for group in permission.groups %}
{% for user in group.user_set.all %} {% for user in group.user_set.all %}
{% include 'permissions_tool/audit_row.html' with type="Group" name=group%} {% include "permissions_tool/audit_row.html" with type="Group" name=group %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% for state in permission.states %} {% for state in permission.states %}
{% for profile in state.userprofile_set.all %} {% for profile in state.userprofile_set.all %}
{% with profile.user as user %} {% with profile.user as user %}
{% include 'permissions_tool/audit_row.html' with type="State" name=state%} {% include "permissions_tool/audit_row.html" with type="State" name=state %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
@ -42,52 +42,54 @@
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include "bundles/datatables-js-bs5.html" %}
{% include 'bundles/filterdropdown-js.html' %} {% include "bundles/filterdropdown-js.html" %}
{% endblock %} {% endblock extra_javascript %}
{% block extra_css %} {% block extra_css %}
{% include 'bundles/datatables-css.html' %} {% include "bundles/datatables-css-bs5.html" %}
{% endblock %} {% endblock extra_css %}
{% block extra_script %} {% block extra_script %}
$(document).ready(function() { $(document).ready(function () {
let groupColumn = 0; let groupColumn = 0;
$('#tab_permissions_audit').DataTable({ $('#tab_permissions_audit').DataTable({
columnDefs: [ columnDefs: [{
{ "visible": false, "targets": groupColumn } "visible": false,
"targets": groupColumn
}],
order: [
[groupColumn, 'asc'],
[2, 'asc']
], ],
order: [[ groupColumn, 'asc' ], [ 2, 'asc' ] ], filterDropDown: {
filterDropDown: columns: [{
{
columns: [
{
idx: 0, idx: 0,
title: 'Source' title: 'Source'
} }],
],
bootstrap: true bootstrap: true
}, },
"stateSave": true, "stateSave": true,
"stateDuration": 0, "stateDuration": 0,
drawCallback: function ( settings ) { drawCallback: function (settings) {
let api = this.api(); let api = this.api();
let rows = api.rows( {page:'current'} ).nodes(); let rows = api.rows({
page: 'current'
}).nodes();
let last = null; let last = null;
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) { api.column(groupColumn, {
if ( last !== group ) { page: 'current'
$(rows).eq( i ).before( }).data().each(function (group, i) {
'<tr class="tr-group"><td colspan="3">' + group + '</td></tr>' if (last !== group) {
$(rows).eq(i).before(
'<tr class="h4 table-secondary"><td colspan="3">' + group + '</td></tr>'
); );
last = group; last = group;
} }
} ); });
} }
} ); });
} ); });
{% endblock %} {% endblock extra_script %}

View File

@ -1,25 +1,17 @@
{% load evelinks %} {% load evelinks %}
{% load i18n %}
<tr> <tr>
<td> <td>{{ type }}: {{ name }}</td>
{{ type }}: {{ name }} <td class="text-end">
</td> <img src="{{ user.profile.main_character|character_portrait_url:32 }}" class="img-circle" alt="{{ user.profile.main_character.character_name }}"/></td>
<td class="text-right"> <td><strong>{{ user }}<br/></strong>{{ user.profile.main_character.character_name }}</td>
<img src="{{ user.profile.main_character|character_portrait_url:32 }}" class="img-circle" alt="{{ user.profile.main_character.character_name }}"> <td class="text-start">
</td>
<td>
<strong>{{ user }}<br></strong>
{{ user.profile.main_character.character_name }}
</td>
<td class="text-left">
{% if user.profile.main_character %} {% if user.profile.main_character %}
<a href="{{ user.profile.main_character|dotlan_corporation_url }}" target="_blank"> <a href="{{ user.profile.main_character|dotlan_corporation_url }}" target="_blank">{{ user.profile.main_character.corporation_name }}</a>
{{ user.profile.main_character.corporation_name }} <br/>
</a><br>
{{ user.profile.main_character.alliance_name|default_if_none:"" }} {{ user.profile.main_character.alliance_name|default_if_none:"" }}
{% else %} {% else %}
(unknown) {% translate "(unknown)" %}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@ -1,73 +1,47 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}
{% block page_title %}{% translate "Permissions Overview" %}{% endblock page_title %} {% translate "Permissions Overview" %}
{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-sm-12"> <div class="col-sm-12">
<h1 class="page-header">{% translate "Permissions Overview" %}</h1> <h1 class="page-header">{% translate "Permissions Overview" %}</h1>
<p> <p>
{% if request.GET.all != 'yes' %} {% if request.GET.all != 'yes' %}
{% blocktranslate %}Showing only applied permissions{% endblocktranslate %} {% translate "Showing only applied permissions" %}
<a href="{% url 'permissions_tool:overview' %}?all=yes" class="btn btn-primary">{% translate "Show All" %}</a> <a href="{% url 'permissions_tool:overview' %}?all=yes" class="btn btn-primary">{% translate "Show All" %}</a>
{% else %} {% else %}
{% blocktranslate %}Showing all permissions{% endblocktranslate %} {% translate "Showing all permissions" %}
<a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% translate "Show Applied" %}</a> <a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% translate "Show Applied" %}</a>
{% endif %} {% endif %}
</p> </p>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped" id="tab_permissions_overview" style="width:100%"> <table class="table table-striped" id="tab_permissions_overview">
<thead> <thead>
<tr> <tr>
<th> <th scope="col">{% translate "App" %}</th>
{% translate "App" %} <th scope="col">{% translate "Model" %}</th>
</th> <th scope="col">{% translate "Code Name" %}</th>
<th> <th scope="col">{% translate "Name" %}</th>
{% translate "Model" %} <th scope="col">{% translate "Users" %}</th>
</th> <th scope="col">{% translate "Groups" %}</th>
<th> <th scope="col">{% translate "States" %}</th>
{% translate "Code Name" %}
</th>
<th>
{% translate "Name" %}
</th>
<th class="col-md-1">
{% translate "Users" %}
</th>
<th class="col-md-1">
{% translate "Groups" %}
</th>
<th class="col-md-1">
{% translate "States" %}
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for perm in permissions %} {% for perm in permissions %}
<tr> <tr>
<td> <td>{{ perm.permission.content_type.app_label }}</td>
{{ perm.permission.content_type.app_label }} <td>{{ perm.permission.content_type.model }}</td>
</td>
<td>
{{ perm.permission.content_type.model }}
</td>
<td> <td>
<a href="{% url "permissions_tool:audit" app_label=perm.permission.content_type.app_label model=perm.permission.content_type.model codename=perm.permission.codename %}"> <a href="{% url "permissions_tool:audit" app_label=perm.permission.content_type.app_label model=perm.permission.content_type.model codename=perm.permission.codename %}">
{{ perm.permission.codename }} {{ perm.permission.codename }}
</a> </a>
</td> </td>
<td> <td>{{ perm.permission.name }}</td>
{{ perm.permission.name }} <td class="{% if perm.users > 0 %}info{% endif %}text-end">{{ perm.users }}</td>
</td> <td class="{% if perm.groups > 0 %}info{% endif %}text-end">{{ perm.groups }} ({{ perm.group_users }})</td>
<td class="{% if perm.users > 0 %}info {% endif %}text-right"> <td class="{% if perm.states > 0 %}info{% endif %}text-end">{{ perm.states }} ({{ perm.state_users }})</td>
{{ perm.users }}
</td>
<td class="{% if perm.groups > 0 %}info {% endif %}text-right">
{{ perm.groups }} ({{ perm.group_users }})
</td>
<td class="{% if perm.states > 0 %}info {% endif %}text-right">
{{ perm.states }} ({{ perm.state_users }})
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -75,29 +49,28 @@
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include "bundles/datatables-js-bs5.html" %}
{% include 'bundles/filterdropdown-js.html' %} {% include "bundles/filterdropdown-js.html" %}
{% endblock %} {% endblock extra_javascript %}
{% block extra_css %} {% block extra_css %}
{% include 'bundles/datatables-css.html' %} {% include "bundles/datatables-css-bs5.html" %}
{% endblock %} {% endblock extra_css %}
{% block extra_script %} {% block extra_script %}
$(document).ready(function() { $(document).ready(function () {
let groupColumn = 0; let groupColumn = 0;
$('#tab_permissions_overview').DataTable({ $('#tab_permissions_overview').DataTable({
columnDefs: [ columnDefs: [{
{ "visible": false, "targets": groupColumn } "visible": false,
"targets": groupColumn
}],
order: [
[groupColumn, 'asc'],
[1, 'asc'],
[2, 'asc']
], ],
order: [[ groupColumn, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ] ], filterDropDown: {
filterDropDown: columns: [{
{
columns: [
{
idx: 0 idx: 0
}, },
{ {
@ -108,21 +81,27 @@
}, },
"stateSave": true, "stateSave": true,
"stateDuration": 0, "stateDuration": 0,
drawCallback: function ( settings ) { drawCallback: function (settings) {
let api = this.api(); let api = this.api();
let rows = api.rows( {page:'current'} ).nodes(); let rows = api.rows({
page: 'current'
}).nodes();
let last = null; let last = null;
api.column(groupColumn, {
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) { page: 'current'
if ( last !== group ) { }).data().each(function (group, i) {
$(rows).eq( i ).before( if (last !== group) {
'<tr class="tr-group"><td colspan="6">' + group + '</td></tr>' $(rows).eq(i).before(
'
<tr class="h4 table-secondary">
<td colspan="6">' + group + '</td>
</tr>
'
); );
last = group; last = group;
} }
} ); });
} }
} ); });
} ); });
{% endblock %} {% endblock extra_script %}

View File

@ -31,6 +31,11 @@ INSTALLED_APPS = [
'allianceauth.notifications', 'allianceauth.notifications',
'allianceauth.thirdparty.navhelper', 'allianceauth.thirdparty.navhelper',
'allianceauth.analytics', 'allianceauth.analytics',
'allianceauth.menu',
'allianceauth.theme',
'allianceauth.theme.darkly',
'allianceauth.theme.flatly',
'allianceauth.theme.materia',
] ]
SECRET_KEY = "wow I'm a really bad default secret key" SECRET_KEY = "wow I'm a really bad default secret key"
@ -188,6 +193,8 @@ DATABASES = {
SITE_NAME = 'Alliance Auth' SITE_NAME = 'Alliance Auth'
DEFAULT_THEME = "allianceauth.theme.darkly"
LOGIN_URL = 'auth_login_user' # view that handles login logic LOGIN_URL = 'auth_login_user' # view that handles login logic
LOGIN_REDIRECT_URL = 'authentication:dashboard' # default destination when logging in if no redirect specified LOGIN_REDIRECT_URL = 'authentication:dashboard' # default destination when logging in if no redirect specified

View File

@ -26,7 +26,7 @@ DEBUG = False
# Add any additional apps to this list. # Add any additional apps to this list.
INSTALLED_APPS += [ INSTALLED_APPS += [
#'allianceauth.theme.bootstrap',
] ]
# To change the logging level for extensions, uncomment the following line. # To change the logging level for extensions, uncomment the following line.

View File

@ -1,7 +1,7 @@
from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from django.utils.translation import gettext_lazy as _
from .hooks import MenuItemHook from ..menu.hooks import MenuItemHook
from .hooks import ServicesHook from .hooks import ServicesHook

View File

@ -1,5 +1,5 @@
from django.urls import include, re_path
from string import Formatter from string import Formatter
from django.urls import include, re_path
from typing import Iterable, Optional from typing import Iterable, Optional
from django.conf import settings from django.conf import settings
@ -9,6 +9,11 @@ from django.urls import include, re_path
from django.utils.functional import cached_property from django.utils.functional import cached_property
from allianceauth.hooks import get_hooks from allianceauth.hooks import get_hooks
from allianceauth.menu.hooks import MenuItemHook
from django.conf import settings
from django.urls import include, re_path
from django.core.exceptions import ObjectDoesNotExist
from django.utils.functional import cached_property
from .models import NameFormatConfig from .models import NameFormatConfig
@ -136,26 +141,15 @@ class ServicesHook:
yield fn() yield fn()
class MenuItemHook: class MenuItemHook(MenuItemHook):
def __init__(self, text, classes, url_name, order=None, navactive=list([])): """
self.text = text MenuItemHook shim to allianceauth.menu.hooks
self.classes = classes
self.url_name = url_name
self.template = 'public/menuitem.html'
self.order = order if order is not None else 9999
# count is an integer shown next to the menu item as badge when count != None :param MenuItemHook: _description_
# apps need to set the count in their child class, e.g. in render() method :type MenuItemHook: _type_
self.count = None """
def __init_subclass__(cls) -> None:
navactive = navactive or [] return super().__init_subclass__()
navactive.append(url_name)
self.navactive = navactive
def render(self, request):
return render_to_string(self.template,
{'item': self},
request=request)
class UrlHook: class UrlHook:

View File

@ -1,37 +1,34 @@
{% load i18n %} {% load i18n %}
<div class="card text-center m-4" style="min-width: 18rem; min-height: 18rem;">
<div class="card-body ">
<tr> <h5 class="card-title ">{% translate "Discord" %}</h5>
<td class="text-center">{% translate "Discord" %}</td> <p class="card-text">{% if server_name %}{{ server_name }}{% else %}{% translate "Unlinked Server" %}{% endif %}</p>
<td class="text-center"> <p class="card-text"><span class="badge {% if user_has_account %}bg-success{% else %}bg-warning{% endif %}">{% if user_has_account %}{% translate "Active" %}{% else %}{% translate "Disabled" %}{% endif %}</span></p>
<p class="card-text">
{% if not user_has_account %} {% if not user_has_account %}
(not activated) {% translate "(not activated)" %}
{% else %} {% else %}
{{discord_username}} {{ discord_username }}
{% endif %} {% endif %}
</td> </p>
<td class="text-center"> </div>
{{server_name}} <div class="card-footer">
</td>
<td class="text-center">
{% if not user_has_account %} {% if not user_has_account %}
<a href="{% url 'discord:activate' %}" title="{% translate 'Join the Discord server' %}" class="btn btn-primary"> <a href="{% url 'discord:activate' %}" title="{% translate 'Join the Discord server' %}" class="btn btn-primary">
<span class="glyphicon glyphicon-ok"></span> <span class="fas fa-check fa-fw"></span>
</a> </a>
{% else %} {% else %}
<a href="{% url 'discord:reset' %}" title="{% translate 'Leave- and rejoin the Discord Server (Reset)' %}" class="btn btn-warning"> <a href="{% url 'discord:reset' %}" title="{% translate 'Leave- and rejoin the Discord Server (Reset)' %}" class="btn btn-warning">
<span class="glyphicon glyphicon-refresh"></span> <span class="fas fa-sync fa-fw"></span>
</a> </a>
<a href="{% url 'discord:deactivate' %}" title="{% translate 'Leave the Discord server' %}" class="btn btn-danger"> <a href="{% url 'discord:deactivate' %}" title="{% translate 'Leave the Discord server' %}" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> <span class="fas fa-times fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<div class="text-center" style="padding-top:5px;"> <a type="button" id="btnLinkDiscordServer" class="btn btn-primary" href="{% url 'discord:add_bot' %}">
<a type="button" id="btnLinkDiscordServer" class="btn btn-default" href="{% url 'discord:add_bot' %}"> <span class="fas fa-link fa-fw"></span>
{% translate "Link Discord Server" %}
</a> </a>
</div>
{% endif %} {% endif %}
</td> </div>
</tr> </div>

View File

@ -1,10 +1,20 @@
{% extends "services/services_ctrl_base.html" %}
{% load i18n %} {% load i18n %}
<tr> {% block title %}
<td class="text-center">Discourse</td> {% translate "Discourse" %}
<td class="text-center">{{ char.character_name }}</td> {% endblock %}
<td class="text-center"><a href="{{ DISCOURSE_URL }}">{{ DISCOURSE_URL }}</a></td>
<td class="text-center"> {% block url %}
<a title="Go To Forums" class="btn btn-success" href="{{ DISCOURSE_URL }}"><span class="glyphicon glyphicon-arrow-right"></span></a> <a href="{{ DISCOURSE_URL }}">{{ DISCOURSE_URL }}</a>
</td> {% endblock %}
</tr>
{% block user %}
Username: {{ char.character_name }}
{% endblock %}
{% block controls %}
<a title="Go To Forums" href="{{ DISCOURSE_URL }}" class="btn btn-success" title="Connect">
<span class="fas fa-arrow-right fa-fw"></span>
</a>
{% endblock %}

View File

@ -1,28 +1,34 @@
<tr> {% load i18n %}
<td class="text-center">{{ service_name }}</td> <div class="card text-center m-4" style="min-width: 18rem; min-height: 18rem;">
<td class="text-center">{{ username }}</td> <div class="card-body ">
<h5 class="card-title ">{{ service_name }}</h5>
<p class="card-text"><a href="mumble://{{ service_url }}">{{ service_url }}</a></p>
<p class="card-text"><span class="badge {% if username != '' %}bg-success{% else %}bg-warning{% endif %}">{% if username != '' %}Active{% else %}Disabled{% endif %}</span></p>
<p class="card-text">Username: <span class="badge bg-secondary text-end">{{ username }}</span></p>
</div>
<div class="card-footer">
{% if username == "" %} {% if username == "" %}
<td class="text-center">{{ service_url }}</td> <td class="text-center">{{ service_url }}</td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'mumble:activate' %}" title="Activate" class="btn btn-warning"> <a href="{% url 'mumble:activate' %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="fas fa-check fa-fw"></span>
</a> </a>
</td> </td>
{% else %} {% else %}
<td class="text-center"><a href="mumble://{{ connect_url }}">{{ service_url }}</a></td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'mumble:set_password' %}" title="Set Password" class="btn btn-warning"> <a href="{% url 'mumble:set_password' %}" title="Set Password" class="btn btn-warning">
<span class="glyphicon glyphicon-pencil"></span> <span class="fas fa-edit fa-fw"></span>
</a> </a>
<a href="{% url 'mumble:reset_password' %}" title="Reset Password" class="btn btn-primary"> <a href="{% url 'mumble:reset_password' %}" title="Reset Password" class="btn btn-primary">
<span class="glyphicon glyphicon-refresh"></span> <span class="fas fa-sync fa-fw"></span>
</a> </a>
<a href="{% url 'mumble:deactivate' %}" title="Deactivate" class="btn btn-danger"> <a href="{% url 'mumble:deactivate' %}" title="Deactivate" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> <span class="fas fa-times fa-fw"></span>
</a> </a>
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect"> <a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<span class="glyphicon glyphicon-arrow-right"></span> <span class="fas fa-arrow-right fa-fw"></span>
</a> </a>
</td> </td>
{% endif %} {% endif %}
</tr> </div>
</div>

View File

@ -5,7 +5,8 @@ from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import ServicesHook, MenuItemHook from allianceauth.menu.hooks import MenuItemHook
from allianceauth.services.hooks import ServicesHook
from .tasks import OpenfireTasks from .tasks import OpenfireTasks
from .urls import urlpatterns from .urls import urlpatterns

View File

@ -1,27 +1,39 @@
{% extends "services/services_ctrl_base.html" %}
{% load i18n %} {% load i18n %}
<tr> {% block title %}
<td class="text-center">Teamspeak 3</td> {% translate "Teamspeak 3" %}
<td class="text-center">{{ authinfo.teamspeak3_uid }}</td> {% endblock %}
<td class="text-center"><a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}">{{ TEAMSPEAK3_PUBLIC_URL }}</a></td>
<td class="text-center"> {% block url %}
<a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}">{{ TEAMSPEAK3_PUBLIC_URL }}</a>
{% endblock %}
{% block active %}
<span class="badge {% if authinfo.teamspeak3_uid != '' %}bg-success{% else %}bg-warning{% endif %}">{% if authinfo.teamspeak3_uid != '' %}Active{% else %}Disabled{% endif %}</span>
{% endblock %}
{% block user %}
{{ authinfo.teamspeak3_uid }}
{% endblock %}
{% block controls %}
{% if authinfo.teamspeak3_uid == "" %} {% if authinfo.teamspeak3_uid == "" %}
<a href="{% url 'teamspeak3:activate' %}" title="Activate" class="btn btn-warning"> <a href="{% url 'teamspeak3:activate' %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="fas fa-check fa-fw"></span>
</a> </a>
{% else %} {% else %}
<a href="{% url 'teamspeak3:verify' %}" title="Verify Client ID" class="btn btn-success"> <a href="{% url 'teamspeak3:verify' %}" title="Verify Client ID" class="btn btn-success">
<span class="glyphicon glyphicon-log-in"></span> <span class="far fa-sign-in fa-fw"></span>
</a> </a>
<a href="{% url 'teamspeak3:reset_perm' %}" title="Refresh Token" class="btn btn-primary"> <a href="{% url 'teamspeak3:reset_perm' %}" title="Refresh Token" class="btn btn-primary">
<span class="glyphicon glyphicon-refresh"></span> <span class="fas fa-sync fa-fw"></span>
</a> </a>
<a href="{% url 'teamspeak3:deactivate' %}" title="Deactivate" class="btn btn-danger"> <a href="{% url 'teamspeak3:deactivate' %}" title="Deactivate" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> <span class="fas fa-times fa-fw"></span>
</a> </a>
<a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}?nickname={{ authinfo.teamspeak3_uid }}" title="Connect" class="btn btn-success"> <a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}?nickname={{ authinfo.teamspeak3_uid }}" title="Connect" class="btn btn-success">
<span class="glyphicon glyphicon-arrow-right"></span> <span class="fas fa-arrow-right fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
</td> {% endblock %}
</tr>

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load bootstrap %} {% load bootstrap %}
{% load i18n %} {% load i18n %}

View File

@ -1,29 +1,48 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% block page_title %}{% translate "Services Management" %}{% endblock page_title %} {% block page_title %}{% translate "Services Management" %}{% endblock page_title %}
{% block extra_css %}{% endblock extra_css %} {% block extra_css %}{% endblock extra_css %}
{% block header_nav_brand %}{% translate "Available Services" %}{% endblock header_nav_brand %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="d-flex p-2 bd-highlight justify-content-center flex-wrap">
<h1 class="page-header text-center">{% translate "Available Services" %}</h1>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th class="text-center">{% translate "Service" %}</th>
<th class="text-center">{% translate "Username" %}</th>
<th class="text-center">{% translate "Domain" %}</th>
<th class="text-center">{% translate "Action" %}</th>
</tr>
</thead>
<tbody>
{% for svc in service_ctrls %} {% for svc in service_ctrls %}
{{ svc }} {{ svc }}
{% endfor %} {% endfor %}
</tbody>
</table>
</div> </div>
<div class="w-100 text-center">
<h4>Legend</h4>
<div class="d-inline-flex bd-highlight justify-content-center flex-wrap">
<div class="d-inline-flex m-3">
<a title="Activate" class="btn btn-warning">
<span class="fas fa-check fa-fw"></span>
</a>
<p class="m-2 p-0 align-self-center">{% translate "Click to activate the service for your user." %}</p>
</div>
<div class="d-inline-flex m-3">
<a title="Set Password" class="btn btn-warning">
<span class="fas fa-edit fa-fw"></span>
</a>
<p class="m-2 p-0 align-self-center">{% translate "Click to manually set your password." %}</p>
</div>
<div class="d-inline-flex m-3">
<a title="Reset Password" class="btn btn-primary">
<span class="fas fa-sync fa-fw"></span>
</a>
<p class="m-2 p-0 align-self-center">{% translate "Click to randomly generate your password." %}</p>
</div>
<div class="d-inline-flex m-3">
<a title="Deactivate" class="btn btn-danger">
<span class="fas fa-times fa-fw"></span>
</a>
<p class="m-2 p-0 align-self-center">{% translate "Click to deactivate the service for your user" %}</p>
</div>
</div>
<p class="m-2 p-0 align-self-center">{% translate "Some services provide different options. Hover over the buttons to see more." %}</p>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -1,32 +1,44 @@
{% extends "services/services_ctrl_base.html" %}
{% load i18n %} {% load i18n %}
<tr> {% block title %}
<td class="text-center">{{ service_name }}</td> {{ service_name }}
<td class="text-center">{{ username }}</td> {% endblock %}
<td class="text-center"><a href="{{ service_url }}">{{ service_url }}</a></td>
<td class="text-center"> {% block url %}
<a href="{{ service_url }}">{{ service_url }}</a>
{% endblock %}
{% block active %}
<span class="badge {% if username != '' %}bg-success{% else %}bg-warning{% endif %}">{% if username != '' %}Active{% else %}Disabled{% endif %}</span>
{% endblock %}
{% block user %}
Username: <span class="badge bg-secondary">{{ username }}</span>
{% endblock %}
{% block controls %}
{% if username == "" %} {% if username == "" %}
{% if urls.auth_activate %} {% if urls.auth_activate %}
<a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning"> <a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="fas fa-check fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
{% else %} {% else %}
{% if urls.auth_set_password %} {% if urls.auth_set_password %}
<a href="{% url urls.auth_set_password %}" title="Set Password" class="btn btn-warning"> <a href="{% url urls.auth_set_password %}" title="Set Password" class="btn btn-warning">
<span class="glyphicon glyphicon-pencil"></span> <span class="fas fa-edit fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
{% if urls.auth_reset_password %} {% if urls.auth_reset_password %}
<a href="{% url urls.auth_reset_password %}" title="Reset Password" class="btn btn-primary"> <a href="{% url urls.auth_reset_password %}" title="Reset Password" class="btn btn-primary">
<span class="glyphicon glyphicon-refresh"></span> <span class="fas fa-sync fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
{% if urls.auth_deactivate %} {% if urls.auth_deactivate %}
<a href="{% url urls.auth_deactivate %}" title="Deactivate" class="btn btn-danger"> <a href="{% url urls.auth_deactivate %}" title="Deactivate" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> <span class="fas fa-times fa-fw"></span>
</a> </a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> {% endblock %}
</tr>

View File

@ -0,0 +1,15 @@
{% load i18n %}
<div class="card text-center m-4" style="min-width: 18rem; min-height: 18rem">
<div class="card-body">
<h5 class="card-title">{% block title %}{% endblock title %}</h5>
<p class="card-text">{% block url %}{% endblock url %}</p>
<p class="card-text">
{% block active %}
<span class="badge bg-success">Active</span>
{% endblock active %}
</p>
<p class="card-text">{% block user %}{% endblock user %}</p>
{% block extra %}{% endblock extra %}
</div>
<div class="card-footer">{% block controls %}{% endblock controls %}</div>
</div>

View File

@ -1,7 +1,8 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.menu.hooks import MenuItemHook
from allianceauth.services.hooks import UrlHook
from . import urls from . import urls
from .managers import SRPManager from .managers import SRPManager

View File

@ -1,54 +1,13 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% load humanize %} {% load humanize %}
{% block page_title %}{% translate "Srp Fleet Data" %}{% endblock page_title %} {% block page_title %}{% translate "Srp Fleet Data" %}{% endblock page_title %}
{% block extra_css %}
{% include 'bundles/datatables-css.html' %}
{% include 'bundles/x-editable.css.html' %}
{% include 'bundles/checkbox-css.html' %}
<style>
.copy-text-fa-icon:hover {
cursor: pointer;
}
.radio label, .checkbox label {
padding-left: 10px;
}
.editable {
width:150px;
text-align: center;
}
.editableform .form-control {
width: 95%;
text-align: center;
margin-left: 10px;
}
.editable-input {
width: 95%;
}
.radio, .checkbox {
margin-top: 0;
margin-bottom: 0;
}
.editable-error-block {
white-space: nowrap;
}
.editable-click, a.editable-click, a.editable-click:hover {
border-bottom: none;
}
.tooltip-inner {
white-space:pre;
max-width: none;
}
</style>
{% endblock extra_css %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<div class="row"> <div class="row">
<h1 class="page-header text-center">{% translate "SRP Fleet Data" %} <h1 class="page-header text-center">{% translate "SRP Fleet Data" %}
<div class="text-right"> <div class="text-end">
{% if perms.auth.srp_management %} {% if perms.auth.srp_management %}
{% if fleet_status == "Completed" %} {% if fleet_status == "Completed" %}
<a href="{% url 'srp:mark_uncompleted' fleet_id %}" class="btn btn-warning"> <a href="{% url 'srp:mark_uncompleted' fleet_id %}" class="btn btn-warning">
@ -67,7 +26,7 @@
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<div class="text-right"> <div class="text-end">
<b><span style="padding-right:2.5em">{% translate "Total Losses:" %} {{ srpfleetrequests.count }}</span></b> <b><span style="padding-right:2.5em">{% translate "Total Losses:" %} {{ srpfleetrequests.count }}</span></b>
<b><span style="padding-right:2.5em">{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</span></b> <b><span style="padding-right:2.5em">{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</span></b>
{% if perms.auth.srp_management %} {% if perms.auth.srp_management %}
@ -114,7 +73,7 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{{ srpfleetrequest.killboard_link }}" <a href="{{ srpfleetrequest.killboard_link }}"
target="_blank" class="label label-warning">Link</a> target="_blank" class="badge badge-warning">{% translate "Link" %}</a>
</td> </td>
<td class="text-center">{{ srpfleetrequest.additional_info }}</td> <td class="text-center">{{ srpfleetrequest.additional_info }}</td>
<td class="text-center">{{ srpfleetrequest.srp_ship_name }}</td> <td class="text-center">{{ srpfleetrequest.srp_ship_name }}</td>
@ -123,15 +82,15 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
<td class="text-center" data-sort="{{ srpfleetrequest.post_time | date:"Y-m-d H:i" }}">{{ srpfleetrequest.post_time | date:"Y-M-d H:i" }}</td> <td class="text-center" data-sort="{{ srpfleetrequest.post_time | date:"Y-m-d H:i" }}">{{ srpfleetrequest.post_time | date:"Y-M-d H:i" }}</td>
<td class="text-center"> <td class="text-center">
{% if srpfleetrequest.srp_status == "Approved" %} {% if srpfleetrequest.srp_status == "Approved" %}
<div class="label label-success"> <div class="badge badge-success">
{% translate "Approved" %} {% translate "Approved" %}
</div> </div>
{% elif srpfleetrequest.srp_status == "Rejected" %} {% elif srpfleetrequest.srp_status == "Rejected" %}
<div class="label label-danger"> <div class="badge badge-danger">
{% translate "Rejected" %} {% translate "Rejected" %}
</div> </div>
{% else %} {% else %}
<div class="label label-warning"> <div class="badge badge-warning">
{% translate "Pending" %} {% translate "Pending" %}
</div> </div>
{% endif %} {% endif %}
@ -148,12 +107,12 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
<tbody> </tbody>
</table> </table>
</div> </div>
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<div class="text-right"> <div class="text-end">
<b><span style="padding-right:2.5em">{% translate "Total Losses:" %} {{ srpfleetrequests.count }}</span></b> <b><span style="padding-right:2.5em">{% translate "Total Losses:" %} {{ srpfleetrequests.count }}</span></b>
<b><span style="padding-right:2.5em">{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</span></b> <b><span style="padding-right:2.5em">{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</span></b>
{% if perms.auth.srp_management %} {% if perms.auth.srp_management %}
@ -180,10 +139,10 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
{% endblock content %} {% endblock content %}
{% block extra_javascript %} {% block extra_javascript %}
{% include 'bundles/datatables-js.html' %} {% include "bundles/datatables-js-bs5.html" %}
{% include 'bundles/x-editable-js.html' %} {% include "bundles/x-editable-js.html" %}
{% include 'bundles/moment-js.html' %} {% include "bundles/moment-js.html" %}
{% include 'bundles/clipboard-js.html' %} {% include "bundles/clipboard-js.html" %}
<script> <script>
const clipboard = new ClipboardJS('.copy-text-fa-icon'); const clipboard = new ClipboardJS('.copy-text-fa-icon');
@ -273,3 +232,44 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
$("[rel=tooltip]").tooltip({ placement: 'top'}); $("[rel=tooltip]").tooltip({ placement: 'top'});
}); });
{% endblock extra_script %} {% endblock extra_script %}
{% block extra_css %}
{% include "bundles/datatables-css-bs5.html" %}
{% include "bundles/x-editable.css.html" %}
{% include "bundles/checkbox-css.html" %}
<style>
.copy-text-fa-icon:hover {
cursor: pointer;
}
.radio label, .checkbox label {
padding-left: 10px;
}
.editable {
width:150px;
text-align: center;
}
.editableform .form-control {
width: 95%;
text-align: center;
margin-left: 10px;
}
.editable-input {
width: 95%;
}
.radio, .checkbox {
margin-top: 0;
margin-bottom: 0;
}
.editable-error-block {
white-space: nowrap;
}
.editable-click, a.editable-click, a.editable-click:hover {
border-bottom: none;
}
.tooltip-inner {
white-space:pre;
max-width: none;
}
</style>
{% endblock extra_css %}

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load i18n %} {% load i18n %}
{% load humanize %} {% load humanize %}
@ -10,7 +10,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="row"> <div class="row">
<h1 class="page-header text-center">{% translate "SRP Management" %} <h1 class="page-header text-center">{% translate "SRP Management" %}
<div class="text-right"> <div class="text-end">
{% if perms.auth.srp_management %} {% if perms.auth.srp_management %}
<a href="{% url 'srp:all' %}" class="btn btn-primary"> <a href="{% url 'srp:all' %}" class="btn btn-primary">
{% translate "View All" %} {% translate "View All" %}
@ -24,7 +24,7 @@
</div> </div>
</h1> </h1>
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<div class="text-right"> <div class="text-end">
<b>{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</b> <b>{% translate "Total ISK Cost:" %} {{ totalcost | intcomma }}</b>
</div> </div>
</div> </div>
@ -46,27 +46,27 @@
{% for srpfleet in srpfleets %} {% for srpfleet in srpfleets %}
<tr> <tr>
<td class="text-center"> <td class="text-center">
<div class="label label-info"> <div class="badge badge-info">
{{ srpfleet.fleet_name }} {{ srpfleet.fleet_name }}
</div> </div>
</td> </td>
<td class="text-center">{{ srpfleet.fleet_time | date:"Y-m-d H:i" }}</td> <td class="text-center">{{ srpfleet.fleet_time | date:"Y-m-d H:i" }}</td>
<td class="text-center">{{ srpfleet.fleet_doctrine }}</td> <td class="text-center">{{ srpfleet.fleet_doctrine }}</td>
<td class="text-center"> <td class="text-center">
<div class="label label-success"> <div class="badge badge-success">
{{ srpfleet.fleet_commander.character_name }} {{ srpfleet.fleet_commander.character_name }}
</div> </div>
</td> </td>
<td class="text-center"> <td class="text-center">
{% if srpfleet.fleet_srp_aar_link %} {% if srpfleet.fleet_srp_aar_link %}
<a href="{{ srpfleet.fleet_srp_aar_link }}" target="_blank" class="label label-primary">{% translate 'Link' %}</a> <a href="{{ srpfleet.fleet_srp_aar_link }}" target="_blank" class="badge badge-primary">{% translate "Link" %}</a>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
{% if srpfleet.fleet_srp_code %} {% if srpfleet.fleet_srp_code %}
<a class="label label-warning" href="{% url 'srp:request' srpfleet.fleet_srp_code %}">{{ srpfleet.fleet_srp_code }}</a> <a class="badge badge-warning" href="{% url 'srp:request' srpfleet.fleet_srp_code %}">{{ srpfleet.fleet_srp_code }}</a>
{% else %} {% else %}
<div class="label label-danger"> <div class="badge badge-danger">
{% translate "Disabled" %} {% translate "Disabled" %}
</div> </div>
{% endif %} {% endif %}
@ -75,17 +75,17 @@
<td class="text-center"> <td class="text-center">
{% if srpfleet.fleet_srp_status == "" %} {% if srpfleet.fleet_srp_status == "" %}
<div class="label label-warning"> <div class="badge badge-warning">
{% translate "Pending" %} {% translate "Pending" %}
</div> </div>
{% else %} {% else %}
<div class="label label-success"> <div class="badge badge-success">
{% translate "Completed" %} {% translate "Completed" %}
</div> </div>
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
<div class="label label-warning">{{ srpfleet.pending_requests }}</div> <div class="badge badge-warning">{{ srpfleet.pending_requests }}</div>
</td> </td>
<td class="text-center"> <td class="text-center">

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load bootstrap %} {% load bootstrap %}
{% load i18n %} {% load i18n %}

View File

@ -1,4 +1,4 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base-bs5.html" %}
{% load bootstrap %} {% load bootstrap %}
{% load i18n %} {% load i18n %}
@ -26,7 +26,6 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg122"
width="256"
height="256"
viewBox="0 0 255.99999 256"
sodipodi:docname="allianceauth (2).svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs126" />
<sodipodi:namedview
id="namedview124"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
showgrid="false"
inkscape:zoom="3.8506576"
inkscape:cx="30.514269"
inkscape:cy="102.57988"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g128" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g128">
<g
id="g2338"
transform="translate(41.953499,36.607802)">
<path
style="display:inline;fill:#e14852;stroke-width:0.32"
d="M 131.07236,159.67687 C 109.26615,147.02458 91.302022,136.55002 91.152067,136.40007 l -0.272649,-0.27265 23.786292,-13.82371 c 13.08247,-7.60304 23.9186,-13.82025 24.08029,-13.81602 l 0.294,0.008 15.93273,36.83413 c 8.763,20.25877 15.891,36.95054 15.84,37.09283 l -0.0927,0.25869 z"
id="path2342"
sodipodi:nodetypes="cscsccsscc" />
<path
style="display:inline;fill:#436195;stroke-width:0.32"
d="m 1.28,182.46369 c 0,-0.16969 17.354495,-40.46543 38.565546,-89.546103 L 78.411088,3.68 C 79.919052,1.4903841 82.294641,0.02199886 86.08,0.01224344 89.865359,0.00248802 92.288,1.4677954 93.674477,3.5158445 l 21.668143,50.1206965 21.66814,50.120699 -0.26538,0.23285 C 136.59942,104.11816 106.528,121.61441 69.92,142.87065 33.312,164.12688 2.892,181.80046 2.32,182.14527 l -1.04,0.62693 z"
id="path2340"
sodipodi:nodetypes="ssczcccssscs" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,36 +1,41 @@
{% load i18n %} {% load i18n %}
{% load humanize %} {% load humanize %}
{% if notifications %}
<div class="col-sm-12"> <div class="col-12 align-self-stretch p-2">
<div class="row vertical-flexbox-row2"> <div class="card">
<div class="col-sm-6"> <div class="card-body">
<div class="panel panel-primary" style="height:100%;position:relative;"> <div class="d-flex align-items-center">
<div class="panel-heading text-center"><h3 class="panel-title">{% translate "Alliance Auth Notifications" %}</h3></div> <div class="w-100 align-self-stretch">
<div class="panel-body"> <h4 class="ms-auto me-auto">
{% translate "Alliance Auth Notifications" %}
</h4>
<div class="card-body">
<ul class="list-group"> <ul class="list-group">
{% for notif in notifications %} {% for notif in notifications %}
<li class="list-group-item"> <li class="list-group-item">
{% if notif.state == 'opened' %} {% if notif.state == 'opened' %}
<span class="label label-success">{% translate "Open" %}</span> <span class="badge badge-success">{% translate "Open" %}</span>
{% else %} {% else %}
<span class="label label-danger">{% translate "Closed" %}</span> <span class="badge badge-danger">{% translate "Closed" %}</span>
{% endif %} {% endif %}
<a href="{{ notif.web_url }}" target="_blank">#{{ notif.iid }} {{ notif.title }}</a> <a href="{{ notif.web_url }}" target="_blank">#{{ notif.iid }} {{ notif.title }}</a>
</li> </li>
{% empty %}
<div class="alert alert-primary" role="alert">
{% translate "No notifications at this time" %}
</div>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<div class="text-end" style="position: absolute; bottom: 5px; right: 5px;">
<div class="text-right" style="position: absolute; bottom: 5px; right: 5px;">
<a href="https://gitlab.com/allianceauth/allianceauth/issues" target="_blank" style="margin-right: 0.5rem;"> <a href="https://gitlab.com/allianceauth/allianceauth/issues" target="_blank" style="margin-right: 0.5rem;">
<span class="label" style="background-color: #e65328;"> <span class="badge" style="background-color: #e65328;">
<i class="fab fa-gitlab" aria-hidden="true"></i> <i class="fab fa-gitlab" aria-hidden="true"></i>
{% translate 'Powered by GitLab' %} {% translate 'Powered by GitLab' %}
</span> </span>
</a> </a>
<a href="https://discord.com/invite/fjnHAmk" target="_blank"> <a href="https://discord.com/invite/fjnHAmk" target="_blank">
<span class="label" style="background-color: rgb(110,133,211);"> <span class="badge" style="background-color: rgb(110,133,211);">
<i class="fab fa-discord" aria-hidden="true"></i> <i class="fab fa-discord" aria-hidden="true"></i>
{% translate 'Support Discord' %} {% translate 'Support Discord' %}
</span> </span>
@ -38,45 +43,54 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-6"> </div>
<div class="panel panel-primary" style="height:50%;"> </div>
<div class="panel-heading text-center"><h3 class="panel-title">{% translate "Software Version" %}</h3></div> </div>
<div class="panel-body flex-center-horizontal"> {% endif %}
<ul class="list-group list-group-horizontal" style="margin-bottom: 0;"> <div class="col-12 align-self-stretch p-2">
<li class="list-group-item"> <div class="card">
<div class="card-body d-flex flex-row flex-wrap">
<div class="col-xl-6 col-lg-12 col-md-12 col-sm-12">
<h4 class="ms-auto me-auto text-center">
{% translate "Software Version" %}
</h4>
<div class="card-body pb-0">
<ul class="list-group list-group-horizontal w-100" role="group" aria-label="Basic example">
<li type="button" class="list-group-item w-100">
<h5 class="list-group-item-heading">{% translate "Current" %}</h5> <h5 class="list-group-item-heading">{% translate "Current" %}</h5>
<p class="list-group-item-text"> <p class="list-group-item-text">
{{ current_version }} {{ current_version }}
</p> </p>
</li> </li>
<li class="list-group-item list-group-item-{% if latest_patch %}success{% elif latest_minor %}warning{% else %}danger{% endif %}"> <li class="list-group-item list-group-item-{% if latest_patch %}success{% elif latest_minor %}warning{% else %}danger{% endif %} w-100" href="https://gitlab.com/allianceauth/allianceauth/-/tags/v{{ latest_patch_version }}">
<h5 class="list-group-item-heading">{% translate "Latest Stable" %}</h5> <h5 class="list-group-item-heading">{% translate "Latest Stable" %}</h5>
<p class="list-group-item-text"> <p class="list-group-item-text">
<a href="https://gitlab.com/allianceauth/allianceauth/-/tags/v{{ latest_patch_version }}" style="color:#000;">
<i class="fab fa-gitlab hidden-xs" aria-hidden="true"></i> <i class="fab fa-gitlab hidden-xs" aria-hidden="true"></i>
{{ latest_patch_version }} {{ latest_patch_version }}
</a>
{% if not latest_patch %}<br>{% translate "Update available" %}{% endif %} {% if not latest_patch %}<br>{% translate "Update available" %}{% endif %}
</p> </p>
</li> </li>
{% if latest_beta %} {% if latest_beta %}
<li class="list-group-item list-group-item-info"> <li>
<a type="button" class="btn btn-info w-100" href="https://gitlab.com/allianceauth/allianceauth/-/tags/v{{ latest_beta_version }}">
<h5 class="list-group-item-heading">{% translate "Latest Pre-Release" %}</h5> <h5 class="list-group-item-heading">{% translate "Latest Pre-Release" %}</h5>
<p class="list-group-item-text"> <p class="list-group-item-text">
<a href="https://gitlab.com/allianceauth/allianceauth/-/tags/v{{ latest_beta_version }}" style="color:#000;">
<i class="fab fa-gitlab hidden-xs" aria-hidden="true"></i> <i class="fab fa-gitlab hidden-xs" aria-hidden="true"></i>
{{ latest_beta_version }} {{ latest_beta_version }}
</a>
<br>{% translate "Pre-Release available" %} <br>{% translate "Pre-Release available" %}
</p> </p>
</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
</div> </div>
<div class="panel panel-primary" style="height:50%;"> <div class="d-xl-none d-lg-show d-md-show d-sm-show m-2"></div>
<div class="panel-heading text-center"><h3 class="panel-title">{% translate "Task Queue" %}</h3></div> <div class="col-xl-6 col-lg-12 col-md-12 col-sm-12">
<div class="panel-body flex-center-horizontal"> <h4 class="ms-auto me-auto text-center">
{% translate "Task Queue" %}
</h4>
<div class="card-body pb-0">
<p> <p>
{% blocktranslate with total=tasks_total|intcomma latest=earliest_task|timesince|default:"?" %} {% blocktranslate with total=tasks_total|intcomma latest=earliest_task|timesince|default:"?" %}
Status of {{ total }} processed tasks • last {{ latest }} Status of {{ total }} processed tasks • last {{ latest }}
@ -99,7 +113,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="clearfix"></div>
</div> </div>
<script> <script>

View File

@ -0,0 +1,123 @@
{% load static %}
{% load i18n %}
{% load navactive %}
{% load auth_notifications %}
{% load theme_tags %}
<!DOCTYPE html>
<html lang="en" {% theme_html_tags %}>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- End Required meta tags -->
<!-- Meta tags -->
<!-- TODO Bundle all the site specific stuff up into its own template for easy overide -->
<meta name="description" content="">
<meta name="author" content="">
{% include 'allianceauth/icons.html' %}
<!-- Meta tags -->
<title>{% block title %}{% block page_title %}{% endblock page_title %} - {{ SITE_NAME }}{% endblock title %}</title>
{% theme_css %}
{% include 'bundles/fontawesome.html' %}
<style>
.navbar-toggler.collapsed{
transform: rotate(180deg);
}
.nav-padding {
padding-top: {% header_padding_size %} !important;
}
.auth-logo {
background-position: bottom;
background-repeat: no-repeat;
background-image: url("{% static 'allianceauth/images/auth-logo.png' %}") ;
}
</style>
{% block extra_css %}{% endblock extra_css %}
</head>
<body class="overflow-none">
{% if user.is_authenticated %}
<!-- Top Menu, Blocks don't work in "include" tagged views -->
<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-primary">
<div class="container-fluid justify-content-start">
<a class="navbar-brand" data-bs-toggle="collapse" data-bs-target="#sidebar" role="button">
<i class="fas fa-solid fa-bars ms-2 me-2"></i>
</a>
<a class="navbar-brand">{% block header_nav_brand %}{{ SITE_NAME }}{% endblock %}</a>
<div class="collapse navbar-collapse" id="navbarexpand">
<div class="m-2"></div>
<ul id="nav-left" class="navbar-nav nav me-auto">
{% block header_nav_collapse_left %}
{% endblock %}
</ul>
<ul id="nav-right" class="navbar-nav">
{% block header_nav_collapse_right %} <!-- Default to add char and swap main -->
{% include 'allianceauth/top-menu-rh-default.html' %}
{% endblock %}
{% include 'menu/menu-notification-block.html' %}
</ul>
</div>
<a class="navbar-toggler navbar-brand border-0 collapsed" data-bs-toggle="collapse" data-bs-target="#navbarexpand" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation" style="margin-left: auto;">
<i class="fas fa-solid fa-chevron-up"></i>
</a>
</div>
</nav>
<!-- End Top Menu -->
<!-- Body -->
<main class="row flex-nowrap m-0">
{% include 'menu/sortable-side-menu.html' %}
<div class="nav-padding col flex-nowrap px-0 m-0 vh-100 overflow-auto">
<div class="p-2">
{% include 'allianceauth/messages-bs5.html' %}
{% block content %}
{% endblock content %}
</div>
</div>
</main>
<!-- End Body -->
{% endif %}
<script>
(function () {
// TODO Extend this to the groups in the sidebar too.
// TODO Move to own JS file
var sidebar = document.getElementById('sidebar')
sidebar.addEventListener("shown.bs.collapse", function () {
localStorage.removeItem("sidebar_" + sidebar.id);
});
sidebar.addEventListener("hidden.bs.collapse", function () {
localStorage.setItem("sidebar_" + sidebar.id, true);
});
if (localStorage.getItem("sidebar_" + sidebar.id) === "true") {
sidebar.classList.remove("show")
}
else {
sidebar.classList.add("show")
}
})();
</script>
{% include 'bundles/jquery-js.html' %}
{% theme_js %}
<script type="application/javascript">
let notificationUPdateSettings = {
notificationsListViewUrl: "{% url 'notifications:list' %}",
notificationsRefreshTime: "{% notifications_refresh_time %}",
userNotificationsCountViewUrl: "{% url 'notifications:user_notifications_count' request.user.pk %}"
};
</script>
{% block extra_javascript %}
{% endblock extra_javascript %}
<script>
{% block extra_script %}
{% endblock extra_script %}
</script>
</body>
</html>

View File

@ -0,0 +1,27 @@
{% extends "allianceauth/base-bs5.html" %}
{% block page_title %}
{{ error_title }}
{% endblock page_title %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{{ error_title }}</h1>
<div class="text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="150"
height="150"
fill="currentColor"
class="bi bi-exclamation-triangle"
viewBox="0 0 16 16"
>
<path
d="M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z"
/>
<path
d="M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z"
/>
</svg>
</div>
<p class="text-center"></p>>{{ error_message }}</p>
</div>
{% endblock content %}

Some files were not shown because too many files have changed in this diff Show More