Skip to content

Commit 2136e4e

Browse files
philli-mgoapunk
authored andcommitted
assets/userindicator: update template, add styles and js functionality for new user indicator
1 parent eff184e commit 2136e4e

File tree

12 files changed

+166
-32
lines changed

12 files changed

+166
-32
lines changed

changelog/7840.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- new user indicator for user side pages with custom js functionality mimicing the language dropdown functionality from the BO stylguide useing our own vanilla js #7840

meinberlin/apps/projects/templates/meinberlin_projects/project_detail.html

+8-10
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,14 @@
2828
{% endblock %}
2929

3030
{% block breadcrumbs %}
31-
<div id="layout-grid__area--contentheader">
32-
<div id="content-header">
33-
<nav class="breadcrumb" aria-label="{% translate 'You are here:' %}">
34-
<ol>
35-
<li><a href="/">meinBerlin</a></li>
36-
<li><a href="{% url 'meinberlin_plans:plan-list' %}">{% translate 'Project Overview' %}</a></li>
37-
<li class="active" aria-current="page">{{ project.name|truncatechars:50 }}</li>
38-
</ol>
39-
</nav>
40-
</div>
31+
<div id="content-header">
32+
<nav class="breadcrumb" aria-label="{% translate 'You are here:' %}">
33+
<ol>
34+
<li><a href="/">meinBerlin</a></li>
35+
<li><a href="{% url 'meinberlin_plans:plan-list' %}">{% translate 'Project Overview' %}</a></li>
36+
<li class="active" aria-current="page">{{ project.name|truncatechars:50 }}</li>
37+
</ol>
38+
</nav>
4139
</div>
4240
{% endblock %}
4341

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
function init () {
2+
const userIndicator = document.querySelectorAll('#js-user-indicator')
3+
if (userIndicator) {
4+
let closeTimeout
5+
const trigger = document.querySelector('#js-user-indicator-trigger')
6+
const dropdown = document.querySelector('#js-user-indicator-dropdown')
7+
const close = document.querySelector('#js-user-indicator-close')
8+
const container = document.querySelector('#js-user-indicator')
9+
10+
function closeDropdown () {
11+
document.removeEventListener('click', outsideClickListener)
12+
dropdown.style.display = 'none'
13+
container.classList.remove('is-open')
14+
trigger.setAttribute('aria-expanded', false)
15+
clearTimeout(closeTimeout)
16+
}
17+
18+
function openDropdown () {
19+
if (container.classList.contains('is-open')) {
20+
closeDropdown()
21+
} else {
22+
dropdown.style.display = 'block'
23+
container.classList.add('is-open')
24+
trigger.setAttribute('aria-expanded', true)
25+
26+
document.addEventListener('click', outsideClickListener)
27+
}
28+
}
29+
30+
function outsideClickListener (e) {
31+
if (!container.contains(e.target) && e.target !== close) {
32+
closeDropdown()
33+
}
34+
}
35+
36+
trigger.addEventListener('click', function (event) {
37+
event.preventDefault()
38+
openDropdown()
39+
})
40+
41+
close.addEventListener('click', function (event) {
42+
event.stopPropagation() // Prevent the event from bubbling up to the document
43+
closeDropdown()
44+
})
45+
46+
dropdown.addEventListener('keyup', function (e) {
47+
if (e.keyCode === 27) {
48+
closeDropdown()
49+
trigger.focus()
50+
}
51+
})
52+
53+
dropdown.addEventListener('focusout', function (e) {
54+
closeTimeout = setTimeout(function () {
55+
if (!dropdown.contains(e.relatedTarget)) {
56+
closeDropdown()
57+
}
58+
}, 10)
59+
})
60+
}
61+
}
62+
63+
document.addEventListener('DOMContentLoaded', init, false)

meinberlin/apps/users/templates/meinberlin_users/user_indicator.html

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11
{% load i18n static %}
22

3-
{% block extra_js %}
4-
<script defer src="{% static 'user_menu.js' %}"></script>
5-
{% endblock %}
6-
7-
<div class="usermenu__container">
8-
<div class="usermenu__wrapper">
3+
<div class="user-indicator__container">
4+
<div id="js-user-indicator" class="user-indicator__wrapper">
95
{% if request.user.is_authenticated %}
106
<button
11-
class="js-usermenu-btn"
7+
id="js-user-indicator-trigger"
128
type="button"
139
aria-haspopup="menu"
14-
aria-controls="user-actions"
10+
aria-controls="js-user-indicator-dropdown"
1511
tabindex="0">
1612
<i class="fas fa-user text--color-primary" aria-hidden="true"></i>
1713
{{ request.user.username }}
1814
</button>
19-
<div role="menu" class="dropdown js-usermenu" id="user-actions" aria-label="Login of Register" tabindex="-1">
15+
<div role="menu" class="dropdown" id="js-user-indicator-dropdown" aria-label="Login of Register" tabindex="-1">
2016
<ul class="list--clean">
21-
<li ><a href="{% url 'account' %}" role="menuitem">{% translate "Account Settings" %}</a></li>
17+
<li><button id="js-user-indicator-close" type="button" class="button button--close user-indicator__close" title="{% translate 'close' %}" aria-label="{% translate 'menu close' %}"></button></li>
18+
<li><a href="{% url 'account' %}" role="menuitem">{% translate "Account Settings" %}</a></li>
2219
{% for organisation in request.user.organisations %}
2320
<li><a href="{% url 'a4dashboard:project-list' organisation_slug=organisation.slug %}" role="menuitem">{{ organisation.name }}</a></li>
2421
{% endfor %}
2522
{% if request.user.is_superuser %}
2623
<li><a href="{% url 'meinberlin_platformemails:create' %}" role="menuitem">{% translate "Platform Email" %}</a></li>
2724
{% endif %}
2825
<li>
29-
<form class="u-inline" action="{% url 'account_logout' %}" method="post" aria-label="{% translate 'Logout' %}" role="menuitem">
26+
<form class="block--nogap text--color-dark" action="{% url 'account_logout' %}" method="post" aria-label="{% translate 'Logout' %}" role="menuitem">
3027
{% csrf_token %}
3128
<input type="hidden" name="next" value="{{ redirect_field_value }}">
3229
<button type="submit">{% translate "Logout" %}</button>
@@ -36,19 +33,19 @@
3633
</div>
3734
{% else %}
3835
<button
39-
class="js-usermenu-btn"
36+
id="js-user-indicator-trigger"
4037
type="button"
4138
aria-haspopup="menu"
42-
aria-controls="login-register-menu"
39+
aria-controls="js-user-indicator-dropdown"
4340
tabindex="0">
4441
<i class="fas fa-user text--color-primary" aria-hidden="true"></i>
4542
{% translate "Login" %}
4643
</button>
47-
<div role="menu" class="dropdown js-usermenu" id="login-register-menu" aria-label="Login of Register" tabindex="-1">
44+
<div role="menu" class="dropdown" id="js-user-indicator-dropdown" aria-label="Login of Register" tabindex="-1">
4845
<ul class="list--clean">
49-
<li><button type="button" class="button button--close user-indicator__close" title="{% translate 'close' %}" aria-label="{% translate 'menu close' %}"></button></li>
46+
<li><button id="js-user-indicator-close" type="button" class="button button--close user-indicator__close" title="{% translate 'close' %}" aria-label="{% translate 'menu close' %}"></button></li>
5047
<li>
51-
<a href="{% url 'account_login' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Login" %}</a>
48+
<a class="button button--light" href="{% url 'account_login' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Login" %}</a>
5249
</li>
5350
<li>
5451
<a href="{% url 'account_signup' %}?next={{ redirect_field_value|urlencode }}" role="menuitem">{% translate "Register" %}</a>

meinberlin/assets/js/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'select2' // used to select projects in containers
44

55
import '../../apps/actions/assets/timestamps.js'
66
import '../../apps/newsletters/assets/dynamic_fields.js'
7+
import '../../apps/users/assets/user_indicator.js'
78

89
// map search function
910
import 'adhocracy4/adhocracy4/maps/static/a4maps/a4maps_address.js'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// styles copied from their stylguide from #layout-grid__area--contentheader
2+
.user-indicator__container {
3+
grid-area: contentheader;
4+
grid-column: mainbar;
5+
display: flex;
6+
flex-direction: column;
7+
position: relative;
8+
z-index: 1;
9+
10+
&:before {
11+
position: absolute;
12+
background-color: $secondary;
13+
inset: 0 0 0 -9999px;
14+
display: block;
15+
content: "";
16+
z-index: -1;
17+
box-shadow: 9999px 0 0 $secondary;
18+
border-left: 9999px solid $secondary;
19+
}
20+
21+
button {
22+
padding: .5em 0;
23+
}
24+
25+
[role="menu"] {
26+
display: none;
27+
}
28+
29+
[aria-expanded="true"] + [role="menu"] {
30+
display: block;
31+
}
32+
33+
// end of copied styling
34+
35+
.user-indicator__wrapper {
36+
@extend .content-language-select;
37+
38+
color: var(--color-white);
39+
40+
> .dropdown .button {
41+
width: 100%;
42+
}
43+
44+
// copied styles
45+
@media print, (width <= 73.8125rem) {
46+
margin-left: -12px;
47+
margin-right: -12px;
48+
width: auto;
49+
padding-left: 12px;
50+
padding-right: 12px
51+
}
52+
}
53+
}
54+
55+
.button--close.user-indicator__close {
56+
text-align: end;
57+
min-height: auto;
58+
59+
&:after {
60+
font-size: 1em;
61+
}
62+
}

meinberlin/assets/scss/style_dashboard.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
@import "components/dialogue_box";
4949
@import "components/doc_toc";
5050
@import "components/document";
51-
@import "components/dropdown";
51+
@import "components_dashboard/dropdown";
5252
@import "components/dsgvo_video_embed";
5353
@import "components/embed_layout";
5454
@import "components/embed_status";

meinberlin/assets/scss/style_user_facing.scss

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
@import "~bootstrap/scss/variables"; // to be deleted after menues changes
1010
@import "~bootstrap/scss/maps"; // to be deleted after menues changes
1111
@import "~bootstrap/scss/mixins"; // to be deleted after menues changes
12-
@import "~bootstrap/scss/dropdown"; // to be deleted after menues changes
1312

1413
@import "components/a4-comments";
1514
@import "components/action";
@@ -23,7 +22,6 @@
2322
@import "components/dialogue_box";
2423
@import "components/doc_toc";
2524
@import "components/document";
26-
@import "components/dropdown";
2725
@import "components/dsgvo_video_embed";
2826
@import "components/embed_layout";
2927
@import "components/embed_status";
@@ -65,3 +63,4 @@
6563
@import "components_user_facing/searchform-slot";
6664
@import "components_user_facing/select";
6765
@import "components_user_facing/tab";
66+
@import "components_user_facing/user_indicator";

meinberlin/assets/scss/styles_user_facing/_utility.scss

+9
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,12 @@ hr.no-space {
1818
.is-hidden {
1919
display: none;
2020
}
21+
22+
// BO defines this as black so overwritting
23+
.text--color-primary {
24+
color: $primary;
25+
}
26+
27+
.text--color-dark {
28+
color: var(--color-black);
29+
}

meinberlin/templates/a4dashboard/base_dashboard.html

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
{% block header %}
99
{% endblock %}
10+
{% block menu %}{% endblock %}
1011

1112
{% block content %}
1213

meinberlin/templates/base.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@
5252
{% endblock %}
5353
<!-- FIXME we don't currently want their grid in dashboard however this does not work if someone names wagtail, project or plan page 'dashboard' -->
5454
<main role="main" tabindex="-1" {% if '/dashboard' not in request.path or '/components' not in request.path %} id="layout-grid" {% endif %}>
55-
56-
{% block breadcrumbs %}{% endblock %}
57-
{% block menu %}{% userindicator %}{% endblock %}
55+
<div id="layout-grid__area--contentheader">
56+
{% block breadcrumbs %}{% endblock %}
57+
{% block menu %}{% userindicator %}{% endblock %}
58+
</div>
5859

5960
{% if messages %}
6061
<ul class="messages">

0 commit comments

Comments
 (0)