Make a proper front page

This commit is contained in:
Mark Veidemanis 2022-11-29 07:20:39 +00:00
parent a39a5c3857
commit 242c9fbaed
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
5 changed files with 93 additions and 55 deletions

View File

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %} {% load static %}
{% load joinsep %} {% load joinsep %}
{% block outer_content %} {% block content %}
<div class="grid-stack" id="grid-stack-main"> <div class="grid-stack" id="grid-stack-main">
<!-- <div class="grid-stack-item" gs-w="5" gs-h="14" gs-y="0" gs-x="1"> <!-- <div class="grid-stack-item" gs-w="5" gs-h="14" gs-y="0" gs-x="1">
@ -17,7 +17,7 @@
</nav> </nav>
</div> </div>
</div> --> </div> -->
<div class="grid-stack-item" gs-w="4" gs-h="25" gs-y="0" gs-x="6"> <!-- <div class="grid-stack-item" gs-w="4" gs-h="25" gs-y="0" gs-x="6">
<div class="grid-stack-item-content"> <div class="grid-stack-item-content">
<nav class="panel"> <nav class="panel">
<p class="panel-heading" style="padding: .2em; line-height: .5em;"> <p class="panel-heading" style="padding: .2em; line-height: .5em;">
@ -29,7 +29,7 @@
</article> </article>
</nav> </nav>
</div> </div>
</div> </div> -->
<script> <script>
var grid = GridStack.init({ var grid = GridStack.init({
@ -46,57 +46,88 @@
// a widget is ready to be loaded // a widget is ready to be loaded
document.addEventListener('load-widget', function(event) { document.addEventListener('load-widget', function(event) {
let container = htmx.find('#widget'); let containers = htmx.findAll('#widget');
// get the scripts, they won't be run on the new element so we need to eval them console.log("CONTAINERS", containers);
var scripts = htmx.findAll(container, "script"); for (let x = 0, len = containers.length; x < len; x++) {
let widgetelement = container.firstElementChild.cloneNode(true); container = containers[x];
var new_id = widgetelement.id; console.log("CONTAINER", container);
// get the scripts, they won't be run on the new element so we need to eval them
let widgetelement = container.firstElementChild.cloneNode(true);
console.log(widgetelement);
var scripts = htmx.findAll(widgetelement, "script");
var new_id = widgetelement.id;
// check if there's an existing element like the one we want to swap // check if there's an existing element like the one we want to swap
let grid_element = htmx.find('#grid-stack-main'); let grid_element = htmx.find('#grid-stack-main');
let existing_widget = htmx.find(grid_element, "#"+new_id); let existing_widget = htmx.find(grid_element, "#"+new_id);
// get the size and position attributes // get the size and position attributes
if (existing_widget) { if (existing_widget) {
let attrs = existing_widget.getAttributeNames(); let attrs = existing_widget.getAttributeNames();
for (let i = 0, len = attrs.length; i < len; i++) { for (let i = 0, len = attrs.length; i < len; i++) {
if (attrs[i].startsWith('gs-')) { // only target gridstack attributes if (attrs[i].startsWith('gs-')) { // only target gridstack attributes
widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i])); widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i]));
}
} }
} }
} // clear the queue element
// clear the queue element container.outerHTML = "";
container.outerHTML = ""; // container.firstElementChild.outerHTML = "";
grid.addWidget(widgetelement); grid.addWidget(widgetelement);
// re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid // re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid
htmx.process(widgetelement); htmx.process(widgetelement);
// update the size of the widget according to its content // update the size of the widget according to its content
var added_widget = htmx.find(grid_element, "#"+new_id); var added_widget = htmx.find(grid_element, "#"+new_id);
var itemContent = htmx.find(added_widget, ".control"); var itemContent = htmx.find(added_widget, ".control");
var scrollheight = itemContent.scrollHeight+80; var scrollheight = itemContent.scrollHeight+80;
var verticalmargin = 0; var verticalmargin = 0;
var cellheight = grid.opts.cellHeight; var cellheight = grid.opts.cellHeight;
var height = Math.ceil((scrollheight + verticalmargin) / (cellheight + verticalmargin)); var height = Math.ceil((scrollheight + verticalmargin) / (cellheight + verticalmargin));
var opts = { var opts = {
h: height, h: height,
} }
grid.update( grid.update(
added_widget, added_widget,
opts opts
); );
// run the JS scripts inside the added element again // run the JS scripts inside the added element again
for (var i = 0; i < scripts.length; i++) { for (var i = 0; i < scripts.length; i++) {
eval(scripts[i].innerHTML); eval(scripts[i].innerHTML);
}
} }
// clear the containers we just added
// for (let x = 0, len = containers.length; x < len; x++) {
// container = containers[x];
// container.inner = "";
// }
grid.compact();
}); });
</script> </script>
<div <div>
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' <div
hx-get="{% url 'profit' type='widget' %}" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-target="#widgets-here" hx-get="{% url 'positions' type='widget' %}"
hx-trigger="load"></div> hx-target="#widgets-here"
hx-trigger="load"
hx-swap="afterend"
style="display: none;"></div>
<div
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'strategies' type='widget' %}"
hx-target="#widgets-here"
hx-trigger="load"
hx-swap="afterend"
style="display: none;"></div>
<div
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'profit' type='widget' %}"
hx-target="#widgets-here"
hx-trigger="load"
hx-swap="afterend"
style="display: none;"></div>
</div>
{% endblock %} {% endblock %}

View File

@ -15,10 +15,10 @@
<th>currency</th> <th>currency</th>
</thead> </thead>
{% for item in object_list %} {% for item in object_list %}
<tr class=" <tr class="
{% if item.pl > 0 %}has-background-success-light {% if item.pl > 0 %}has-background-success-light
{% elif item.pl < 0 %}has-background-danger-light {% elif item.pl < 0 %}has-background-danger-light
{% endif %}"> {% endif %}">
<td>{{ item.account.id }}</td> <td>{{ item.account.id }}</td>
<td>{{ item.account.name }}</td> <td>{{ item.account.name }}</td>
<td>{{ item.pl }}</td> <td>{{ item.pl }}</td>

View File

@ -1,5 +1,5 @@
<div id="widget"> <div id="widget">
<div id="widget-{{ unique }}" class="grid-stack-item" {% block widget_options %}gs-w="5" gs-h="1" gs-y="0" gs-x="1"{% endblock %}> <div id="widget-{{ unique }}" class="grid-stack-item" {% block widget_options %}{% if widget_options is None %}gs-w="6" gs-h="1" gs-y="7" gs-x="0"{% else %}{% autoescape off %}{{ widget_options }}{% endautoescape %}{% endif %}{% endblock %}>
<div class="grid-stack-item-content"> <div class="grid-stack-item-content">
<nav class="panel"> <nav class="panel">

View File

@ -93,6 +93,7 @@ class Positions(LoginRequiredMixin, OTPRequiredMixin, View):
"list_url": list_url, "list_url": list_url,
"context_object_name_singular": self.context_object_name_singular, "context_object_name_singular": self.context_object_name_singular,
"context_object_name": self.context_object_name, "context_object_name": self.context_object_name,
"widget_options": 'gs-w="12" gs-h="1" gs-y="0" gs-x="0"',
} }
# Return partials for HTMX # Return partials for HTMX
if self.request.htmx: if self.request.htmx:

View File

@ -5,15 +5,15 @@ from django.http import HttpResponseBadRequest
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
from django.views import View from django.views import View
from rest_framework.parsers import FormParser
from two_factor.views.mixins import OTPRequiredMixin from two_factor.views.mixins import OTPRequiredMixin
from core.exchanges import GenericAPIError from core.exchanges import GenericAPIError
from core.models import Account, Trade from core.models import Account
from core.util import logs from core.util import logs
log = logs.get_logger(__name__) log = logs.get_logger(__name__)
def get_profit(user): def get_profit(user):
items = [] items = []
accounts = Account.objects.filter(user=user) accounts = Account.objects.filter(user=user)
@ -21,12 +21,18 @@ def get_profit(user):
try: try:
details = account.client.get_account() details = account.client.get_account()
pl = details["pl"] pl = details["pl"]
item = {"account": account, "pl": float(pl), "balance": details["balance"], "currency": details["currency"]} item = {
"account": account,
"pl": float(pl),
"balance": details["balance"],
"currency": details["currency"],
}
items.append(item) items.append(item)
except GenericAPIError: except GenericAPIError:
continue continue
return items return items
class Profit(LoginRequiredMixin, OTPRequiredMixin, View): class Profit(LoginRequiredMixin, OTPRequiredMixin, View):
allowed_types = ["modal", "widget", "window", "page"] allowed_types = ["modal", "widget", "window", "page"]
window_content = "window-content/objects.html" window_content = "window-content/objects.html"
@ -65,7 +71,7 @@ class Profit(LoginRequiredMixin, OTPRequiredMixin, View):
} }
# Return partials for HTMX # Return partials for HTMX
if self.request.htmx: if self.request.htmx:
if request.headers["HX-Target"] == self.context_object_name+"-table": if request.headers["HX-Target"] == self.context_object_name + "-table":
self.template_name = self.list_template self.template_name = self.list_template
elif orig_type == "page": elif orig_type == "page":
self.template_name = self.list_template self.template_name = self.list_template