Allow changing the asset filter list

master
Mark Veidemanis 1 year ago
parent da9f32e882
commit 287facbab2
Signed by: m
GPG Key ID: 5ACFCEED46C0904F

@ -284,4 +284,20 @@ urlpatterns = [
assets.AssetRestrictionDelete.as_view(),
name="assetrestriction_delete",
),
# Asset group filters
path(
"assetfilter/<str:group_id>/flip/<str:symbol>/",
assets.AssetFilterFlip.as_view(),
name="assetfilter_flip",
),
path(
"assetfilter/<str:group_id>/delete/<str:symbol>/",
assets.AssetFilterDelete.as_view(),
name="assetfilter_delete",
),
path(
"assetfilter/<str:type>/view/<str:group_id>/",
assets.AssetFilterList.as_view(),
name="assetfilters",
),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

@ -94,7 +94,7 @@ class RiskModelAdmin(admin.ModelAdmin):
class AssetGroupAdmin(admin.ModelAdmin):
list_display = ("user", "name", "description", "account")
list_display = ("user", "name", "description")
class AssetRestrictionAdmin(admin.ModelAdmin):

@ -309,12 +309,10 @@ class AssetGroupForm(RestrictedFormMixin, ModelForm):
fields = (
"name",
"description",
"account",
)
help_texts = {
"name": "Name of the asset group. Informational only.",
"description": "Description of the asset group. Informational only.",
"account": "Account to pull assets from.",
}

@ -0,0 +1,17 @@
# Generated by Django 4.1.6 on 2023-02-11 18:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0057_alter_assetgroup_account_and_more'),
]
operations = [
migrations.RemoveField(
model_name='assetgroup',
name='account',
),
]

@ -411,11 +411,6 @@ class AssetGroup(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
# Account for checking pairs on children if specified
account = models.ForeignKey(
Account, on_delete=models.PROTECT, null=True, blank=True
)
# Dict like {"RUB": True, "USD": False}
allowed = models.JSONField(null=True, blank=True, default=dict)

@ -0,0 +1,59 @@
{% load cache %}
{% load cachalot cache %}
{% get_last_invalidation 'core.AssetGroup' as last %}
{% include 'mixins/partials/notify.html' %}
{% cache 600 objects_assetgroups_field request.user.id object_list last %}
<table
class="table is-fullwidth is-hoverable"
hx-target="#{{ context_object_name }}-table"
id="{{ context_object_name }}-table"
hx-swap="outerHTML"
hx-trigger="{{ context_object_name_singular }}Event from:body"
hx-get="{{ list_url }}">
<thead>
<th>symbol</th>
<th>status</th>
<th>actions</th>
</thead>
{% for key, item in object_list.items %}
<tr class="
{% if item is True %}has-background-success-light
{% elif item is False %}has-background-danger-light
{% endif %}">
<td>{{ key }}</td>
<td>{{ item }}</td>
<td>
<div class="buttons">
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'assetfilter_flip' group_id=group_id symbol=key %}"
hx-trigger="click"
hx-target="#modals-here"
hx-swap="innerHTML"
class="button">
<span class="icon-text">
<span class="icon" data-tooltip="Flip direction">
<i class="fa-solid fa-arrows-repeat"></i>
</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-delete="{% url 'assetfilter_delete' group_id=group_id symbol=key %}"
hx-trigger="click"
hx-target="#modals-here"
hx-swap="innerHTML"
class="button">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-xmark"></i>
</span>
</span>
</button>
</div>
</td>
</tr>
{% endfor %}
</table>
{% endcache %}

@ -15,7 +15,6 @@
<th>user</th>
<th>name</th>
<th>description</th>
<th>account</th>
<th>status</th>
<th>restrictions</th>
<th>actions</th>
@ -26,8 +25,16 @@
<td>{{ item.user }}</td>
<td>{{ item.name }}</td>
<td>{{ item.description }}</td>
<td>{{ item.account }}</td>
<td>{{ item.matches }}</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'assetfilters' type=type group_id=item.id %}"
hx-trigger="click"
hx-target="#{{ type }}s-here"
hx-swap="innerHTML">
{{ item.matches }}
</a>
</td>
<td>{{ item.restrictions }}</td>
<td>
<div class="buttons">

@ -3,7 +3,16 @@ import json
from cachalot.api import invalidate
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
from django.shortcuts import render
from django.views import View
from mixins.views import (
AbortSave,
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectNameMixin,
ObjectUpdate,
)
from rest_framework import status
from rest_framework.parsers import JSONParser
from rest_framework.views import APIView
@ -154,3 +163,68 @@ class AssetRestrictionAPI(APIView):
return HttpResponse(status=status.HTTP_200_OK)
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
# Asset group allowed field
class AssetFilterList(LoginRequiredMixin, ObjectList):
list_template = "partials/asset-filter-list.html"
page_title = "List of asset filters."
page_subtitle = None
context_object_name_singular = "asset filter"
context_object_name = "asset filters"
list_url_name = "assetfilters"
list_url_args = ["type", "group_id"]
def get_queryset(self, **kwargs):
group_id = kwargs.get("group_id", None)
self.extra_context = {"group_id": group_id}
try:
group = AssetGroup.objects.get(id=group_id, user=self.request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return self.render_to_response(context)
return group.allowed
class AssetFilterFlip(LoginRequiredMixin, ObjectNameMixin, View):
template_name = "mixins/partials/notify.html"
model = AssetGroup
def get(self, request, group_id, symbol):
try:
group = AssetGroup.objects.get(id=group_id, user=request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return render(request, self.template_name, context)
if symbol not in group.allowed:
context = {"message": "Asset filter does not exist", "class": "danger"}
return render(request, self.template_name, context)
group.allowed[symbol] = not group.allowed[symbol]
group.save()
context = {"message": "Asset filter updated", "class": "success"}
response = render(request, self.template_name, context)
response["HX-Trigger"] = "assetgroupEvent"
return response
class AssetFilterDelete(LoginRequiredMixin, ObjectNameMixin, View):
template_name = "mixins/partials/notify.html"
model = AssetGroup
def delete(self, request, group_id, symbol):
try:
group = AssetGroup.objects.get(id=group_id, user=request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return render(request, self.template_name, context)
if symbol not in group.allowed:
context = {"message": "Asset filter does not exist", "class": "danger"}
return render(request, self.template_name, context)
del group.allowed[symbol]
group.save()
context = {"message": "Asset filter deleted", "class": "success"}
response = render(request, self.template_name, context)
response["HX-Trigger"] = "assetgroupEvent"
return response

Loading…
Cancel
Save