Add types and description to optimers

This commit is contained in:
Peter Pfeufer 2021-10-30 04:34:49 +00:00 committed by Ariel Rin
parent 2054a76353
commit 2c59cc4cc3
8 changed files with 211 additions and 31 deletions

View File

@ -1,5 +1,6 @@
from django.contrib import admin
from allianceauth.optimer.models import OpTimer
from allianceauth.optimer.models import OpTimer, OpTimerType
admin.site.register(OpTimerType)
admin.site.register(OpTimer)

View File

@ -1,11 +1,34 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
from allianceauth.optimer.form_widgets import DataListWidget
class OpForm(forms.Form):
"""
Create/Edit Fleet Operation Form
"""
doctrine = forms.CharField(max_length=254, required=True, label=_('Doctrine'))
system = forms.CharField(max_length=254, required=True, label=_("System"))
start = forms.DateTimeField(required=True, label=_("Start Time"))
duration = forms.CharField(max_length=254, required=True, label=_("Duration"))
operation_name = forms.CharField(max_length=254, required=True, label=_("Operation Name"))
type = forms.CharField(required=False, label=_("Operation Type"))
fc = forms.CharField(max_length=254, required=True, label=_("Fleet Commander"))
duration = forms.CharField(max_length=254, required=True, label=_("Duration"))
description = forms.CharField(
widget=forms.Textarea(attrs={"rows": 10, "cols": 20, "input_type": "textarea"}),
required=False,
label=_("Additional Info"),
help_text=_("(Optional) Describe the operation with a couple of short words."),
)
def __init__(self, *args, **kwargs):
_data_list = kwargs.pop('data_list', None)
super().__init__(*args, **kwargs)
# Add the DataListWidget to our type field
self.fields['type'].widget = DataListWidget(
data_list=_data_list, name='data-list'
)

View File

@ -0,0 +1,45 @@
"""
Form Widgets
"""
from django import forms
class DataListWidget(forms.TextInput):
"""
DataListWidget
Draws an HTML5 datalist form field
"""
def __init__(self, data_list, name, *args, **kwargs):
super().__init__(*args, **kwargs)
self._name = name
self._list = data_list
self.attrs.update({"list": "list__%s" % self._name})
def render(self, name, value, attrs=None, renderer=None):
"""
Render the DataList
:param name:
:type name:
:param value:
:type value:
:param attrs:
:type attrs:
:param renderer:
:type renderer:
:return:
:rtype:
"""
text_html = super().render(name, value, attrs=attrs)
data_list = '<datalist id="list__%s">' % self._name
for item in self._list:
data_list += '<option value="%s">' % item
data_list += "</datalist>"
return text_html + data_list

View File

@ -0,0 +1,50 @@
# Generated by Django 3.2.8 on 2021-10-26 16:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("optimer", "0004_on_delete"),
]
operations = [
migrations.CreateModel(
name="OpTimerType",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("type", models.CharField(default="", max_length=254)),
],
options={
"ordering": ["type"],
"default_permissions": (),
},
),
migrations.AlterModelOptions(
name="optimer",
options={"default_permissions": (), "ordering": ["start"]},
),
migrations.AddField(
model_name="optimer",
name="description",
field=models.TextField(blank=True, default=""),
),
migrations.AddField(
model_name="optimer",
name="type",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="optimer.optimertype",
),
),
]

View File

@ -6,9 +6,25 @@ from django.utils import timezone
from allianceauth.eveonline.models import EveCharacter
class OpTimerType(models.Model):
"""
Optimer Type
"""
type = models.CharField(max_length=254, default="")
def __str__(self):
return self.type
class Meta:
ordering = ['type']
default_permissions = ()
class OpTimer(models.Model):
class Meta:
ordering = ['start']
default_permissions = ()
doctrine = models.CharField(max_length=254, default="")
system = models.CharField(max_length=254, default="")
@ -17,7 +33,10 @@ class OpTimer(models.Model):
operation_name = models.CharField(max_length=254, default="")
fc = models.CharField(max_length=254, default="")
post_time = models.DateTimeField(default=timezone.now)
eve_character = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL)
eve_character = models.ForeignKey(EveCharacter, null=True,
on_delete=models.SET_NULL)
description = models.TextField(blank=True, default="")
type = models.ForeignKey(OpTimerType, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.operation_name

View File

@ -6,37 +6,48 @@
<table class="table">
<thead>
<tr>
<th class="text-center col-lg-3">{% translate "Operation Name" %}</th>
<th class="text-center col lg-2">{% translate "Doctrine" %}</th>
<th class="text-center col-lg-1">{% translate "Form Up System" %}</th>
<th class="text-center col-lg-1">{% translate "Start Time" %}</th>
<th class="text-center col-lg-1">{% translate "Local Time" %}</th>
<th class="text-center col-lg-1">{% translate "Duration" %}</th>
<th class="text-center col-lg-1">{% translate "FC" %}</th>
<th>{% translate "Operation Name" %}</th>
<th>{% translate "Description" %}</th>
<th>{% translate "Doctrine" %}</th>
<th>{% translate "Form Up System" %}</th>
<th>{% translate "Start Time" %}</th>
<th>{% translate "Local Time" %}</th>
<th>{% translate "Duration" %}</th>
<th>{% translate "FC" %}</th>
{% if perms.auth.optimer_management %}
<th class="text-center col-lg-1">{% translate "Creator" %}</th>
<th class="text-center col-lg-2">{% translate "Action" %}</th>
{# <th>{% translate "Creator" %}</th>#}
<th class="text-right" style="width: 150px;">{% translate "Action" %}</th>
{% endif %}
</tr>
</thead>
{% for ops in timers %}
<tbody>
<tr>
<td class="text-center">{{ ops.operation_name }}</td>
<td class="text-center">{{ ops.doctrine }}</td>
<td class="text-center">
<td>
{{ ops.operation_name }}
{% if ops.type %}
<br>({{ ops.type }})
{% endif %}
</td>
<td>{{ ops.description }}</td>
<td>{{ ops.doctrine }}</td>
<td>
<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>
<td class="text-center" nowrap><div id="localtime{{ ops.id }}"></div><div id="countdown{{ ops.id }}"></div></td>
<td class="text-center">{{ ops.duration }}</td>
<td class="text-center">{{ ops.fc }}</td>
<td nowrap>{{ ops.start | date:"Y-m-d H:i" }}</td>
<td nowrap><div id="localtime{{ ops.id }}"></div><div id="countdown{{ ops.id }}"></div></td>
<td>{{ ops.duration }}</td>
<td>{{ ops.fc }}</td>
{% if perms.auth.optimer_management %}
<td class="text-center">{{ ops.eve_character }}</td>
<td class="text-center">
{# <td>{{ ops.eve_character }}</td>#}
<td class="text-right">
<a href="{% url 'optimer:remove' ops.id %}" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a><a href="{% url 'optimer:edit' ops.id %}" class="btn btn-info"><span class="glyphicon glyphicon-pencil"></span></a>
<span class="glyphicon glyphicon-remove"></span>
</a>
<a href="{% url 'optimer:edit' ops.id %}" class="btn btn-info">
<span class="glyphicon glyphicon-pencil"></span>
</a>
</td>
{% endif %}
</tr>

View File

@ -24,14 +24,14 @@
<br />
</div>
<h4><b>{% translate "Next Timers" %}</b></h4>
<h4><b>{% translate "Next Fleet Operations" %}</b></h4>
{% if future_timers %}
{% include "optimer/fleetoptable.html" with timers=future_timers %}
{% else %}
<div class="alert alert-warning text-center">{% translate "No upcoming timers." %}</div>
{% endif %}
<h4><b>{% translate "Past Timers" %}</b></h4>
<h4><b>{% translate "Past Fleet Operations" %}</b></h4>
{% if past_timers %}
{% include "optimer/fleetoptable.html" with timers=past_timers %}
{% else %}

View File

@ -9,7 +9,7 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from .form import OpForm
from .models import OpTimer
from .models import OpTimer, OpTimerType
logger = logging.getLogger(__name__)
@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
@permission_required('auth.optimer_view')
def optimer_view(request):
logger.debug("optimer_view called by user %s" % request.user)
base_query = OpTimer.objects.select_related('eve_character')
base_query = OpTimer.objects.select_related('eve_character', 'type')
render_items = {'optimer': base_query.all(),
'future_timers': base_query.filter(
start__gte=timezone.now()),
@ -33,9 +33,21 @@ def optimer_view(request):
def add_optimer_view(request):
logger.debug("add_optimer_view called by user %s" % request.user)
if request.method == 'POST':
form = OpForm(request.POST)
form = OpForm(request.POST, data_list=OpTimerType.objects.all())
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
if form.is_valid():
optimer_type = None
if form.cleaned_data['type'] != '':
try:
optimer_type = OpTimerType.objects.get(
type__iexact=form.cleaned_data['type']
)
except OpTimerType.DoesNotExist:
optimer_type = OpTimerType.objects.create(
type=form.cleaned_data['type']
)
# Get Current Time
post_time = timezone.now()
# Get character
@ -50,13 +62,15 @@ def add_optimer_view(request):
op.fc = form.cleaned_data['fc']
op.create_time = post_time
op.eve_character = character
op.type = optimer_type
op.description = form.cleaned_data['description']
op.save()
logger.info(f"User {request.user} created op timer with name {op.operation_name}")
messages.success(request, _('Created operation timer for %(opname)s.') % {"opname": op.operation_name})
return redirect("optimer:view")
else:
logger.debug("Returning new opForm")
form = OpForm()
form = OpForm(data_list=OpTimerType.objects.all())
render_items = {'form': form}
@ -80,10 +94,23 @@ def edit_optimer(request, optimer_id):
logger.debug(f"edit_optimer called by user {request.user} for optimer id {optimer_id}")
op = get_object_or_404(OpTimer, id=optimer_id)
if request.method == 'POST':
form = OpForm(request.POST)
form = OpForm(request.POST, data_list=OpTimerType.objects.all())
logger.debug("Received POST request containing update optimer form, is valid: %s" % form.is_valid())
if form.is_valid():
character = request.user.profile.main_character
optimer_type = None
if form.cleaned_data['type'] != '':
try:
optimer_type = OpTimerType.objects.get(
type__iexact=form.cleaned_data['type']
)
except OpTimerType.DoesNotExist:
optimer_type = OpTimerType.objects.create(
type=form.cleaned_data['type']
)
op.doctrine = form.cleaned_data['doctrine']
op.system = form.cleaned_data['system']
op.start = form.cleaned_data['start']
@ -91,6 +118,8 @@ def edit_optimer(request, optimer_id):
op.operation_name = form.cleaned_data['operation_name']
op.fc = form.cleaned_data['fc']
op.eve_character = character
op.type = optimer_type
op.description = form.cleaned_data['description']
logger.info(f"User {request.user} updating optimer id {optimer_id} ")
op.save()
messages.success(request, _('Saved changes to operation timer for %(opname)s.') % {"opname": op.operation_name})
@ -103,6 +132,8 @@ def edit_optimer(request, optimer_id):
'duration': op.duration,
'operation_name': op.operation_name,
'fc': op.fc,
'description': op.description,
'type': op.type
}
form = OpForm(initial=data)
form = OpForm(initial=data, data_list=OpTimerType.objects.all())
return render(request, 'optimer/update.html', context={'form': form})