static: add admin shell to improve admin experience

This commit is contained in:
Jens Langhammer 2020-11-20 22:46:05 +01:00
parent 592f2cc558
commit 582dfface9
11 changed files with 249 additions and 188 deletions

View File

@ -1,180 +1,8 @@
{% extends "base/page.html" %}
{% load static %}
{% load i18n %}
{% load passbook_is_active %}
{% load passbook_utils %}
{% block head %}
{{ block.super }}
<script src="{% static 'node_modules/codemirror/lib/codemirror.js' %}"></script>
<script src="{% static 'node_modules/codemirror/addon/display/autorefresh.js' %}"></script>
<link rel="stylesheet" href="{% static 'node_modules/codemirror/lib/codemirror.css' %}">
<link rel="stylesheet" href="{% static 'node_modules/codemirror/theme/monokai.css' %}">
<script src="{% static 'node_modules/codemirror/mode/xml/xml.js' %}"></script>
<script src="{% static 'node_modules/codemirror/mode/yaml/yaml.js' %}"></script>
<script src="{% static 'node_modules/codemirror/mode/python/python.js' %}"></script>
{% endblock %}
{% block page_content %}
<div class="pf-c-page__sidebar">
<div class="pf-c-page__sidebar-body">
<nav class="pf-c-nav" id="page-default-nav-example-primary-nav" aria-label="Global">
<ul class="pf-c-nav__list">
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:overview' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:overview' %}">
{% trans 'Overview' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:applications' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:applications' 'passbook_admin:application-create' 'passbook_admin:application-update' 'passbook_admin:application-delete' %}">
{% trans 'Applications' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:sources' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:sources' 'passbook_admin:source-create' 'passbook_admin:source-update' 'passbook_admin:source-delete' %}">
{% trans 'Sources' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:providers' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:providers' 'passbook_admin:provider-create' 'passbook_admin:provider-update' 'passbook_admin:provider-delete' %}">
{% trans 'Providers' %}
</a>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Outposts' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:outposts' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:outposts' 'passbook_admin:outpost-create' 'passbook_admin:outpost-update' 'passbook_admin:outpost-delete' %}">
{% trans 'Outposts' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:outpost-service-connections' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:outpost-service-connections' 'passbook_admin:outpost-service-connections-create' 'passbook_admin:outpost-service-connections-update' 'passbook_admin:outpost-service-connections-delete' %}">
{% trans 'Service Connections' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:property-mappings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:property-mappings' 'passbook_admin:property-mapping-create' 'passbook_admin:property-mapping-update' 'passbook_admin:property-mapping-delete' %}">
{% trans 'Property Mappings' %}
</a>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Flows' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:flows' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:flows' 'passbook_admin:flow-create' 'passbook_admin:flow-update' 'passbook_admin:flow-delete' %}">
{% trans 'Flows' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:stage-bindings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-bindings' 'passbook_admin:stage-binding-create' 'passbook_admin:stage-binding-update' 'passbook_admin:stage-binding-delete' %}">
{% trans 'Bindings' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:stages' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stages' 'passbook_admin:stage-create' 'passbook_admin:stage-update' 'passbook_admin:stage-delete' %}">
{% trans 'Stages' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:stage-prompts' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-prompts' 'passbook_admin:stage-prompt-create' 'passbook_admin:stage-prompt-update' 'passbook_admin:stage-prompt-delete' %}">
{% trans 'Prompts' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:stage-invitations' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-invitations' 'passbook_admin:stage-invitation-create' 'passbook_admin:stage-invitation-delete' %}">
{% trans 'Invitations' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Policies' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav" aria-labelledby="subnav-title1">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:policies' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:policies' 'passbook_admin:policy-create' 'passbook_admin:policy-update' 'passbook_admin:policy-delete' 'passbook_admin:policy-test' %}">
{% trans 'Policies' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:policies-bindings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:policies-bindings' 'passbook_admin:policy-binding-create' 'passbook_admin:policy-binding-update' 'passbook_admin:policy-binding-delete' %}">
{% trans 'Bindings' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:certificate_key_pair' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:certificate_key_pair' 'passbook_admin:certificatekeypair-create' 'passbook_admin:certificatekeypair-update' 'passbook_admin:certificatekeypair-delete' %}">
{% trans 'Certificates' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:tokens' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:tokens' 'passbook_admin:token-delete' %}">
{% trans 'Tokens' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:users' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:users' 'passbook_admin:user-create' 'passbook_admin:user-update' 'passbook_admin:user-delete' %}">
{% trans 'Users' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:groups' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:groups' 'passbook_admin:group-create' 'passbook_admin:group-update' 'passbook_admin:group-delete' %}">
{% trans 'Groups' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:tasks' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:tasks' %}">
{% trans 'System Tasks' %}
</a>
</li>
</ul>
</nav>
</div>
</div>
<main role="main" class="pf-c-page__main" tabindex="-1" id="main-content">
{% block content %}
{% endblock %}
</main>
{% block content %}
{% endblock %}

View File

@ -277,8 +277,6 @@
</div>
</div>
</div>
<script src="{% static 'node_modules/chart.js/dist/Chart.bundle.min.js' %}"></script>
<script>
var ctx = document.getElementById('logins-last-metrics').getContext('2d');
fetch("{% url 'passbook_api:admin_metrics-list' %}").then(r => r.json()).then(r => {

View File

@ -0,0 +1,179 @@
{% extends "base/page.html" %}
{% load static %}
{% load i18n %}
{% load passbook_is_active %}
{% load passbook_utils %}
{% block head %}
{{ block.super }}
<script src="{% static 'node_modules/codemirror/lib/codemirror.js' %}"></script>
<script src="{% static 'node_modules/codemirror/addon/display/autorefresh.js' %}"></script>
<link rel="stylesheet" href="{% static 'node_modules/codemirror/lib/codemirror.css' %}">
<link rel="stylesheet" href="{% static 'node_modules/codemirror/theme/monokai.css' %}">
<script src="{% static 'node_modules/codemirror/mode/xml/xml.js' %}"></script>
<script src="{% static 'node_modules/codemirror/mode/yaml/yaml.js' %}"></script>
<script src="{% static 'node_modules/codemirror/mode/python/python.js' %}"></script>
<script src="{% static 'node_modules/chart.js/dist/Chart.bundle.min.js' %}"></script>
{% endblock %}
{% block page_content %}
<div class="pf-c-page__sidebar">
<div class="pf-c-page__sidebar-body">
<nav class="pf-c-nav" id="page-default-nav-example-primary-nav" aria-label="Global">
<ul class="pf-c-nav__list">
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:overview' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:overview' %}">
{% trans 'Overview' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:applications' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:applications' 'passbook_admin:application-create' 'passbook_admin:application-update' 'passbook_admin:application-delete' %}">
{% trans 'Applications' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:sources' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:sources' 'passbook_admin:source-create' 'passbook_admin:source-update' 'passbook_admin:source-delete' %}">
{% trans 'Sources' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:providers' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:providers' 'passbook_admin:provider-create' 'passbook_admin:provider-update' 'passbook_admin:provider-delete' %}">
{% trans 'Providers' %}
</a>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="" class="pf-c-nav__link" aria-expanded="true">{% trans 'Outposts' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:outposts' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:outposts' 'passbook_admin:outpost-create' 'passbook_admin:outpost-update' 'passbook_admin:outpost-delete' %}">
{% trans 'Outposts' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:outpost-service-connections' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:outpost-service-connections' 'passbook_admin:outpost-service-connections-create' 'passbook_admin:outpost-service-connections-update' 'passbook_admin:outpost-service-connections-delete' %}">
{% trans 'Service Connections' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:property-mappings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:property-mappings' 'passbook_admin:property-mapping-create' 'passbook_admin:property-mapping-update' 'passbook_admin:property-mapping-delete' %}">
{% trans 'Property Mappings' %}
</a>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="" class="pf-c-nav__link" aria-expanded="true">{% trans 'Flows' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:flows' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:flows' 'passbook_admin:flow-create' 'passbook_admin:flow-update' 'passbook_admin:flow-delete' %}">
{% trans 'Flows' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:stage-bindings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-bindings' 'passbook_admin:stage-binding-create' 'passbook_admin:stage-binding-update' 'passbook_admin:stage-binding-delete' %}">
{% trans 'Bindings' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:stages' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stages' 'passbook_admin:stage-create' 'passbook_admin:stage-update' 'passbook_admin:stage-delete' %}">
{% trans 'Stages' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:stage-prompts' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-prompts' 'passbook_admin:stage-prompt-create' 'passbook_admin:stage-prompt-update' 'passbook_admin:stage-prompt-delete' %}">
{% trans 'Prompts' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:stage-invitations' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:stage-invitations' 'passbook_admin:stage-invitation-create' 'passbook_admin:stage-invitation-delete' %}">
{% trans 'Invitations' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item pf-m-expanded">
<a href="" class="pf-c-nav__link" aria-expanded="true">{% trans 'Policies' %}
<span class="pf-c-nav__toggle">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
</a>
<section class="pf-c-nav__subnav" aria-labelledby="subnav-title1">
<ul class="pf-c-nav__simple-list">
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:policies' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:policies' 'passbook_admin:policy-create' 'passbook_admin:policy-update' 'passbook_admin:policy-delete' 'passbook_admin:policy-test' %}">
{% trans 'Policies' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:policies-bindings' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:policies-bindings' 'passbook_admin:policy-binding-create' 'passbook_admin:policy-binding-update' 'passbook_admin:policy-binding-delete' %}">
{% trans 'Bindings' %}
</a>
</li>
</ul>
</section>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:certificate_key_pair' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:certificate_key_pair' 'passbook_admin:certificatekeypair-create' 'passbook_admin:certificatekeypair-update' 'passbook_admin:certificatekeypair-delete' %}">
{% trans 'Certificates' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:tokens' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:tokens' 'passbook_admin:token-delete' %}">
{% trans 'Tokens' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:users' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:users' 'passbook_admin:user-create' 'passbook_admin:user-update' 'passbook_admin:user-delete' %}">
{% trans 'Users' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:groups' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:groups' 'passbook_admin:group-create' 'passbook_admin:group-update' 'passbook_admin:group-delete' %}">
{% trans 'Groups' %}
</a>
</li>
<li class="pf-c-nav__item">
<a href="#{% url 'passbook_admin:tasks' %}"
class="pf-c-nav__link {% is_active 'passbook_admin:tasks' %}">
{% trans 'System Tasks' %}
</a>
</li>
</ul>
</nav>
</div>
</div>
<pb-admin-shell defaultUrl="{% url 'passbook_admin:overview' %}" role="main" class="pf-c-page__main" tabindex="-1" id="main-content">
</pb-admin-shell>
{% endblock %}

View File

@ -21,10 +21,12 @@ from passbook.admin.views import (
tasks,
tokens,
users,
shell,
)
urlpatterns = [
path("", overview.AdministrationOverviewView.as_view(), name="overview"),
path("", shell.ShellView.as_view(), name="shell"),
path("overview/", overview.AdministrationOverviewView.as_view(), name="overview"),
# Applications
path(
"applications/", applications.ApplicationListView.as_view(), name="applications"

View File

@ -0,0 +1,6 @@
from django.views.generic.base import TemplateView
class ShellView(TemplateView):
template_name = "administration/shell.html"

View File

@ -35,7 +35,7 @@
href="{% url 'passbook_core:overview' %}">{% trans 'Access' %}</a></li>
{% if user.is_superuser %}
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_app 'passbook_admin' %}"
href="{% url 'passbook_admin:overview' %}">{% trans 'Administrate' %}</a></li>
href="{% url 'passbook_admin:shell' %}">{% trans 'Administrate' %}</a></li>
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_audit:log' %}"
href="{% url 'passbook_audit:log' %}">{% trans 'Monitor' %}</a></li>
{% endif %}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,50 @@
import { customElement, html, LitElement, property } from "lit-element";
@customElement("pb-admin-shell")
export class AdminSiteShell extends LitElement {
@property()
set defaultUrl(value: string) {
if (window.location.hash === "" && value !== undefined) {
window.location.hash = `#${value}`;
}
}
createRenderRoot() {
return this;
}
constructor() {
super();
this.loadContent();
window.addEventListener("hashchange", (e) => this.loadContent());
}
loadContent() {
let url = window.location.hash.slice(1, Infinity);
if (url === "") {
return
}
fetch(url).then(r => r.text()).then((t) => {
this.innerHTML = t;
}).then(() => {
this.querySelectorAll("a").forEach(a => {
if (a.href === "") {
return;
}
try {
const url = new URL(a.href);
const qs = url.search || "";
a.href = `#${url.pathname}${qs}`;
} catch (e) {
a.href = `#${a.href}`;
}
});
});
}
render() {
return html`${this.innerHTML}`;
}
}

View File

@ -10,9 +10,6 @@ export class DropdownButton extends LitElement {
btn.addEventListener("click", e => {
menu.hidden = !menu.hidden;
});
btn.addEventListener("blur", e => {
menu.hidden = true;
});
});
}

View File

@ -7,3 +7,4 @@ import './FlowShellCard';
import './Messages';
import './Tabs';
import './ModalButton';
import './AdminSiteShell';