Implement alias editing views and templates

This commit is contained in:
Mark Veidemanis 2022-08-01 18:47:29 +01:00
parent 5a66236828
commit 6b0851ab6f
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
8 changed files with 152 additions and 61 deletions

View File

@ -35,6 +35,7 @@ from core.views.manage.threshold.irc import (
ThresholdIRCNetworkRelayStatus,
ThresholdIRCNetworks,
ThresholdIRCStats,
ThresholdIRCAliasesEdit,
)
# Management stuff
@ -155,6 +156,11 @@ urlpatterns = [
ThresholdIRCAliases.as_view(),
name="threshold_irc_aliases",
),
path(
"manage/threshold/irc/aliases/edit/",
ThresholdIRCAliasesEdit.as_view(),
name="threshold_irc_aliases_edit",
),
path(
"manage/threshold/irc/network/<str:net>/actions/",
ThresholdIRCNetworkActions.as_view(),

17
core/static/modal.js Normal file
View File

@ -0,0 +1,17 @@
var modal = document.querySelector('.modal'); // assuming you have only 1
var html = document.querySelector('html');
modal.querySelector('.modal-background').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
modal.querySelector('.modal-close').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
modal.querySelector('.modal-close-button').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});

7
core/static/tabs.css Normal file
View File

@ -0,0 +1,7 @@
#tab-content div {
display: none;
}
#tab-content div.is-active {
display: block;
}

35
core/static/tabs.js Normal file
View File

@ -0,0 +1,35 @@
// tabbed browsing for the modal
function initTabs() {
TABS.forEach((tab) => {
tab.addEventListener('click', (e) => {
let selected = tab.getAttribute('data-tab');
updateActiveTab(tab);
updateActiveContent(selected);
})
})
}
function updateActiveTab(selected) {
TABS.forEach((tab) => {
if (tab && tab.classList.contains(ACTIVE_CLASS)) {
tab.classList.remove(ACTIVE_CLASS);
}
});
selected.classList.add(ACTIVE_CLASS);
}
function updateActiveContent(selected) {
CONTENT.forEach((item) => {
if (item && item.classList.contains(ACTIVE_CLASS)) {
item.classList.remove(ACTIVE_CLASS);
}
let data = item.getAttribute('data-content');
if (data === selected) {
item.classList.add(ACTIVE_CLASS);
}
});
}
var TABS = [...document.querySelectorAll('#tabs li')];
var CONTENT = [...document.querySelectorAll('#tab-content div')];
var ACTIVE_CLASS = 'is-active';
initTabs();

View File

@ -36,6 +36,16 @@
</tbody>
</table>
</div>
</div>
<div hx-target="#modals-here">
<button hx-get="{% url 'threshold_irc_aliases_edit' %}" class="button is-primary is-fullwidth">
<span class="icon" data-tooltip="Edit">
<i class="fa-solid fa-pencil" aria-hidden="true"></i>
</span>
</button>
</div>
{% endif %}
<div id="modals-here">
</div>
</div>

View File

@ -0,0 +1,73 @@
{% load index %}
{% load static %}
{% load joinsep %}
<script src="{% static 'modal.js' %}"></script>
<div class="modal is-active is-clipped">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<h4 class="subtitle is-4">Edit aliases</h4>
<form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_aliases_edit' %}"
hx-target="#aliases"
hx-swap="outerHTML">
<div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container">
<table class="table is-fullwidth is-hoverable">
<thead>
<th>num</th>
<th>nick</th>
<th>realname</th>
<th>emails</th>
</thead>
<tbody>
{% for alias in aliases %}
<tr>
<td>
{{ alias.num }}
</td>
<td>
<div class="field">
<input class="input" type="text" name="{{ alias.num }}|nick" value="{{ alias.nick }}">
</div>
</td>
<td>
<div class="field">
<input class="input" type="text" name="{{ alias.num }}|realname" value="{{ alias.realname }}">
</div>
</td>
<td>
<div class="field">
<textarea class="textarea" name="{{ alias.num }}|emails">{{ alias.emails|joinsep:'\n' }}</textarea>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<button
class="button is-primary modal-close-button">
Cancel
</button>
<button class="button is-primary modal-close-button">Submit</button>
</form>
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div>

View File

@ -1,33 +1,9 @@
{% load index %}
{% load static %}
<script>
var modal = document.querySelector('.modal'); // assuming you have only 1
var html = document.querySelector('html');
modal.querySelector('.modal-background').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
modal.querySelector('.modal-close').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
var TABS = [...document.querySelectorAll('#tabs li')];
var CONTENT = [...document.querySelectorAll('#tab-content div')];
var ACTIVE_CLASS = 'is-active';
initTabs();
</script>
<style>
#tab-content div {
display: none;
}
#tab-content div.is-active {
display: block;
}
</style>
<script src="{% static 'modal.js' %}"></script>
<link rel ="stylesheet" href="{% static 'tabs.css' %}">
<script src="{% static 'tabs.js' %}"></script>
<div class="modal is-active is-clipped">
<div class="modal-background"></div>
<div class="modal-content">

View File

@ -2,39 +2,6 @@
{% load static %}
{% block content %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
// tabbed browsing for the modal
function initTabs() {
TABS.forEach((tab) => {
tab.addEventListener('click', (e) => {
let selected = tab.getAttribute('data-tab');
updateActiveTab(tab);
updateActiveContent(selected);
})
})
}
function updateActiveTab(selected) {
TABS.forEach((tab) => {
if (tab && tab.classList.contains(ACTIVE_CLASS)) {
tab.classList.remove(ACTIVE_CLASS);
}
});
selected.classList.add(ACTIVE_CLASS);
}
function updateActiveContent(selected) {
CONTENT.forEach((item) => {
if (item && item.classList.contains(ACTIVE_CLASS)) {
item.classList.remove(ACTIVE_CLASS);
}
let data = item.getAttribute('data-content');
if (data === selected) {
item.classList.add(ACTIVE_CLASS);
}
});
}
</script>
<div class="box">
<form method="POST">
{% csrf_token %}