admin: remove inline JS, add CodeMirror widget for jinja and yaml

This commit is contained in:
Jens Langhammer 2020-05-20 13:00:45 +02:00
parent e08c5ff875
commit c61c84e9f3
7 changed files with 36 additions and 33 deletions

View File

@ -4,6 +4,27 @@ from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
class CodeMirrorWidget(forms.Textarea):
"""Custom Textarea-based Widget that triggers a CodeMirror editor"""
# CodeMirror mode to enable
mode: str
def __init__(self, *args, mode="yaml", **kwargs):
super().__init__(*args, **kwargs)
self.mode = mode
def render(self, *args, **kwargs):
if "attrs" not in kwargs:
kwargs["attrs"] = {}
attrs = kwargs["attrs"]
if "class" not in attrs:
attrs["class"] = ""
attrs["class"] += " codemirror"
attrs["data-cm-mode"] = self.mode
return super().render(*args, **kwargs)
class InvalidYAMLInput(str): class InvalidYAMLInput(str):
"""Invalid YAML String type""" """Invalid YAML String type"""

View File

@ -2,7 +2,7 @@
from django import forms from django import forms
from passbook.admin.fields import YAMLField from passbook.admin.fields import CodeMirrorWidget, YAMLField
from passbook.core.models import User from passbook.core.models import User
@ -15,6 +15,7 @@ class UserForm(forms.ModelForm):
fields = ["username", "name", "email", "is_staff", "is_active", "attributes"] fields = ["username", "name", "email", "is_staff", "is_active", "attributes"]
widgets = { widgets = {
"name": forms.TextInput, "name": forms.TextInput,
"attributes": CodeMirrorWidget,
} }
field_classes = { field_classes = {
"attributes": YAMLField, "attributes": YAMLField,

View File

@ -66,6 +66,12 @@
{% trans 'Flows' %} {% trans 'Flows' %}
</a> </a>
</li> </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"> <li class="pf-c-nav__item">
<a href="{% url 'passbook_admin:stages' %}" <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' %}"> class="pf-c-nav__link {% is_active 'passbook_admin:stages' 'passbook_admin:stage-create' 'passbook_admin:stage-update' 'passbook_admin:stage-delete' %}">
@ -84,12 +90,6 @@
{% trans 'Invitations' %} {% trans 'Invitations' %}
</a> </a>
</li> </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>
</ul> </ul>
</section> </section>
</li> </li>

View File

@ -48,28 +48,6 @@
</div> </div>
</div> </div>
</section> </section>
<script>
const attributes = document.getElementsByName('attributes');
if (attributes.length > 0) {
// https://github.com/codemirror/CodeMirror/issues/5092
attributes[0].removeAttribute("required");
const attributesCM = CodeMirror.fromTextArea(attributes[0], {
mode: 'yaml',
theme: 'monokai',
lineNumbers: true,
});
}
const expressions = document.getElementsByName('expression');
if (expressions.length > 0) {
// https://github.com/codemirror/CodeMirror/issues/5092
expressions[0].removeAttribute("required");
const expressionCM = CodeMirror.fromTextArea(expressions[0], {
mode: 'jinja2',
theme: 'monokai',
lineNumbers: true,
});
}
</script>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}

View File

@ -2,6 +2,7 @@
from django import forms from django import forms
from passbook.admin.fields import CodeMirrorWidget
from passbook.policies.expression.models import ExpressionPolicy from passbook.policies.expression.models import ExpressionPolicy
from passbook.policies.forms import GENERAL_FIELDS from passbook.policies.forms import GENERAL_FIELDS
@ -19,4 +20,5 @@ class ExpressionPolicyForm(forms.ModelForm):
] ]
widgets = { widgets = {
"name": forms.TextInput(), "name": forms.TextInput(),
"expression": CodeMirrorWidget(mode="jinja2"),
} }

View File

@ -2,6 +2,7 @@
from django import forms from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from passbook.admin.fields import CodeMirrorWidget, YAMLField
from passbook.stages.invitation.models import Invitation, InvitationStage from passbook.stages.invitation.models import Invitation, InvitationStage
@ -27,7 +28,5 @@ class InvitationForm(forms.ModelForm):
labels = { labels = {
"fixed_data": _("Optional fixed data to enforce on user enrollment."), "fixed_data": _("Optional fixed data to enforce on user enrollment."),
} }
widgets = { widgets = {"fixed_data": CodeMirrorWidget}
"fixed_username": forms.TextInput(), field_classes = {"fixed_data": YAMLField}
"fixed_email": forms.TextInput(),
}

View File

@ -28,6 +28,8 @@ document.querySelectorAll(".codemirror").forEach((cm) => {
if ('data-cm-mode' in cm.attributes) { if ('data-cm-mode' in cm.attributes) {
cmMode = cm.attributes['data-cm-mode'].value; cmMode = cm.attributes['data-cm-mode'].value;
} }
// https://github.com/codemirror/CodeMirror/issues/5092
cm.removeAttribute("required");
CodeMirror.fromTextArea(cm, { CodeMirror.fromTextArea(cm, {
mode: cmMode, mode: cmMode,
theme: 'monokai', theme: 'monokai',