ui: clean up more generic forms, remove is_login everywhere

This commit is contained in:
Jens Langhammer 2020-02-21 15:00:45 +01:00
parent ea6a1422f7
commit b6326f399c
22 changed files with 423 additions and 239 deletions

View file

@ -1,7 +1 @@
{% extends "overview/base.html" %}
{% load i18n %}
{% load is_active %}
{% block nav_secondary %}
{% endblock %}

View file

@ -24,18 +24,35 @@
{% endblock %}
{% block content %}
<div class="container">
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
{% block above_form %}
{% endblock %}
<div class="">
<form action="" method="post" class="form-horizontal">
{% include 'partials/form.html' with form=form %}
</div>
</section>
<section class="pf-c-page__main-section">
<div class="pf-l-stack">
<div class="pf-l-stack__item">
<div class="pf-c-card">
<div class="pf-c-card__body">
<form action="" method="post" class="pf-c-form pf-m-horizontal">
{% include 'partials/form_horizontal.html' with form=form %}
{% block beneath_form %}
{% endblock %}
<a class="btn btn-default" href="{% back %}">{% trans "Cancel" %}</a>
<input type="submit" class="btn btn-primary" value="{% block action %}{% endblock %}" />
<div class="pf-c-form__group pf-m-action">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-primary" type="submit" value="{% block action %}{% endblock %}" />
<a class="pf-c-button pf-m-secondary" href="{% back %}">{% trans "Cancel" %}</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
<script>
const attributes = document.getElementsByName('attributes');
if (attributes.length > 0) {
@ -58,7 +75,6 @@
});
}
</script>
</div>
{% endblock %}
{% block scripts %}

View file

@ -1,29 +0,0 @@
{% extends "administration/base.html" %}
{% load i18n %}
{% load utils %}
{% block content %}
<div class="container">
{% block above_table %}
{% endblock %}
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Class' %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for source in object_list %}
<tr>
<td>{{ source.name }}</td>
<td>{{ source.cast|fieldtype }}</td>
<td><a href="{% url 'passbook_admin:source-update' pk=source.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View file

@ -14,10 +14,11 @@
</style>
{% endblock %}
{% block card_title %}
{% trans 'Bad Request' %}
{% endblock %}
{% block card %}
<header class="login-pf-header">
<h1>{% trans 'Bad Request' %}</h1>
</header>
<form>
{% if message %}
<h3>{% trans message %}</h3>

View file

@ -4,12 +4,23 @@
{% load utils %}
{% block content %}
<div class="container">
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
{% block above_form %}
<h1>{% blocktrans with object_type=object|verbose_name %}Delete {{ object_type }}{% endblocktrans %}</h1>
<h1>
{% blocktrans with object_type=object|verbose_name %}
Delete {{ object_type }}
{% endblocktrans %}
</h1>
{% endblock %}
<div class="">
<form method="post" class="form-horizontal">
</div>
</section>
<section class="pf-c-page__main-section">
<div class="pf-l-stack">
<div class="pf-l-stack__item">
<div class="pf-c-card">
<div class="pf-c-card__body">
<form action="" method="post" class="pf-c-form">
{% csrf_token %}
<p>
{% blocktrans with object_type=object|verbose_name name=object %}
@ -17,9 +28,16 @@
{% endblocktrans %}
</p>
<input type="hidden" name="confirmdelete" value="yes">
<a href="{% back %}" class="btn btn-default">{% trans 'Back' %}</a>
<input type="submit" class="btn btn-danger" value="{% trans 'Delete' %}" />
<div class="pf-c-form__group pf-m-action">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-danger" type="submit" value="{% trans 'Delete' %}" />
<a class="pf-c-button pf-m-secondary" href="{% back %}">{% trans "Back" %}</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
{% endblock %}

View file

@ -17,6 +17,7 @@
</filter>
</svg>
</div>
{% include 'partials/messages.html' %}
<div class="pf-c-login">
<div class="pf-c-login__container">
<header class="pf-c-login__header">
@ -27,12 +28,16 @@
</header>
<main class="pf-c-login__main">
<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">{% trans title %}</h1>
<h1 class="pf-c-title pf-m-3xl">
{% block card_title %}
{% trans title %}
{% endblock %}
</h1>
</header>
<div class="pf-c-login__main-body">
{% block card %}
<form method="POST" class="pf-c-form">
{% include 'partials/form_login_pf4.html' %}
{% include 'partials/form.html' %}
<div class="pf-c-form__group pf-m-action">
<button class="pf-c-button pf-m-primary pf-m-block" type="submit">Log in</button>
</div>
@ -71,7 +76,7 @@
<p></p>
<ul class="pf-c-list pf-m-inline">
<li>
<a href="https://beryju.github.io/passbook/">Help</a>
<a href="https://beryju.github.io/passbook/">{% trans 'Documentation' %}</a>
</li>
<!-- todo: load config.passbook.footer.links -->
</ul>

View file

@ -20,7 +20,7 @@
</header>
<form method="POST">
{% csrf_token %}
{% include 'partials/form_login_pf4.html' %}
{% include 'partials/form.html' %}
<span class="pf-icon pficon-error-circle-o btn-block"></span>
Access denied
{% if 'back' in request.GET %}

View file

@ -7,7 +7,9 @@
<form method="POST" class="pf-c-form">
{% block above_form %}
{% endblock %}
{% include 'partials/form_login_pf4.html' %}
{% include 'partials/form.html' %}
{% block beneath_form %}
{% endblock %}
<div class="pf-c-form__group pf-m-action">

View file

@ -1,50 +1,52 @@
{% load utils %}
{% load i18n %}
{% csrf_token %}
{% for field in form %}
<div class="form-group {% if field.errors %} has-error {% endif %}">
<div class="pf-c-form__group {% if field.errors %} has-error {% endif %}">
{% if field.field.widget|fieldtype == 'RadioSelect' %}
<label class="col-sm-2 control-label" {% if field.field.required %}class="required"{% endif %} for="{{ field.name }}-{{ forloop.counter0 }}">
<label class="pf-c-form__label" {% if field.field.required %}class="required" {% endif %}
for="{{ field.name }}-{{ forloop.counter0 }}">
{{ field.label }}
</label>
{% for c in field %}
<div class="radio col-sm-10">
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}" name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}" {% if c.data.selected %} checked {% endif %}>
<label class="col-sm-2 control-label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}"
name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}"
{% if c.data.selected %} checked {% endif %}>
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
</div>
{% endfor %}
{% elif field.field.widget|fieldtype == 'Select' %}
<label class="col-sm-2 control-label" {% if field.field.required %}class="required"{% endif %} for="{{ field.name }}-{{ forloop.counter0 }}">
<label class="pf-c-form__label" {% if field.field.required %}class="required" {% endif %}
for="{{ field.name }}-{{ forloop.counter0 }}">
{{ field.label }}
</label>
<div class="select col-sm-10">
{{ field }}
</div>
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<label class="checkbox-label">
{{ field }} {{ field.label }}
</label>
</div>
</div>
{% else %}
<label class="col-sm-2 control-label" {% if field.field.required %}class="required"{% endif %} for="{{ field.name }}-{{ forloop.counter0 }}">
{{ field.label }}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
<div class="col-sm-10">
{{ field|css_class:'form-control' }}
{{ field|css_class:'pf-c-form-control' }}
{% if field.help_text %}
<span>
{{ field.help_text }}
</span>
{% endif %}
{% for error in field.errors %}
<span class="help-block">
{{ error }}
</span>
{% endfor %}
</div>
{% endif %}
{% for error in field.errors %}
<p class="pf-c-form__helper-text pf-m-error">
{{ error }}
</p>
{% endfor %}
</div>
{% endfor %}

View file

@ -0,0 +1,59 @@
{% load utils %}
{% load i18n %}
{% csrf_token %}
{% for field in form %}
<div class="pf-c-form__group {% if field.errors %} has-error {% endif %}">
{% if field.field.widget|fieldtype == 'RadioSelect' %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
{% for c in field %}
<div class="radio col-sm-10">
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}"
name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}"
{% if c.data.selected %} checked {% endif %}>
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
</div>
{% endfor %}
{% elif field.field.widget|fieldtype == 'Select' %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
<div class="pf-c-form__horizontal-group">
{{ field|css_class:"pf-c-form-control" }}
</div>
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
<div class="pf-c-form__horizontal-group">
<div class="pf-c-check">
{{ field|css_class:"pf-c-check__input" }}
<label class="pf-c-check__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ field.label }}</label>
</div>
</div>
{% else %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
<div class="c-form__horizontal-group">
{{ field|css_class:'pf-c-form-control' }}
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text }}</p>
{% endif %}
</div>
{% endif %}
{% for error in field.errors %}
<p class="pf-c-form__helper-text pf-m-error">
{{ error }}
</p>
{% endfor %}
</div>
{% endfor %}

View file

@ -1,52 +0,0 @@
{% load utils %}
{% load i18n %}
{% csrf_token %}
{% for field in form %}
<div class="pf-c-form__group {% if field.errors %} has-error {% endif %}">
{% if field.field.widget|fieldtype == 'RadioSelect' %}
<label class="pf-c-form__label" {% if field.field.required %}class="required" {% endif %}
for="{{ field.name }}-{{ forloop.counter0 }}">
{{ field.label }}
</label>
{% for c in field %}
<div class="radio col-sm-10">
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}"
name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}"
{% if c.data.selected %} checked {% endif %}>
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
</div>
{% endfor %}
{% elif field.field.widget|fieldtype == 'Select' %}
<label class="pf-c-form__label" {% if field.field.required %}class="required" {% endif %}
for="{{ field.name }}-{{ forloop.counter0 }}">
{{ field.label }}
</label>
<div class="select col-sm-10">
{{ field }}
</div>
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
<label class="checkbox-label">
{{ field }} {{ field.label }}
</label>
{% else %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
{{ field|css_class:'pf-c-form-control' }}
{% if field.help_text %}
<span>
{{ field.help_text }}
</span>
{% endif %}
{% endif %}
{% for error in field.errors %}
<span class="help-block">
{{ error }}
</span>
{% endfor %}
</div>
{% endfor %}

View file

@ -2,27 +2,21 @@
<ul class="pf-c-alert-group pf-m-toast">
{% for msg in messages %}
<li class="pf-c-alert-group__item">
<div class="pf-c-alert pf-m-{{ msg.level_tag }}">
<div class="pf-c-alert pf-m-{{ msg.level_tag }} {% if msg.level_tag == 'error' %}pf-m-danger{% endif %}">
<div class="pf-c-alert__icon">
{% if msg.level_tag == 'danger' %}
<o class="pficon pficon-error-circle-o"></o>
{% if msg.level_tag == 'error' %}
<i class="fas fa-exclamation-circle"></i>
{% elif msg.level_tag == 'warning' %}
<o class="pficon pficon-warning-triangle-o"></o>
<i class="fas fa-exclamation-triangle"></i>
{% elif msg.level_tag == 'success' %}
<o class="pficon pficon-ok"></o>
<i class="fas fa-check-circle"></i>
{% elif msg.level_tag == 'info' %}
<o class="pficon pficon-info"></o>
<i class="fas fa-info"></i>
{% endif %}
</div>
<div class="pf-c-alert__description">
<h4 class="pf-c-alert__title">
{{ msg.message|safe }}
</div>
<div class="pf-c-alert__action">
<button class="pf-c-button pf-m-plain" type="button"
aria-label="Close success alert: Newest notification">
<i class="fas fa-times"></i>
</button>
</div>
</h4>
</div>
</li>
{% endfor %}

View file

@ -40,7 +40,6 @@ class LoginView(UserPassesTestMixin, FormView):
def get_context_data(self, **kwargs):
kwargs["config"] = CONFIG.y("passbook")
kwargs["is_login"] = True
kwargs["title"] = _("Log in to your account")
kwargs["primary_action"] = _("Log in")
kwargs["show_sign_up_notice"] = CONFIG.y("passbook.sign_up.enabled")
@ -139,7 +138,6 @@ class SignUpView(UserPassesTestMixin, FormView):
def get_context_data(self, **kwargs):
kwargs["config"] = CONFIG.y("passbook")
kwargs["is_login"] = True
kwargs["title"] = _("Sign Up")
kwargs["primary_action"] = _("Sign up")
return super().get_context_data(**kwargs)

View file

@ -32,8 +32,6 @@ class BadRequestView(TemplateView):
response_class = BadRequestTemplateResponse
template_name = "error/400.html"
extra_context = {"is_login": True}
class ForbiddenView(TemplateView):
"""Show Forbidden message"""
@ -41,8 +39,6 @@ class ForbiddenView(TemplateView):
response_class = ForbiddenTemplateResponse
template_name = "error/403.html"
extra_context = {"is_login": True}
class NotFoundView(TemplateView):
"""Show Not Found message"""
@ -50,8 +46,6 @@ class NotFoundView(TemplateView):
response_class = NotFoundTemplateResponse
template_name = "error/404.html"
extra_context = {"is_login": True}
class ServerErrorView(TemplateView):
"""Show Server Error message"""
@ -59,8 +53,6 @@ class ServerErrorView(TemplateView):
response_class = ServerErrorTemplateResponse
template_name = "error/500.html"
extra_context = {"is_login": True}
# pylint: disable=useless-super-delegation
def dispatch(self, *args, **kwargs):
"""Little wrapper so django accepts this function"""

View file

@ -67,7 +67,6 @@ class UserChangePasswordView(LoginRequiredMixin, FormView):
def get_context_data(self, **kwargs):
kwargs["config"] = CONFIG.y("passbook")
kwargs["is_login"] = True
kwargs["title"] = _("Change Password")
kwargs["primary_action"] = _("Change")
return super().get_context_data(**kwargs)

View file

@ -15,7 +15,6 @@ class LoadingView(TemplateView):
return self.target_url
def get_context_data(self, **kwargs):
kwargs["is_login"] = True
kwargs["title"] = self.title
kwargs["target_url"] = self.get_url()
return super().get_context_data(**kwargs)
@ -28,6 +27,5 @@ class PermissionDeniedView(TemplateView):
title = _("Permission denied.")
def get_context_data(self, **kwargs):
kwargs["is_login"] = True
kwargs["title"] = self.title
return super().get_context_data(**kwargs)

View file

@ -25,7 +25,6 @@ class AuthenticationFactor(TemplateView):
def get_context_data(self, **kwargs):
kwargs["config"] = CONFIG.y("passbook")
kwargs["is_login"] = True
kwargs["title"] = _("Log in to your account")
kwargs["primary_action"] = _("Log in")
kwargs["user"] = self.pending_user

View file

@ -77,7 +77,6 @@ class EnableView(LoginRequiredMixin, FormView):
# TODO: Check if OTP Factor exists and applies to user
def get_context_data(self, **kwargs):
kwargs["config"] = CONFIG.y("passbook")
kwargs["is_login"] = True
kwargs["title"] = _("Configure OTP")
kwargs["primary_action"] = _("Setup")
return super().get_context_data(**kwargs)

View file

@ -74,11 +74,6 @@ class PassbookAuthorizationView(AccessMixin, AuthorizationView):
LOGGER.debug(request.GET.get("redirect_uri"))
return actual_response
def render_to_response(self, context, **kwargs):
# Always set is_login to true for correct css class
context["is_login"] = True
return super().render_to_response(context, **kwargs)
def form_valid(self, form):
# User has clicked on "Authorize"
Event.new(

View file

@ -66,10 +66,7 @@ class AccessRequiredView(AccessMixin, View):
return render(
request,
"login/denied.html",
{
"title": _("You don't have access to this application"),
"is_login": True,
},
{"title": _("You don't have access to this application"),},
)
return super().dispatch(request, *args, **kwargs)
@ -142,12 +139,7 @@ class LoginProcessView(AccessRequiredView):
return render(
request,
"saml/idp/login.html",
{
"saml_params": params,
"provider": self.provider,
# This is only needed to for the template to render correctly
"is_login": True,
},
{"saml_params": params, "provider": self.provider,},
)
except exceptions.CannotHandleAssertion as exc:
@ -308,10 +300,5 @@ class InitiateLoginView(AccessRequiredView):
return render(
request,
"saml/idp/login.html",
{
"saml_params": params,
"provider": self.provider,
# This is only needed to for the template to render correctly
"is_login": True,
},
{"saml_params": params, "provider": self.provider,},
)

View file

@ -78,7 +78,7 @@ INSTALLED_APPS = [
"guardian",
"django_prometheus",
"passbook.core.apps.PassbookCoreConfig",
'passbook.static.apps.PassbookStaticConfig',
"passbook.static.apps.PassbookStaticConfig",
"passbook.admin.apps.PassbookAdminConfig",
"passbook.api.apps.PassbookAPIConfig",
"passbook.lib.apps.PassbookLibConfig",

View file

@ -1,3 +1,4 @@
/* Fix patternfly sidebar and header with open Modal */
.pf-c-page__sidebar {
z-index: 0;
}
@ -5,3 +6,209 @@
.pf-c-page__header {
z-index: 0;
}
@@ -1,204 +0,0 @@
.navbar-brand-name {
height: 35px;
}
.dynamic-array-widget .array-item {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.dynamic-array-widget .remove_sign {
width: 10px;
height: 2px;
background: #a41515;
border-radius: 1px;
}
.dynamic-array-widget .remove {
height: 15px;
display: flex;
align-items: center;
margin-left: 5px;
}
.dynamic-array-widget .remove:hover {
cursor: pointer;
}
/* Selector */
.selector {
display: flex;
width: 100%;
height: 45vh;
}
.selector .selector-filter {
display: flex;
align-items: center;
}
.selector .selector-filter label {
margin: 0 8px 0 0;
}
.selector .selector-filter input {
width: auto;
min-height: 0;
flex: 1 1;
}
.selector-available, .selector-chosen {
width: auto;
flex: 1 1;
display: flex;
flex-direction: column;
}
.selector select {
width: 100%;
flex: 1 0 auto;
margin-bottom: 5px;
}
.selector ul.selector-chooser {
width: 26px;
height: 52px;
padding: 2px 0;
margin: auto 15px;
border-radius: 20px;
transform: translateY(-10px);
list-style: none;
}
.selector-add, .selector-remove {
width: 20px;
height: 20px;
background-size: 20px auto;
}
.selector-add {
background-position: 0 -120px;
}
.selector-remove {
background-position: 0 -80px;
}
a.selector-chooseall, a.selector-clearall {
align-self: center;
}
.stacked {
flex-direction: column;
max-width: 480px;
}
.stacked > * {
flex: 0 1 auto;
}
.stacked select {
margin-bottom: 0;
}
.stacked .selector-available, .stacked .selector-chosen {
width: auto;
}
.stacked ul.selector-chooser {
width: 52px;
height: 26px;
padding: 0 2px;
margin: 15px auto;
transform: none;
}
.stacked .selector-chooser li {
padding: 3px;
}
.stacked .selector-add, .stacked .selector-remove {
background-size: 20px auto;
}
.stacked .selector-add {
background-position: 0 -40px;
}
.stacked .active.selector-add {
background-position: 0 -60px;
}
.stacked .selector-remove {
background-position: 0 0;
}
.stacked .active.selector-remove {
background-position: 0 -20px;
}
.help-tooltip, .selector .help-icon {
display: none;
}
form .form-row p.datetime {
width: 100%;
}
.datetime input {
width: 50%;
max-width: 120px;
}
.datetime span {
font-size: 13px;
}
.datetime .timezonewarning {
display: block;
font-size: 11px;
color: #999;
}
.datetimeshortcuts {
color: #ccc;
}
.inline-group {
overflow: auto;
}
.selector-add, .selector-remove {
width: 16px;
height: 16px;
display: block;
text-indent: -3000px;
overflow: hidden;
cursor: default;
opacity: 0.3;
}
.active.selector-add, .active.selector-remove {
opacity: 1;
}
.active.selector-add:hover, .active.selector-remove:hover {
cursor: pointer;
}
.selector-add {
background: url(../admin/img/selector-icons.svg) 0 -96px no-repeat;
}
.active.selector-add:focus, .active.selector-add:hover {
background-position: 0 -112px;
}
.selector-remove {
background: url(../admin/img/selector-icons.svg) 0 -64px no-repeat;
}
input[data-is-monospace] {
font-family: monospace;
}