Просмотр исходного кода

Closes #11294: Markdown Preview (#11894)

* MarkdownWidget

* Change border and color of active markdown tab

* Fix template name typo

* Add render markdown endpoint

* Static assets for markdown widget

* widget style fix and unique ids based on name

* Replace SmallTextArea with SmallMarkdownWidget

* Clear innerHTML before swapping

* render markdown directly in template

* change render markdown view path

* remove small markdown widget

* Simplify rendering logic

* Use a form to clean input Markdown data

---------

Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
Aron Bergur Jóhannsson 2 лет назад
Родитель
Сommit
fa60f9d2a8

+ 1 - 4
netbox/circuits/forms/bulk_edit.py

@@ -7,7 +7,7 @@ from ipam.models import ASN
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
-    add_blank_choice, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SmallTextarea,
+    add_blank_choice, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
     StaticSelect,
     StaticSelect,
 )
 )
 
 
@@ -35,7 +35,6 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 
@@ -63,7 +62,6 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 
@@ -125,7 +123,6 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 

+ 1 - 12
netbox/dcim/forms/bulk_edit.py

@@ -11,7 +11,7 @@ from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, CommentField, DynamicModelChoiceField,
     add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, CommentField, DynamicModelChoiceField,
-    DynamicModelMultipleChoiceField, form_from_model, SmallTextarea, StaticSelect, SelectSpeedWidget,
+    DynamicModelMultipleChoiceField, form_from_model, StaticSelect, SelectSpeedWidget
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -138,7 +138,6 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -309,7 +308,6 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -345,7 +343,6 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -406,7 +403,6 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -441,7 +437,6 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -551,7 +546,6 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -594,7 +588,6 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -644,7 +637,6 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -668,7 +660,6 @@ class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -714,7 +705,6 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -776,7 +766,6 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 

+ 1 - 0
netbox/extras/forms/__init__.py

@@ -2,6 +2,7 @@ from .model_forms import *
 from .filtersets import *
 from .filtersets import *
 from .bulk_edit import *
 from .bulk_edit import *
 from .bulk_import import *
 from .bulk_import import *
+from .misc import *
 from .mixins import *
 from .mixins import *
 from .config import *
 from .config import *
 from .scripts import *
 from .scripts import *

+ 14 - 0
netbox/extras/forms/misc.py

@@ -0,0 +1,14 @@
+from django import forms
+
+__all__ = (
+    'RenderMarkdownForm',
+)
+
+
+class RenderMarkdownForm(forms.Form):
+    """
+    Provides basic validation for markup to be rendered.
+    """
+    text = forms.CharField(
+        required=False
+    )

+ 2 - 0
netbox/extras/urls.py

@@ -92,4 +92,6 @@ urlpatterns = [
     path('scripts/results/<int:job_result_pk>/', views.ScriptResultView.as_view(), name='script_result'),
     path('scripts/results/<int:job_result_pk>/', views.ScriptResultView.as_view(), name='script_result'),
     re_path(r'^scripts/(?P<module>.([^.]+)).(?P<name>.(.+))/', views.ScriptView.as_view(), name='script'),
     re_path(r'^scripts/(?P<module>.([^.]+)).(?P<name>.(.+))/', views.ScriptView.as_view(), name='script'),
 
 
+    # Markdown
+    path('render/markdown/', views.RenderMarkdownView.as_view(), name="render_markdown")
 ]
 ]

+ 17 - 1
netbox/extras/views.py

@@ -1,7 +1,7 @@
 from django.contrib import messages
 from django.contrib import messages
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import Count, Q
 from django.db.models import Count, Q
-from django.http import Http404, HttpResponseForbidden
+from django.http import Http404, HttpResponseBadRequest, HttpResponseForbidden, HttpResponse
 from django.shortcuts import get_object_or_404, redirect, render
 from django.shortcuts import get_object_or_404, redirect, render
 from django.urls import reverse
 from django.urls import reverse
 from django.views.generic import View
 from django.views.generic import View
@@ -10,6 +10,7 @@ from rq import Worker
 
 
 from netbox.views import generic
 from netbox.views import generic
 from utilities.htmx import is_htmx
 from utilities.htmx import is_htmx
+from utilities.templatetags.builtins.filters import render_markdown
 from utilities.utils import copy_safe_request, count_related, get_viewname, normalize_querydict, shallow_compare_dict
 from utilities.utils import copy_safe_request, count_related, get_viewname, normalize_querydict, shallow_compare_dict
 from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
 from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
 from . import filtersets, forms, tables
 from . import filtersets, forms, tables
@@ -885,3 +886,18 @@ class JobResultBulkDeleteView(generic.BulkDeleteView):
     queryset = JobResult.objects.all()
     queryset = JobResult.objects.all()
     filterset = filtersets.JobResultFilterSet
     filterset = filtersets.JobResultFilterSet
     table = tables.JobResultTable
     table = tables.JobResultTable
+
+
+#
+# Markdown
+#
+
+class RenderMarkdownView(View):
+
+    def post(self, request):
+        form = forms.RenderMarkdownForm(request.POST)
+        if not form.is_valid():
+            HttpResponseBadRequest()
+        rendered = render_markdown(form.cleaned_data['text'])
+
+        return HttpResponse(rendered)

+ 1 - 12
netbox/ipam/forms/bulk_edit.py

@@ -10,7 +10,7 @@ from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, NumericArrayField,
     add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, NumericArrayField,
-    SmallTextarea, StaticSelect, DynamicModelMultipleChoiceField,
+    StaticSelect, DynamicModelMultipleChoiceField
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -48,7 +48,6 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -69,7 +68,6 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -116,7 +114,6 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -145,7 +142,6 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -227,7 +223,6 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -266,7 +261,6 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -314,7 +308,6 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -359,7 +352,6 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -442,7 +434,6 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -474,7 +465,6 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -504,7 +494,6 @@ class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox-dark.css


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox-light.css


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox-print.css


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
netbox/project-static/dist/netbox.js.map


+ 2 - 0
netbox/project-static/src/buttons/index.ts

@@ -4,6 +4,7 @@ import { initMoveButtons } from './moveOptions';
 import { initReslug } from './reslug';
 import { initReslug } from './reslug';
 import { initSelectAll } from './selectAll';
 import { initSelectAll } from './selectAll';
 import { initSelectMultiple } from './selectMultiple';
 import { initSelectMultiple } from './selectMultiple';
+import { initMarkdownPreviews } from './markdownPreview';
 
 
 export function initButtons(): void {
 export function initButtons(): void {
   for (const func of [
   for (const func of [
@@ -13,6 +14,7 @@ export function initButtons(): void {
     initSelectAll,
     initSelectAll,
     initSelectMultiple,
     initSelectMultiple,
     initMoveButtons,
     initMoveButtons,
+    initMarkdownPreviews,
   ]) {
   ]) {
     func();
     func();
   }
   }

+ 45 - 0
netbox/project-static/src/buttons/markdownPreview.ts

@@ -0,0 +1,45 @@
+import { isTruthy } from 'src/util';
+
+/**
+ * interface for htmx configRequest event
+ */
+declare global {
+  interface HTMLElementEventMap {
+    'htmx:configRequest': CustomEvent<{
+      parameters: Record<string, string>;
+      headers: Record<string, string>;
+    }>;
+  }
+}
+
+function initMarkdownPreview(markdownWidget: HTMLDivElement) {
+  const previewButton = markdownWidget.querySelector('button.preview-button') as HTMLButtonElement;
+  const textarea = markdownWidget.querySelector('textarea') as HTMLTextAreaElement;
+  const preview = markdownWidget.querySelector('div.preview') as HTMLDivElement;
+
+  /**
+   * Make sure the textarea has style attribute height
+   * So that it can be copied over to preview div.
+   */
+  if (!isTruthy(textarea.style.height)) {
+    const { height } = textarea.getBoundingClientRect();
+    textarea.style.height = `${height}px`;
+  }
+
+  /**
+   * Add the value of the textarea to the body of the htmx request
+   * and copy the height of text are to the preview div
+   */
+  previewButton.addEventListener('htmx:configRequest', e => {
+    e.detail.parameters = { text: textarea.value || '' };
+    e.detail.headers['X-CSRFToken'] = window.CSRF_TOKEN;
+    preview.style.minHeight = textarea.style.height;
+    preview.innerHTML = '';
+  });
+}
+
+export function initMarkdownPreviews(): void {
+  for (const markdownWidget of document.querySelectorAll<HTMLDivElement>('.markdown-widget')) {
+    initMarkdownPreview(markdownWidget);
+  }
+}

+ 22 - 7
netbox/project-static/styles/netbox.scss

@@ -236,12 +236,12 @@ table {
   }
   }
 
 
   th.asc > a::after {
   th.asc > a::after {
-    content: "\f0140";
+    content: '\f0140';
     font-family: 'Material Design Icons';
     font-family: 'Material Design Icons';
   }
   }
 
 
   th.desc > a::after {
   th.desc > a::after {
-    content: "\f0143";
+    content: '\f0143';
     font-family: 'Material Design Icons';
     font-family: 'Material Design Icons';
   }
   }
 
 
@@ -416,18 +416,18 @@ nav.search {
   }
   }
 }
 }
 
 
-// Styles for the quicksearch and its clear button; 
+// Styles for the quicksearch and its clear button;
 // Overrides input-group styles and adds transition effects
 // Overrides input-group styles and adds transition effects
 .quicksearch {
 .quicksearch {
-  input[type="search"] {
-    border-radius: $border-radius  !important;
+  input[type='search'] {
+    border-radius: $border-radius !important;
   }
   }
 
 
   button {
   button {
     margin-left: -32px !important;
     margin-left: -32px !important;
     z-index: 100 !important;
     z-index: 100 !important;
     outline: none !important;
     outline: none !important;
-    border-radius: $border-radius  !important;
+    border-radius: $border-radius !important;
     transition: visibility 0s, opacity 0.2s linear;
     transition: visibility 0s, opacity 0.2s linear;
   }
   }
 
 
@@ -998,9 +998,24 @@ div.card-overlay {
   padding: 8px;
   padding: 8px;
 }
 }
 
 
+/* Markdown widget */
+.markdown-widget {
+  .nav-link {
+    border-bottom: 0;
+
+    &.active {
+      background-color: var(--nbx-body-bg);
+    }
+  }
+
+  .nav-tabs {
+    background-color: var(--nbx-pre-bg);
+  }
+}
+
 // Preformatted text blocks
 // Preformatted text blocks
 td pre {
 td pre {
-  margin-bottom: 0
+  margin-bottom: 0;
 }
 }
 pre.block {
 pre.block {
   padding: $spacer;
   padding: $spacer;

+ 1 - 2
netbox/tenancy/forms/bulk_edit.py

@@ -2,7 +2,7 @@ from django import forms
 
 
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import *
 from tenancy.models import *
-from utilities.forms import CommentField, DynamicModelChoiceField, SmallTextarea
+from utilities.forms import CommentField, DynamicModelChoiceField
 
 
 __all__ = (
 __all__ = (
     'ContactBulkEditForm',
     'ContactBulkEditForm',
@@ -106,7 +106,6 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 

+ 1 - 1
netbox/utilities/forms/fields/fields.py

@@ -27,7 +27,7 @@ class CommentField(forms.CharField):
     """
     """
     A textarea with support for Markdown rendering. Exists mostly just to add a standard `help_text`.
     A textarea with support for Markdown rendering. Exists mostly just to add a standard `help_text`.
     """
     """
-    widget = forms.Textarea
+    widget = widgets.MarkdownWidget
     help_text = f"""
     help_text = f"""
         <i class="mdi mdi-information-outline"></i>
         <i class="mdi mdi-information-outline"></i>
         <a href="{static('docs/reference/markdown/')}" target="_blank" tabindex="-1">
         <a href="{static('docs/reference/markdown/')}" target="_blank" tabindex="-1">

+ 5 - 0
netbox/utilities/forms/widgets.py

@@ -16,6 +16,7 @@ __all__ = (
     'ColorSelect',
     'ColorSelect',
     'DatePicker',
     'DatePicker',
     'DateTimePicker',
     'DateTimePicker',
+    'MarkdownWidget',
     'NumericArrayField',
     'NumericArrayField',
     'SelectDurationWidget',
     'SelectDurationWidget',
     'SelectSpeedWidget',
     'SelectSpeedWidget',
@@ -116,6 +117,10 @@ class SelectDurationWidget(forms.NumberInput):
     template_name = 'widgets/select_duration.html'
     template_name = 'widgets/select_duration.html'
 
 
 
 
+class MarkdownWidget(forms.Textarea):
+    template_name = 'widgets/markdown_input.html'
+
+
 class NumericArrayField(SimpleArrayField):
 class NumericArrayField(SimpleArrayField):
 
 
     def clean(self, value):
     def clean(self, value):

+ 1 - 1
netbox/utilities/templates/form_helpers/render_field.html

@@ -6,7 +6,7 @@
   {# Render the field label, except for: #}
   {# Render the field label, except for: #}
   {#   1. Checkboxes (label appears to the right of the field #}
   {#   1. Checkboxes (label appears to the right of the field #}
   {#   2. Textareas with no label set (will expand across entire row) #}
   {#   2. Textareas with no label set (will expand across entire row) #}
-  {% if field|widget_type == 'checkboxinput' or field|widget_type == 'textarea' and not label %}
+  {% if field|widget_type == 'checkboxinput' or field|widget_type == 'textarea' or field|widget_type == 'markdownwidget' and not label %}
   {% else %}
   {% else %}
     <label for="{{ field.id_for_label }}" class="col-sm-3 col-form-label text-lg-end{% if field.field.required %} required{% endif %}">
     <label for="{{ field.id_for_label }}" class="col-sm-3 col-form-label text-lg-end{% if field.field.required %} required{% endif %}">
       {{ label }}
       {{ label }}

+ 22 - 0
netbox/utilities/templates/widgets/markdown_input.html

@@ -0,0 +1,22 @@
+<div class="border rounded markdown-widget"> 
+    <ul class="nav nav-tabs px-3 pt-2 rounded-top border-0">
+        <li class="nav-item" role="presentation">
+          <button class="nav-link active " id="{{ widget.name }}-input-tab" data-bs-toggle="tab" data-bs-target="#{{ widget.name }}-input" type="button" role="tab" aria-controls="{{ widget.name }}-input" aria-selected="true">
+            Write
+          </button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button hx-target="#{{ widget.name }}-preview" hx-swap="innerHTML" hx-post="{% url 'extras:render_markdown' %}" class="nav-link preview-button" id="{{ widget.name }}-markdown-preview-tab" data-bs-toggle="tab" data-bs-target="#{{ widget.name }}-markdown-preview" type="button" role="tab" aria-controls="{{ widget.name }}-markdown-preview" aria-selected="false">
+              Preview   
+            </button>
+          </li>
+      </ul>
+      <div class="tab-content bg-body rounded-bottom border-top">
+        <div class="tab-pane show active" id="{{ widget.name }}-input" role="tabpanel" aria-labelledby="{{ widget.name }}-input-tab">
+        {% include "django/forms/widgets/textarea.html" %}
+        </div>
+        <div class="tab-pane show" id="{{ widget.name }}-markdown-preview" role="tabpanel" aria-labelledby="{{ widget.name }}-markdown-preview-tab">
+            <div id="{{ widget.name }}-preview" class="preview px-3 py-2">Testing</div>
+        </div>
+    </div>
+</div>

+ 1 - 3
netbox/virtualization/forms/bulk_edit.py

@@ -9,7 +9,7 @@ from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BulkEditNullBooleanSelect, BulkRenameForm, CommentField, DynamicModelChoiceField,
     add_blank_choice, BulkEditNullBooleanSelect, BulkRenameForm, CommentField, DynamicModelChoiceField,
-    DynamicModelMultipleChoiceField, SmallTextarea, StaticSelect
+    DynamicModelMultipleChoiceField, StaticSelect
 )
 )
 from virtualization.choices import *
 from virtualization.choices import *
 from virtualization.models import *
 from virtualization.models import *
@@ -90,7 +90,6 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 
@@ -163,7 +162,6 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label=_('Comments')
         label=_('Comments')
     )
     )
 
 

+ 1 - 3
netbox/wireless/forms/bulk_edit.py

@@ -5,7 +5,7 @@ from dcim.choices import LinkStatusChoices
 from ipam.models import VLAN
 from ipam.models import VLAN
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
-from utilities.forms import add_blank_choice, CommentField, DynamicModelChoiceField, SmallTextarea
+from utilities.forms import add_blank_choice, CommentField, DynamicModelChoiceField
 from wireless.choices import *
 from wireless.choices import *
 from wireless.constants import SSID_MAX_LENGTH
 from wireless.constants import SSID_MAX_LENGTH
 from wireless.models import *
 from wireless.models import *
@@ -74,7 +74,6 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 
@@ -119,7 +118,6 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
         required=False
         required=False
     )
     )
     comments = CommentField(
     comments = CommentField(
-        widget=SmallTextarea,
         label='Comments'
         label='Comments'
     )
     )
 
 

Некоторые файлы не были показаны из-за большого количества измененных файлов