Compare commits

..
Author SHA1 Message Date
Mira Weller fb737d8dd8 Add style for admin-only panels 2026-09-26 00:19:31 +02:00
Mira Weller 4330699b9b Minor fixes 2026-09-26 00:07:34 +02:00
Mira Weller 7a4c05ffe5 Single menu on mobile 2026-09-25 23:38:04 +02:00
Mira Weller 67a2be4820 Experiment 2026-09-25 14:26:36 +02:00
Mira Weller 1f1c30491f Always show profile header 2026-09-25 01:48:35 +02:00
Mira Weller 1a409c5fec Always show brand on large screen 2026-09-25 01:38:58 +02:00
Mira Weller d546501b97 Navbar redesign 2026-09-25 01:16:03 +02:00
Mira Weller e4a6d14c4a Navbar top external links and separators 2026-09-24 22:50:36 +02:00
16 changed files with 460 additions and 280 deletions
@@ -97,25 +97,42 @@
{% if request.organizer %}data-organizer="{{ request.organizer.slug }}"{% endif %}
{% if request.event %}data-event="{{ request.event.slug }}"{% endif %}
data-select2-locale="{{ select2locale }}" data-longdateformat="{{ js_long_date_format }}" class="nojs">
{% if request.event %}
{% if has_domain and not request.event.live %}
<form action="{% eventurl request.event "presale:event.auth" %}" method="post"
target="_blank" id="gotoshopform">
<input type="hidden" value="{{ new_session }}" name="session">
</form>
{% else %}
<form action="{% eventurl request.event "presale:event.index" %}" method="get"
target="_blank" id="gotoshopform"></form>
{% endif %}
{% endif %}
<div id="wrapper">
<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-nav-collapse">
<span class="sr-only">{% trans "Toggle navigation" %}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url "control:index" %}">
<img src="{% static "pretixbase/img/pretix-icon-white-mini.svg" %}" />
<span class="{% if request.event or request.organizer %}visible-lg-inline-block{% endif %}">
{{ settings.PRETIX_INSTANCE_NAME }}
</span>
</a>
{% if request.organizer %}
<a class="navbar-context-breadcrumb" href="{% url "control:organizer" organizer=request.organizer.slug %}">
{{ request.organizer.slug }} {#<span class="fa fa-users"></span>#}
</a>
{% endif %}
{% if request.event %}
<a class="navbar-context-breadcrumb" href="{% url "control:event.index" organizer=request.organizer.slug event=request.event.slug %}">
{{ request.event.slug }} {#<span class="fa fa-calendar"></span>#}
</a>
{% endif %}
{% if request.event %}
{% if has_domain and not request.event.live %}
<form action="{% eventurl request.event "presale:event.auth" %}" method="post"
target="_blank" class="mobile-navbar-view-form visible-xs-block">
<input type="hidden" value="{{ new_session }}" name="session">
<button type="submit" class="btn btn-link navbar-toggle">
<i class="fa fa-eye"></i>
</button>
</form>
<button type="submit" class="btn btn-link navbar-toggle" form="gotoshopform">
<i class="fa fa-eye"></i>
</button>
{% else %}
<a href="{% eventurl request.event "presale:event.index" %}" title="{% trans "Go to shop" %}"
target="_blank" class="navbar-toggle mobile-navbar-view-link">
@@ -128,23 +145,24 @@
<i class="fa fa-eye"></i>
</a>
{% endif %}
<a class="navbar-brand" href="{% url "control:index" %}">
<img src="{% static "pretixbase/img/pretix-icon-white-mini.svg" %}" />
<span>
{{ settings.PRETIX_INSTANCE_NAME }}
</span>
</a>
<button type="button" class="navbar-toggle"
data-toggle="dropdown" data-target="#main_sidebar">
<span class="sr-only">{% trans "Toggle navigation" %}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<ul class="nav navbar-nav navbar-top-links navbar-left flip hidden-xs">
<!--
{% if request.event %}
<li>
{% if has_domain and not request.event.live %}
<form action="{% eventurl request.event "presale:event.auth" %}" method="post" target="_blank">
<input type="hidden" value="{{ new_session }}" name="session">
<button type="submit" class="btn btn-link" id="button-shop">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</button>
</form>
<button type="submit" class="btn btn-link" id="button-shop" form="gotoshopform">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</button>
{% else %}
<a href="{% eventurl request.event "presale:event.index" %}" title="{% trans "Go to shop" %}" target="_blank">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
@@ -158,11 +176,13 @@
</a>
</li>
{% endif %}
-->
</ul>
<ul class="nav navbar-nav navbar-top-links navbar-right flip">
<ul class="nav navbar-nav navbar-top-links navbar-right flip hidden-xs">
{% for nav in nav_topbar %}
<li {% if nav.children %}class="dropdown"{% endif %}>
<a href="{{ nav.url }}" title="{{ nav.title }}" {% if nav.active %}class="active"{% endif %}
{% if nav.external %}target="_blank"{% endif %}
{% if nav.children %}class="dropdown-toggle" data-toggle="dropdown"{% endif %}>
{% if nav.icon %}
{% if "<svg" in nav.icon %}
@@ -177,16 +197,24 @@
</a>
{% if nav.children %}
<ul class="dropdown-menu" role="menu">
<li class="dropdown-mobile-header visible-xs">
<strong>{{ nav.title }}</strong>
</li>
<li role="separator" class="divider visible-xs"></li>
{% for item in nav.children %}
<li>
<a {% if item.url %}href="{{ item.url }}"{% endif %}
{% if item.external %}target="_blank"{% endif %}
{% if item.active %}class="active"{% endif %}>
{% if item.icon %}
<span class="fa fa-fw fa-{{ item.icon }}"></span>
{% endif %}
{{ item.label|safe }}</a>
</li>
{% if item.separator %}
<li role="separator" class="divider"></li>
{% else %}
<li>
<a {% if item.url %}href="{{ item.url }}"{% endif %}
{% if item.external %}target="_blank"{% endif %}
{% if item.active %}class="active"{% endif %}>
{% if item.icon %}
<span class="fa fa-fw fa-{{ item.icon }}"></span>
{% endif %}
{{ item.label|safe }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
@@ -216,20 +244,139 @@
</a>
</li>
{% endif %}
<li>
<a href="{% url 'control:user.settings' %}" title="{% trans "Account Settings" %}" >
<li class="dropdown">
<a href="{% url 'control:user.settings' %}" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user"></i> {{ request.user.get_full_name }}
</a>
</li>
<li>
<a href="{% url 'control:auth.logout' %}" title="{% trans "Log out" %}">
<i class="fa fa-sign-out"></i>
<span class="visible-xs-inline">{% trans "Log out" %}</span>
</a>
<ul class="dropdown-menu" role="menu">
<li class="dropdown-mobile-header dropdown-header">
<strong>{{ request.user.get_full_name }}</strong><br>
{{ request.user.email }}
</li>
<li role="separator" class="divider"></li>
<li>
<a href="{% url 'control:organizers' %}">
<i class="fa fa-fw fa-group"></i> {% trans "My organizer accounts" %}
</a>
</li>
<li>
<a href="{% url 'control:user.settings' %}">
<i class="fa fa-fw fa-cog"></i> {% trans "Account settings" %}
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="{% url 'control:auth.logout' %}" title="{% trans "Log out" %}">
<i class="fa fa-fw fa-sign-out"></i> {% trans "Log out" %}
</a>
</li>
</ul>
</li>
</ul>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-nav-collapse navbar-collapse">
<div class="navbar-default sidebar" id="main_sidebar" role="navigation" data-dropdown-keep-on-click-inside="true">
<div class="sidebar-nav">
<ul class="nav visible-xs">
{% for nav in nav_topbar %}
<li {% if nav.children %}{% endif %}>
{% if nav.children %}<details>
<summary>{% endif %}
<a {% if not nav.children %}href="{{ nav.url }}"{% endif %} title="{{ nav.title }}" {% if nav.active %}class="active"{% endif %}
{% if nav.external %}target="_blank"{% endif %}
>
{% if nav.icon %}
{% if "<svg" in nav.icon %}
{{ nav.icon|safe }}
{% else %}
<span class="fa fa-fw fa-{{ nav.icon }}"></span>
{% endif %}
<span class="visible-xs-inline">{{ nav.label|default:nav.title }}</span>
{% else %}
{{ nav.label }}
{% endif %}
{% if nav.children %}<span class="fa arrow pull-right"></span>{% endif %}
</a>
{% if nav.children %}
</summary>
<ul class="nav nav-second-level" role="menu">
{% for item in nav.children %}
{% if item.separator %}
<li role="separator" class="divider"></li>
{% else %}
<li>
<a {% if item.url %}href="{{ item.url }}"{% endif %}
{% if item.external %}target="_blank"{% endif %}
{% if item.active %}class="active"{% endif %}>
{% if item.icon %}
<span class="fa fa-fw fa-{{ item.icon }}"></span>
{% endif %}
{{ item.label|safe }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</details>
{% endif %}
</li>
{% endfor %}
{% if request.user.is_staff and not staff_session %}
<li>
<form action="{% url 'control:user.sudo' %}?next={{ request.path|add:"?"|add:request.GET.urlencode|urlencode }}" method="post">
{% csrf_token %}
<button type="submit" class="btn-block text-left" id="button-sudo">
<i class="fa fa-fw fa-id-card"></i> {% trans "Admin mode" %}
</button>
</form>
</li>
{% elif request.user.is_staff and staff_session %}
<li>
<a href="{% url 'control:user.sudo.stop' %}" class="danger admin-only">
<i class="fa fa-fw fa-id-card"></i> {% trans "End admin session" %}
</a>
</li>
{% endif %}
{% if warning_update_available %}
<li>
<a href="{% url 'control:global.update' %}" class="danger">
<i class="fa fa-fw fa-bell"></i>
</a>
</li>
{% endif %}
<li>
<details>
<summary><a>
<i class="fa fa-fw fa-user"></i> {{ request.user.get_full_name }}
<span class="fa arrow pull-right"></span>
</a></summary>
<ul class="nav nav-second-level" role="menu">
<li>
<a href="{% url 'control:organizers' %}">
<i class="fa fa-fw fa-group"></i> {% trans "My organizer accounts" %}
</a>
</li>
<li>
<a href="{% url 'control:user.settings' %}">
<i class="fa fa-fw fa-cog"></i> {% trans "Account settings" %}
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="{% url 'control:auth.logout' %}" title="{% trans "Log out" %}">
<i class="fa fa-fw fa-sign-out"></i> {% trans "Log out" %}
</a>
</li>
</ul>
</details>
</li>
</ul>
<div class="side-header">
{% if request.event or request.organizer %}
{% trans "Switch organizer or event" %}
{% else %}
{% trans "Go to organizer or event" %}
{% endif %}
</div>
<div class="dropdown context-selector">
{% if request.event %}
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
@@ -257,11 +404,11 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="fa-stack fa-lg">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-user fa-stack-1x fa-inverse"></i>
<i class="fa fa-search fa-stack-1x fa-inverse"></i>
</span>
<div class="context-indicator">
<span class="context-name">{{ request.user }}</span>
<span class="context-name">{% trans "Search..." %}</span>
</div>
<span class="caret"></span></a>
{% endif %}
@@ -279,6 +426,15 @@
</li>
</ul>
</div>
<div class="side-header">
{% if request.event %}
{% trans "Event menu" %}
{% elif request.organizer %}
{% trans "Organizer account menu" %}
{% else %}
{% trans "Personal account menu" %}
{% endif %}
</div>
<ul class="nav" id="side-menu">
{% if request.event and request.event.testmode %}
<li class="testmode">
@@ -56,7 +56,7 @@
</p>
</div>
{% else %}
<span class="table-responsive">
<div class="table-responsive">
<table class="table table-hover table-quotas">
<thead>
<tr>
@@ -7,6 +7,15 @@
{% block title %}{{ request.event.name }}{% endblock %}
{% block content %}
<h1>
{% if has_domain and not request.event.live %}
<button type="submit" class="btn btn-lg btn-primary pull-right hidden-xs" id="button-shop" form="gotoshopform">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</button>
{% else %}
<a href="{% eventurl request.event "presale:event.index" %}" class="btn btn-lg btn-primary pull-right hidden-xs" target="_blank">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</a>
{% endif %}
{{ request.event.name }}
<small>
{% if request.event.has_subevents %}
@@ -17,6 +26,17 @@
<span id="warnings_loading" class="fa fa-cog fa-spin"></span>
</small>
</h1>
<p class="visible-xs">
{% if has_domain and not request.event.live %}
<button type="submit" class="btn btn-lg btn-primary" id="button-shop" form="gotoshopform">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</button>
{% else %}
<a href="{% eventurl request.event "presale:event.index" %}" class="btn btn-lg btn-primary" target="_blank">
<i class="fa fa-eye"></i> {% trans "Go to shop" %}
</a>
{% endif %}
</p>
<div class="helper-space-below">
{% trans "Shop URL:" %}
<span id="shop_url" class="text-muted">{% abseventurl request.event "presale:event.index" %}</span>
@@ -21,10 +21,10 @@
</a>
</div>
{% else %}
<div class="panel panel-default">
<div class="panel-heading">
<details class="panel panel-default" data-stateful="events_index_filter">
<summary class="panel-heading">
<h3 class="panel-title">{% trans "Filter" %}</h3>
</div>
</summary>
<form class="panel-body filter-form" action="" method="get">
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
@@ -55,14 +55,14 @@
</button>
</div>
</form>
</div>
</details>
<p>
<a href="{% url "control:events.add" %}" class="btn btn-default">
<span class="fa fa-plus"></span>
{% trans "Create a new event" %}
</a>
</p>
<table class="table table-condensed table-hover">
<div class="table-responsive"><table class="table table-condensed table-hover">
<thead>
<tr>
<th>
@@ -186,7 +186,7 @@
</tr>
{% endfor %}
</tbody>
</table>
</table></div>
{% include "pretixcontrol/pagination.html" %}
{% endif %}
{% endblock %}
@@ -2,10 +2,19 @@
{% load i18n %}
{% load bootstrap3 %}
{% load static %}
{% load eventurl %}
{% block inner %}
<h1>
<a href="{% eventurl request.organizer "presale:organizer.index" %}" class="btn btn-lg btn-default pull-right hidden-xs" target="_blank">
<i class="fa fa-eye"></i> {% trans "Public profile" %}
</a>
{% blocktrans with name=request.organizer.name %}Organizer: {{ name }}{% endblocktrans %}
</h1>
<p class="visible-xs">
<a href="{% eventurl request.organizer "presale:organizer.index" %}" class="btn btn-lg btn-default" target="_blank">
<i class="fa fa-eye"></i> {% trans "Public profile" %}
</a>
</p>
{% if events|length == 0 and not filter_form.filtered %}
{% if "organizer.events:create" in request.orgapermset %}
<p>
@@ -19,10 +28,10 @@
<em>{% trans "You currently do not have access to any events." %}</em>
</p>
{% else %}
<div class="panel panel-default">
<div class="panel-heading">
<details class="panel panel-default" open data-stateful="organizer_detail_filter">
<summary class="panel-heading">
<h3 class="panel-title">{% trans "Filter" %}</h3>
</div>
</summary>
<form class="panel-body filter-form" action="" method="get">
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
@@ -50,7 +59,7 @@
</button>
</div>
</form>
</div>
</details>
{% if "organizer.events:create" in request.orgapermset %}
<p>
<a href="{% url "control:events.add" %}?organizer={{ request.organizer.slug }}" class="btn btn-primary">
@@ -59,7 +68,7 @@
</a>
</p>
{% endif %}
<table class="table table-condensed table-hover">
<div class="table-responsive"><table class="table table-condensed table-hover">
<thead>
<tr>
<th>{% trans "Event name" %}</th>
@@ -157,7 +166,7 @@
</tr>
{% endfor %}
</tbody>
</table>
</table></div>
{% include "pretixcontrol/pagination.html" %}
{% endif %}
{% endblock %}
@@ -5,14 +5,16 @@
{% load eventurl %}
{% block title %}{% trans "Organizers" %}{% endblock %}
{% block content %}
<h1>{% trans "Organizers" %}</h1>
<h1>
{% trans "Organizers" %}
</h1>
<p>{% trans "The list below shows all organizer accounts you have administrative access to." %}</p>
<div class="panel panel-default">
<div class="panel-heading">
<details class="panel panel-default" open data-stateful="organizers_index_filter">
<summary class="panel-heading">
<h3 class="panel-title">
{% trans "Filter" %}
</h3>
</div>
</summary>
<form class="panel-body filter-form" action="" method="get">
<div class="row">
<div class="col-md-12 col-sm-6 col-xs-12">
@@ -26,7 +28,7 @@
</button>
</div>
</form>
</div>
</details>
{% if staff_session %}
<p>
<a href="{% url "control:organizers.add" %}" class="btn btn-default admin-only">
@@ -35,9 +37,9 @@
</a>
</p>
{% endif %}
<table class="table table-condensed table-hover">
<thead>
<tr>
<div class="table-responsive"><table class="table table-condensed table-hover">
<thead>
<tr>
<th>
{% trans "Organizer name" %}
<a href="?{% url_replace request 'ordering' '-name' %}"><i class="fa fa-caret-down"></i></a>
@@ -48,18 +50,18 @@
<a href="?{% url_replace request 'ordering' '-slug' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'slug' %}"><i class="fa fa-caret-up"></i></a>
</th>
</tr>
</thead>
<tbody>
{% for o in organizers %}
<tr>
<td><strong>
</tr>
</thead>
<tbody>
{% for o in organizers %}
<tr>
<td><strong>
<a href="{% url "control:organizer" organizer=o.slug %}">{{ o.name }}</a>
</strong></td>
<td>{{ o.slug }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</tr>
{% endfor %}
</tbody>
</table></div>
{% include "pretixcontrol/pagination.html" %}
{% endblock %}
+2 -12
View File
@@ -773,7 +773,6 @@ if (typeof jQuery === 'undefined') {
// DROPDOWN CLASS DEFINITION
// =========================
var backdrop = '.dropdown-backdrop'
var toggle = '[data-toggle="dropdown"]'
var Dropdown = function (element) {
$(element).on('click.bs.dropdown', this.toggle)
@@ -796,7 +795,6 @@ if (typeof jQuery === 'undefined') {
function clearMenus(e) {
if (e && e.which === 3) return
$(backdrop).remove()
$(toggle).each(function () {
var $this = $(this)
var $parent = getParent($this)
@@ -804,7 +802,7 @@ if (typeof jQuery === 'undefined') {
if (!$parent.hasClass('open')) return
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
if (e && e.type == 'click' && ($parent.attr('data-dropdown-keep-on-click-inside') || /input|textarea/i.test(e.target.tagName)) && $.contains($parent[0], e.target)) return
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
@@ -823,17 +821,9 @@ if (typeof jQuery === 'undefined') {
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
clearMenus()
clearMenus(e)
if (!isActive) {
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
// if mobile we use a backdrop because click events don't delegate
$(document.createElement('div'))
.addClass('dropdown-backdrop')
.insertAfter($(this))
.on('click', clearMenus)
}
var relatedTarget = { relatedTarget: this }
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
@@ -1260,12 +1260,6 @@ html.rtl {
}
}
.navbar-toggle {
float: left;
margin-left: 15px;
margin-right: auto;
}
@media (max-width: 767px) {
.navbar-nav .open .dropdown-menu > li > a,
.navbar-nav .open .dropdown-menu .dropdown-header {
@@ -31,9 +31,7 @@
.navbar-header {
@include clearfix;
@media (min-width: $grid-float-breakpoint) {
float: left;
}
display: flex;
}
@@ -159,7 +157,6 @@
// Brand/project name
.navbar-brand {
float: left;
height: $navbar-height;
padding: $navbar-padding-vertical $navbar-padding-horizontal;
font-size: $font-size-large;
@@ -236,19 +233,52 @@
line-height: $line-height-computed;
}
@media (max-width: $grid-float-breakpoint-max) {
// Dropdowns get custom display when collapsed
.open .dropdown-menu {
position: static;
display: flex;
margin: 0;
max-width: 100%;
> li {
min-width: 0;
> a {
padding-top: $navbar-padding-vertical;
padding-bottom: $navbar-padding-vertical;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100%;
flex: 0 1 10px;
min-width: 0;
}
}
}
@media (max-width: $grid-float-breakpoint-max) {
.navbar-default.sidebar > .sidebar-nav {
display: none;
}
// Dropdowns get custom display when collapsed
.navbar-nav .open, .navbar-default.sidebar.open {
& > .dropdown-menu, & > .sidebar-nav {
position: fixed; display: block;
float: none;
width: auto;
width: 80%; top: 0; left: inherit; right: 0; bottom: 0; background: white; z-index: 2;
margin-top: 0;
background-color: transparent;
border: 0;
box-shadow: none;
> li > a,
.dropdown-header {
padding: 5px 15px 5px 25px;
padding: 50px 0 10px 0;
overflow-y: auto; overflow-x: hidden;
border: 0; border-left: 1px solid #666;
box-shadow: 0 0 70px #222; border-radius: 0;
background: white linear-gradient(140deg, white 0%, white 40%, #faf4fe 60%, #e8cefb 85% , #ddb8fa 100%);
> li > a {
padding: 12px 15px 12px 25px;
}
.dropdown-header, .dropdown-mobile-header, .divider {
margin-left: 25px; margin-right: 15px; padding-left: 0; padding-right: 0;
}
.dropdown-mobile-header {
padding: 20px 0 10px 0; font-size: 14px;
color: #333; white-space: inherit;
strong { font-size: 120%; }
}
> li > a {
line-height: $line-height-computed;
@@ -258,19 +288,8 @@
}
}
}
}
// Uncollapse the nav
@media (min-width: $grid-float-breakpoint) {
float: left;
margin: 0;
> li {
float: left;
> a {
padding-top: $navbar-padding-vertical;
padding-bottom: $navbar-padding-vertical;
}
&::before {
position: fixed; content: " "; background: rgba(0,0,0,0.2); top: 0; left: 0; bottom: 0; right: 0; z-index: -1;
}
}
}
@@ -374,12 +393,12 @@
// Declared after the navbar components to ensure more specificity on the margins.
@media (min-width: $grid-float-breakpoint) {
.navbar { display: flex; flex-direction: row; }
.navbar-left {
float: left !important;
flex: 1;
}
.navbar-right {
float: right !important;
margin-right: -$navbar-padding-horizontal;
margin-right: -$navbar-padding-horizontal;
~ .navbar-right {
margin-right: 0;
@@ -447,35 +466,6 @@
}
}
@media (max-width: $grid-float-breakpoint-max) {
// Dropdowns get custom display when collapsed
.open .dropdown-menu {
> li > a {
color: $navbar-default-link-color;
&:hover,
&:focus {
color: $navbar-default-link-hover-color;
background-color: $navbar-default-link-hover-bg;
}
}
> .active > a {
&,
&:hover,
&:focus {
color: $navbar-default-link-active-color;
background-color: $navbar-default-link-active-bg;
}
}
> .disabled > a {
&,
&:hover,
&:focus {
color: $navbar-default-link-disabled-color;
background-color: $navbar-default-link-disabled-bg;
}
}
}
}
}
.navbar-toggle {
@@ -542,7 +532,7 @@
}
.navbar-nav {
> li > a {
> li > a, > li > form > button {
color: $navbar-inverse-link-color;
&:hover,
@@ -551,7 +541,7 @@
background-color: $navbar-inverse-link-hover-bg;
}
}
> .active > a {
> .active > a, > li.active > form > button {
&,
&:hover,
&:focus {
@@ -578,41 +568,6 @@
}
}
@media (max-width: $grid-float-breakpoint-max) {
// Dropdowns get custom display
.open .dropdown-menu {
> .dropdown-header {
border-color: $navbar-inverse-border;
}
.divider {
background-color: $navbar-inverse-border;
}
> li > a {
color: $navbar-inverse-link-color;
&:hover,
&:focus {
color: $navbar-inverse-link-hover-color;
background-color: $navbar-inverse-link-hover-bg;
}
}
> .active > a {
&,
&:hover,
&:focus {
color: $navbar-inverse-link-active-color;
background-color: $navbar-inverse-link-active-bg;
}
}
> .disabled > a {
&,
&:hover,
&:focus {
color: $navbar-inverse-link-disabled-color;
background-color: $navbar-inverse-link-disabled-bg;
}
}
}
}
}
// Darken the responsive nav toggle
@@ -16,7 +16,7 @@
position: relative;
display: block;
> a {
> a, > details > summary > a, > form > button {
position: relative;
display: block;
padding: $nav-link-padding;
+37 -34
View File
@@ -55,44 +55,17 @@ setup_collapsible_details = function (el) {
})
let isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'
el.find('details summary').click(function (e) {
if (this.tagName !== 'A' && $(e.target).closest('a').length > 0) {
return true
}
let $details = $(this).closest('details')
let isOpen = $details.prop('open')
let $detailsNotSummary = $details.children(':not(summary)')
if ($detailsNotSummary.is(':animated')) {
e.preventDefault()
return false
}
if (isOpen) {
$details.removeClass('details-open')
$detailsNotSummary.stop().show().slideUp(500, function () {
$details.prop('open', false)
})
} else {
$detailsNotSummary.stop().hide()
$details.prop('open', true)
$details.addClass('details-open')
$detailsNotSummary.slideDown()
}
e.preventDefault()
return false
}).keyup(function (event) {
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
// Space or Enter is pressed — trigger the `click` event on the `summary` element
// Opera already seems to trigger the `click` event when Enter is pressed
event.preventDefault()
$(this).click()
}
})
$('details').each(function () {
let $details = $(this),
$detailsSummary = $('summary', $details).first(),
$detailsNotSummary = $details.children(':not(summary)')
$details.prop('open', typeof $details.attr('open') == 'string')
var open = typeof $details.attr('open') == 'string'
var stateKey = null
if ($details.attr('data-stateful')) {
stateKey = 'ui-details-state-' + $details.attr('data-stateful')
if (localStorage[stateKey]) open = localStorage[stateKey] === 'open'
}
$details.prop('open', open)
if (!$details.prop('open')) {
if ($details.find('.has-error, .alert-danger').length) {
$details.addClass('details-open')
@@ -108,6 +81,36 @@ setup_collapsible_details = function (el) {
'aria-controls': $details.attr('id')
}).prop('tabIndex', 0).bind('selectstart dragstart mousedown', function () {
return false
}).click(function (e) {
if (this.tagName !== 'A' && $(e.target).closest('a[href]').length > 0) {
return true
}
let isOpen = $details.prop('open')
if ($detailsNotSummary.is(':animated')) {
e.preventDefault()
return false
}
if (isOpen) {
$details.removeClass('details-open')
$detailsNotSummary.stop().show().slideUp(500, function () {
$details.prop('open', false)
})
} else {
$detailsNotSummary.stop().hide()
$details.prop('open', true)
$details.addClass('details-open')
$detailsNotSummary.slideDown()
}
if (stateKey) localStorage[stateKey] = isOpen ? 'closed' : 'open'
e.preventDefault()
return false
}).keyup(function (event) {
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
// Space or Enter is pressed — trigger the `click` event on the `summary` element
// Opera already seems to trigger the `click` event when Enter is pressed
event.preventDefault()
$(this).click()
}
})
})
@@ -12,10 +12,10 @@ $(window).bind('load resize', function () {
let topOffset = 50,
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width
if (width < 768) {
$('div.navbar-collapse').addClass('collapse')
//$('div.navbar-collapse').addClass('collapse')
topOffset = 100 // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse')
//$('div.navbar-collapse').removeClass('collapse')
}
let height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1
@@ -10,9 +10,8 @@ html.rtl {
}
.navbar-top-links li:last-child {
margin-left: 15px;
margin-right: 0;
.navbar-header :not(.navbar-toggle) + .navbar-toggle {
margin-left: inherit; margin-right: auto;
}
.sidebar .context-selector a span.caret {
@@ -43,10 +43,6 @@ body {
display: inline-block;
}
.navbar-top-links li:last-child {
margin-right: 15px;
}
.navbar-top-links li a {
padding: 15px;
min-height: 50px;
@@ -93,6 +89,13 @@ body {
left: auto;
}
.nav li a div[lang] {
padding-top: 0px;
background-position-y: 4px;
min-height: inherit;
white-space: inherit;
}
// --Sidebar
.sidebar {
@@ -123,6 +126,7 @@ body {
a.has-children {
margin-right: 40px;
}
details[open] summary .fa.arrow { transform: rotate(-90deg); }
}
.sidebar .fa.arrow {
@@ -197,9 +201,22 @@ body {
font-size: 11px;
}
}
}
}
.side-header {
padding: 25px 15px 5px;
border-bottom: 2px solid #e7e7e7;
color: #adadad;
font-weight: bold; font-size: 90%;
text-transform: uppercase;
}
@media(min-width:768px) {
.side-header {
//color: #ddd; transition: color 0.5s ease-in-out;
}
.sidebar:hover .side-header {
//color: #aaa;
}
.sidebar {
z-index: 1;
position: absolute;
+76 -16
View File
@@ -32,25 +32,83 @@ footer {
font-size: 11px;
}
/* Navbar styles */
nav.navbar {
margin: 0;
border: 0;
}
.navbar-brand {
position: relative;
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
}
.navbar-brand span {
padding: 4px 8px 6px; // Optical alignment next to logo
display: inline-block;
}
.navbar-brand img {
width: auto;
height: 100%;
display: inline-block;
vertical-align: top;
.navbar-header {
margin: 0 0 0 10px;
.navbar-brand {
position: relative;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
padding-right: 8px; margin-left: -10px;
img {
width: auto;
height: 100%;
display: inline-block;
vertical-align: top;
}
span {
padding: 5px 0 6px 8px; // Optical alignment next to logo
display: inline-block;
}
}
a.navbar-context-breadcrumb {
padding-left: 0;
padding-right: 8px;
padding-top: 15px;
padding-bottom: 15px;
text-decoration: none;
display: inline-block;
line-height: $line-height-computed;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 18px;
@media (max-width: $screen-sm-max) {
font-size: 16px;
padding-right: 3px;
}
color: $navbar-inverse-link-color;
&::before {
content: "›"; color: #9a81a6; font-weight: normal;
padding: 0 10px 0 5px;
@media (max-width: $screen-sm-max) {
padding-right: 3px;
}
}
&:hover,
&:focus {
color: $navbar-inverse-link-hover-color;
background-color: $navbar-inverse-link-hover-bg;
}
}
a.navbar-context-breadcrumb.active {
font-weight: bold;
}
a.navbar-context-breadcrumb.unknown {
color: #cdb2d9; font-style: italic;
}
:not(.navbar-toggle) + .navbar-toggle { margin-left: auto; }
}
@media (min-width: $grid-float-breakpoint) {
.navbar-header {
flex: 0 1 auto; /* shrink but dont grow */
overflow: hidden;
}
.navbar-top-links.navbar-left {
flex: 1 0 auto; /* grow but dont shrink */
}
.navbar-top-links {
min-width: 50px;
}
}
.navbar-nav { margin: 0; }
}
#side-menu img.fa-img {
@@ -516,6 +574,7 @@ table td ul:last-child {
rgba(255, 255, 255, .5) 24px);
}
.panel-default.admin-only > .panel-heading.admin-only { background-color: rgba(161, 161, 161, 0.42); }
.danger.admin-only {
background-image: repeating-linear-gradient(135deg,
@@ -524,6 +583,7 @@ table td ul:last-child {
transparent 12px,
transparent 22px,
rgba(0, 0, 0, .1) 24px);
color: white;
}
.quotabox {
+1 -26
View File
@@ -109,32 +109,7 @@ let form_handlers = function (el) {
}
$(this).datetimepicker(opts)
})
el.find("button[data-wait-seconds-enable], input[data-wait-seconds-enable]").each(function(i, input) {
var s = parseInt(input.getAttribute("data-wait-seconds-enable")) || 0;
var time = $("time", input) || $("time").appendTo(input);
var reltf = new Intl.RelativeTimeFormat($('body').attr('data-datetimelocale'), { style: "narrow" });
// for a11y do not disable input, but do not allow submit
function disable_submit(e) {
e.preventDefault();
}
if (s) {
input.addEventListener("click", disable_submit);
}
function wait() {
time.attr("datetime", s+"s");
if (s > 0) {
time.text("(" + reltf.format(s, "seconds") + ")");
window.setTimeout(wait, 1000);
s--;
} else {
time.remove();
input.disabled = false;
input.classList.remove("disabled");
input.removeEventListener("click", disable_submit);
}
}
wait();
});
el.find('.input-item-count-dec, .input-item-count-inc').on('click', function (e) {
e.preventDefault()
let step = parseFloat(this.getAttribute('data-step'))