admin: migrate overview data-target modals
This commit is contained in:
parent
322ad0890a
commit
6681289a5a
18
passbook/admin/forms/overview.py
Normal file
18
passbook/admin/forms/overview.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
"""Forms for modals on overview page"""
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyCacheClearForm(forms.Form):
|
||||||
|
"""Form to clear Policy cache"""
|
||||||
|
|
||||||
|
title = "Clear Policy cache"
|
||||||
|
body = """Are you sure you want to clear the policy cache?
|
||||||
|
This will cause all policies to be re-evaluated on their next usage."""
|
||||||
|
|
||||||
|
|
||||||
|
class FlowCacheClearForm(forms.Form):
|
||||||
|
"""Form to clear Flow cache"""
|
||||||
|
|
||||||
|
title = "Clear Flow cache"
|
||||||
|
body = """Are you sure you want to clear the flow cache?
|
||||||
|
This will cause all flows to be re-evaluated on their next usage."""
|
|
@ -179,9 +179,12 @@
|
||||||
<div class="pf-c-card__header-main">
|
<div class="pf-c-card__header-main">
|
||||||
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Policies' %}
|
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Policies' %}
|
||||||
</div>
|
</div>
|
||||||
<a data-target="modal" data-modal="clearPolicyCache">
|
<pb-modal-button href="{% url 'passbook_admin:overview-clear-policy-cache' %}">
|
||||||
<i class="fa fa-trash"> </i>
|
<a slot="trigger">
|
||||||
</a>
|
<i class="fa fa-trash"> </i>
|
||||||
|
</a>
|
||||||
|
<div slot="modal"></div>
|
||||||
|
</pb-modal-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
{% if cached_policies < 1 %}
|
{% if cached_policies < 1 %}
|
||||||
|
@ -202,9 +205,12 @@
|
||||||
<div class="pf-c-card__header-main">
|
<div class="pf-c-card__header-main">
|
||||||
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Flows' %}
|
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Flows' %}
|
||||||
</div>
|
</div>
|
||||||
<a data-target="modal" data-modal="clearFlowCache">
|
<pb-modal-button href="{% url 'passbook_admin:overview-clear-flow-cache' %}">
|
||||||
<i class="fa fa-trash"> </i>
|
<a slot="trigger">
|
||||||
</a>
|
<i class="fa fa-trash"> </i>
|
||||||
|
</a>
|
||||||
|
<div slot="modal"></div>
|
||||||
|
</pb-modal-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
{% if cached_flows < 1 %}
|
{% if cached_flows < 1 %}
|
||||||
|
@ -221,60 +227,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="pf-c-backdrop" id="clearPolicyCache" hidden>
|
|
||||||
<div class="pf-l-bullseye">
|
|
||||||
<div class="pf-c-modal-box pf-m-sm" role="dialog">
|
|
||||||
<button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
|
|
||||||
<i class="fas fa-times" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<div class="pf-c-modal-box__header">
|
|
||||||
<h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Clear Policy Cache' %}?</h1>
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-modal-box__body" id="modal-description">
|
|
||||||
<form method="post" id="clear_policies">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="clear_policies">
|
|
||||||
<p>
|
|
||||||
{% blocktrans %}
|
|
||||||
Are you sure you want to clear the policy cache? This will cause all policies to be re-evaluated on their next usage.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<footer class="pf-c-modal-box__footer pf-m-align-left">
|
|
||||||
<button form="clear_policies" class="pf-c-button pf-m-primary" type="submit">{% trans 'Clear' %}</button>
|
|
||||||
<button data-modal-close class="pf-c-button pf-m-link" type="button">{% trans 'Cancel' %}</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pf-c-backdrop" id="clearFlowCache" hidden>
|
|
||||||
<div class="pf-l-bullseye">
|
|
||||||
<div class="pf-c-modal-box pf-m-sm" role="dialog">
|
|
||||||
<button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
|
|
||||||
<i class="fas fa-times" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<div class="pf-c-modal-box__header">
|
|
||||||
<h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Clear Flow Cache' %}?</h1>
|
|
||||||
</div>
|
|
||||||
<div class="pf-c-modal-box__body" id="modal-description">
|
|
||||||
<form method="post" id="clear_flows">
|
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="clear_flows">
|
|
||||||
<p>
|
|
||||||
{% blocktrans %}
|
|
||||||
Are you sure you want to clear the flow cache? This will cause all flows to be re-evaluated on their next usage.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<footer class="pf-c-modal-box__footer pf-m-align-left">
|
|
||||||
<button form="clear_flows" class="pf-c-button pf-m-primary" type="submit">{% trans 'Clear' %}</button>
|
|
||||||
<button data-modal-close class="pf-c-button pf-m-link" type="button">{% trans 'Cancel' %}</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
20
passbook/admin/templates/generic/form_non_model.html
Normal file
20
passbook/admin/templates/generic/form_non_model.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends base_template|default:"generic/form.html" %}
|
||||||
|
|
||||||
|
{% load passbook_utils %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block above_form %}
|
||||||
|
<h1>
|
||||||
|
{% trans form.title %}
|
||||||
|
</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block beneath_form %}
|
||||||
|
<p>
|
||||||
|
{% trans form.body %}
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block action %}
|
||||||
|
{% trans 'Confirm' %}
|
||||||
|
{% endblock %}
|
|
@ -26,6 +26,16 @@ from passbook.admin.views import (
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", shell.ShellView.as_view(), name="shell"),
|
path("", shell.ShellView.as_view(), name="shell"),
|
||||||
|
path(
|
||||||
|
"overview/cache/flow/",
|
||||||
|
overview.FlowCacheClearView.as_view(),
|
||||||
|
name="overview-clear-flow-cache",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"overview/cache/policy/",
|
||||||
|
overview.PolicyCacheClearView.as_view(),
|
||||||
|
name="overview-clear-policy-cache",
|
||||||
|
),
|
||||||
path("overview/", overview.AdministrationOverviewView.as_view(), name="overview"),
|
path("overview/", overview.AdministrationOverviewView.as_view(), name="overview"),
|
||||||
# Applications
|
# Applications
|
||||||
path(
|
path(
|
||||||
|
|
|
@ -2,14 +2,20 @@
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db.models.fields.json import KeyTextTransform
|
from django.db.models.fields.json import KeyTextTransform
|
||||||
from django.views.generic import TemplateView
|
from django.http.request import HttpRequest
|
||||||
|
from django.http.response import HttpResponse
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
from django.views.generic import FormView, TemplateView
|
||||||
from packaging.version import LegacyVersion, Version, parse
|
from packaging.version import LegacyVersion, Version, parse
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook import __version__
|
from passbook import __version__
|
||||||
|
from passbook.admin.forms.overview import FlowCacheClearForm, PolicyCacheClearForm
|
||||||
from passbook.admin.mixins import AdminRequiredMixin
|
from passbook.admin.mixins import AdminRequiredMixin
|
||||||
from passbook.admin.tasks import VERSION_CACHE_KEY, update_latest_version
|
from passbook.admin.tasks import VERSION_CACHE_KEY, update_latest_version
|
||||||
from passbook.audit.models import Event, EventAction
|
from passbook.audit.models import Event, EventAction
|
||||||
|
@ -24,18 +30,6 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
|
||||||
|
|
||||||
template_name = "administration/overview.html"
|
template_name = "administration/overview.html"
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
|
||||||
"""Handle post (clear cache from modal)"""
|
|
||||||
if "clear_policies" in self.request.POST:
|
|
||||||
keys = cache.keys("policy_*")
|
|
||||||
cache.delete_many(keys)
|
|
||||||
LOGGER.debug("Cleared Policy cache", keys=len(keys))
|
|
||||||
if "clear_flows" in self.request.POST:
|
|
||||||
keys = cache.keys("flow_*")
|
|
||||||
cache.delete_many(keys)
|
|
||||||
LOGGER.debug("Cleared flow cache", keys=len(keys))
|
|
||||||
return self.get(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_latest_version(self) -> Union[LegacyVersion, Version]:
|
def get_latest_version(self) -> Union[LegacyVersion, Version]:
|
||||||
"""Get latest version from cache"""
|
"""Get latest version from cache"""
|
||||||
version_in_cache = cache.get(VERSION_CACHE_KEY)
|
version_in_cache = cache.get(VERSION_CACHE_KEY)
|
||||||
|
@ -75,3 +69,35 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
|
||||||
kwargs["cached_policies"] = len(cache.keys("policy_*"))
|
kwargs["cached_policies"] = len(cache.keys("policy_*"))
|
||||||
kwargs["cached_flows"] = len(cache.keys("flow_*"))
|
kwargs["cached_flows"] = len(cache.keys("flow_*"))
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
|
||||||
|
"""View to clear Policy cache"""
|
||||||
|
|
||||||
|
form_class = PolicyCacheClearForm
|
||||||
|
|
||||||
|
template_name = "generic/form_non_model.html"
|
||||||
|
success_url = reverse_lazy("passbook_admin:overview")
|
||||||
|
success_message = _("Successfully cleared Policy cache")
|
||||||
|
|
||||||
|
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||||
|
keys = cache.keys("policy_*")
|
||||||
|
cache.delete_many(keys)
|
||||||
|
LOGGER.debug("Cleared Policy cache", keys=len(keys))
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class FlowCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
|
||||||
|
"""View to clear Flow cache"""
|
||||||
|
|
||||||
|
form_class = FlowCacheClearForm
|
||||||
|
|
||||||
|
template_name = "generic/form_non_model.html"
|
||||||
|
success_url = reverse_lazy("passbook_admin:overview")
|
||||||
|
success_message = _("Successfully cleared Flow cache")
|
||||||
|
|
||||||
|
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||||
|
keys = cache.keys("flow_*")
|
||||||
|
cache.delete_many(keys)
|
||||||
|
LOGGER.debug("Cleared flow cache", keys=len(keys))
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
2
passbook/static/static/dist/main.js.map
vendored
2
passbook/static/static/dist/main.js.map
vendored
File diff suppressed because one or more lines are too long
|
@ -7,11 +7,6 @@ import BullseyeStyle from "@patternfly/patternfly/layouts/Bullseye/bullseye.css"
|
||||||
import BackdropStyle from "@patternfly/patternfly/components/Backdrop/backdrop.css";
|
import BackdropStyle from "@patternfly/patternfly/components/Backdrop/backdrop.css";
|
||||||
import { updateMessages } from "./Messages";
|
import { updateMessages } from "./Messages";
|
||||||
|
|
||||||
const PRIMARY_CLASS = "pf-m-primary";
|
|
||||||
const SUCCESS_CLASS = "pf-m-success";
|
|
||||||
const ERROR_CLASS = "pf-m-danger";
|
|
||||||
const PROGRESS_CLASSES = ["pf-m-progress", "pf-m-in-progress"];
|
|
||||||
|
|
||||||
@customElement("pb-modal-button")
|
@customElement("pb-modal-button")
|
||||||
export class ModalButton extends LitElement {
|
export class ModalButton extends LitElement {
|
||||||
|
|
||||||
|
|
|
@ -40,23 +40,6 @@ document.querySelectorAll(".pf-c-check__label").forEach((checkLabel) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// CodeMirror
|
|
||||||
// document.querySelectorAll(".codemirror").forEach((cm) => {
|
|
||||||
// let cmMode = 'xml';
|
|
||||||
// if ('data-cm-mode' in cm.attributes) {
|
|
||||||
// cmMode = cm.attributes['data-cm-mode'].value;
|
|
||||||
// }
|
|
||||||
// // https://github.com/codemirror/CodeMirror/issues/5092
|
|
||||||
// cm.removeAttribute("required");
|
|
||||||
// CodeMirror.fromTextArea(cm, {
|
|
||||||
// mode: cmMode,
|
|
||||||
// theme: 'monokai',
|
|
||||||
// lineNumbers: false,
|
|
||||||
// readOnly: cm.readOnly,
|
|
||||||
// autoRefresh: true,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Automatic slug fields
|
// Automatic slug fields
|
||||||
const convertToSlug = (text) => {
|
const convertToSlug = (text) => {
|
||||||
return text
|
return text
|
||||||
|
|
Reference in a new issue