admin: remove inline JS, add CodeMirror widget for jinja and yaml
This commit is contained in:
		| @ -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""" | ||||||
|  |  | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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 %} | ||||||
|  | |||||||
| @ -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"), | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -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(), |  | ||||||
|         } |  | ||||||
|  | |||||||
| @ -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', | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer