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

Merge branch 'develop' into feature

Arthur 1 год назад
Родитель
Сommit
1952d3e63a
30 измененных файлов с 6345 добавлено и 5124 удалено
  1. 1 1
      .github/ISSUE_TEMPLATE/bug_report.yaml
  2. 1 1
      .github/ISSUE_TEMPLATE/feature_request.yaml
  3. 1 0
      contrib/generated_schema.json
  4. 0 6
      docs/customization/custom-scripts.md
  5. 17 1
      docs/release-notes/version-4.0.md
  6. 1 1
      netbox/core/views.py
  7. 5 5
      netbox/dcim/models/cables.py
  8. 3 1
      netbox/netbox/settings.py
  9. 0 0
      netbox/project-static/dist/netbox.css
  10. 0 0
      netbox/project-static/dist/netbox.js
  11. 0 0
      netbox/project-static/dist/netbox.js.map
  12. 2 2
      netbox/project-static/package.json
  13. 56 20
      netbox/project-static/src/search.ts
  14. 5 0
      netbox/project-static/styles/overrides/_tabler.scss
  15. 8 8
      netbox/project-static/yarn.lock
  16. 1 1
      netbox/templates/core/object_jobs.html
  17. 2 2
      netbox/templates/extras/script/base.html
  18. 3 3
      netbox/templates/extras/script_list.html
  19. 1 1
      netbox/templates/virtualization/cluster.html
  20. 1 1
      netbox/templates/virtualization/virtualmachine.html
  21. BIN
      netbox/translations/de/LC_MESSAGES/django.mo
  22. 1242 1009
      netbox/translations/de/LC_MESSAGES/django.po
  23. 29 29
      netbox/translations/en/LC_MESSAGES/django.po
  24. 1236 1003
      netbox/translations/fr/LC_MESSAGES/django.po
  25. 1236 1003
      netbox/translations/pt/LC_MESSAGES/django.po
  26. 1236 1003
      netbox/translations/ru/LC_MESSAGES/django.po
  27. 1236 1003
      netbox/translations/tr/LC_MESSAGES/django.po
  28. 1 1
      netbox/utilities/templates/buttons/export.html
  29. 14 12
      netbox/utilities/templatetags/helpers.py
  30. 7 7
      requirements.txt

+ 1 - 1
.github/ISSUE_TEMPLATE/bug_report.yaml

@@ -26,7 +26,7 @@ body:
     attributes:
       label: NetBox Version
       description: What version of NetBox are you currently running?
-      placeholder: v4.0.3
+      placeholder: v4.0.5
     validations:
       required: true
   - type: dropdown

+ 1 - 1
.github/ISSUE_TEMPLATE/feature_request.yaml

@@ -14,7 +14,7 @@ body:
     attributes:
       label: NetBox version
       description: What version of NetBox are you currently running?
-      placeholder: v4.0.3
+      placeholder: v4.0.5
     validations:
       required: true
   - type: dropdown

+ 1 - 0
contrib/generated_schema.json

@@ -323,6 +323,7 @@
                         "100base-tx",
                         "100base-t1",
                         "1000base-t",
+                        "1000base-tx",
                         "2.5gbase-t",
                         "5gbase-t",
                         "10gbase-t",

+ 0 - 6
docs/customization/custom-scripts.md

@@ -65,12 +65,6 @@ class AnotherCustomScript(Script):
 script_order = (MyCustomScript, AnotherCustomScript)
 ```
 
-## Module Attributes
-
-### `name`
-
-You can define `name` within a script module (the Python file which contains one or more scripts) to set the module name. If `name` is not defined, the module's file name will be used.
-
 ## Script Attributes
 
 Script attributes are defined under a class named `Meta` within the script. These are optional, but encouraged.

+ 17 - 1
docs/release-notes/version-4.0.md

@@ -1,18 +1,34 @@
 # NetBox v4.0
 
-## v4.0.4 (FUTURE)
+## v4.0.6 (FUTURE)
+
+---
+
+## v4.0.5 (2024-06-06)
 
 ### Enhancements
 
 * [#14810](https://github.com/netbox-community/netbox/issues/14810) - Enable contact assignment for services
 * [#15489](https://github.com/netbox-community/netbox/issues/15489) - Add 1000Base-TX interface type
+* [#15873](https://github.com/netbox-community/netbox/issues/15873) - Improve readability of allocates resource numbers for clusters
 * [#16290](https://github.com/netbox-community/netbox/issues/16290) - Capture entire object in changelog data (but continue to display only non-internal attributes)
+* [#16353](https://github.com/netbox-community/netbox/issues/16353) - Enable plugins to extend object change view with custom content
 
 ### Bug Fixes
 
 * [#13422](https://github.com/netbox-community/netbox/issues/13422) - Rebuild MPTT trees for applicable models after merging staged changes
+* [#14567](https://github.com/netbox-community/netbox/issues/14567) - Apply active quicksearch value when exporting "current view" from object list
+* [#15194](https://github.com/netbox-community/netbox/issues/15194) - Avoid enqueuing duplicate event triggers for a modified object
+* [#16039](https://github.com/netbox-community/netbox/issues/16039) - Fix row highlighting for front & rear port connections under device view
+* [#16050](https://github.com/netbox-community/netbox/issues/16050) - Fix display of names & descriptions defined for custom scripts
+* [#16083](https://github.com/netbox-community/netbox/issues/16083) - Disable font ligatures to avoid peculiarities in rendered text
 * [#16202](https://github.com/netbox-community/netbox/issues/16202) - Fix site map button URL for certain localizations
+* [#16261](https://github.com/netbox-community/netbox/issues/16261) - Fix GraphQL filtering for certain multi-value filters
 * [#16286](https://github.com/netbox-community/netbox/issues/16286) - Fix global search support for provider accounts
+* [#16312](https://github.com/netbox-community/netbox/issues/16312) - Fix object list navigation for dashboard widgets
+* [#16315](https://github.com/netbox-community/netbox/issues/16315) - Fix filtering change log & journal entries by object type in UI
+* [#16376](https://github.com/netbox-community/netbox/issues/16376) - Update change log for the terminating object (e.g. interface) when attaching a cable
+* [#16400](https://github.com/netbox-community/netbox/issues/16400) - Fix AttributeError when attempting to restore a previous configuration revision after deleting the current one
 
 ---
 

+ 1 - 1
netbox/core/views.py

@@ -224,7 +224,7 @@ class ConfigRevisionRestoreView(ContentTypePermissionRequiredMixin, View):
         for param in PARAMS:
             params.append((
                 param.name,
-                current_config.data.get(param.name, None),
+                current_config.data.get(param.name, None) if current_config else None,
                 candidate_config.data.get(param.name, None)
             ))
 

+ 5 - 5
netbox/dcim/models/cables.py

@@ -355,11 +355,11 @@ class CableTermination(ChangeLoggedModel):
         super().save(*args, **kwargs)
 
         # Set the cable on the terminating object
-        termination_model = self.termination._meta.model
-        termination_model.objects.filter(pk=self.termination_id).update(
-            cable=self.cable,
-            cable_end=self.cable_end
-        )
+        termination = self.termination._meta.model.objects.get(pk=self.termination_id)
+        termination.snapshot()
+        termination.cable = self.cable
+        termination.cable_end = self.cable_end
+        termination.save()
 
     def delete(self, *args, **kwargs):
 

+ 3 - 1
netbox/netbox/settings.py

@@ -25,7 +25,7 @@ from utilities.string import trailing_slash
 # Environment setup
 #
 
-VERSION = '4.0.4-dev'
+VERSION = '4.0.6-dev'
 HOSTNAME = platform.node()
 # Set the base directory two levels up
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -368,6 +368,8 @@ INSTALLED_APPS = [
     'drf_spectacular',
     'drf_spectacular_sidecar',
 ]
+if not DEBUG:
+    INSTALLED_APPS.remove('debug_toolbar')
 if not DJANGO_ADMIN_ENABLED:
     INSTALLED_APPS.remove('django.contrib.admin')
 

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


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


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


+ 2 - 2
netbox/project-static/package.json

@@ -27,10 +27,10 @@
     "bootstrap": "5.3.3",
     "clipboard": "2.0.11",
     "flatpickr": "4.6.13",
-    "gridstack": "10.1.2",
+    "gridstack": "10.2.0",
     "htmx.org": "1.9.12",
     "query-string": "9.0.0",
-    "sass": "1.77.2",
+    "sass": "1.77.4",
     "tom-select": "2.3.1",
     "typeface-inter": "3.18.1",
     "typeface-roboto-mono": "1.1.13"

+ 56 - 20
netbox/project-static/src/search.ts

@@ -7,38 +7,74 @@ import { isTruthy } from './util';
  */
 function quickSearchEventHandler(event: Event): void {
   const quicksearch = event.currentTarget as HTMLInputElement;
-  const clearbtn = document.getElementById("quicksearch_clear") as HTMLAnchorElement;
+  const clearbtn = document.getElementById('quicksearch_clear') as HTMLAnchorElement;
   if (isTruthy(clearbtn)) {
-    if (quicksearch.value === "") {
-      clearbtn.classList.add("invisible");
+    if (quicksearch.value === '') {
+      clearbtn.classList.add('invisible');
     } else {
-      clearbtn.classList.remove("invisible");
+      clearbtn.classList.remove('invisible');
     }
   }
 }
 
+/**
+ * Clear the existing search parameters in the link to export Current View.
+ */
+function clearLinkParams(): void {
+  const link = document.getElementById('export_current_view') as HTMLLinkElement;
+  const linkUpdated = link?.href.split('&')[0];
+  link.setAttribute('href', linkUpdated);
+}
+
+/**
+ * Update the Export View link to add the Quick Search parameters.
+ * @param event
+ */
+function handleQuickSearchParams(event: Event): void {
+  const quickSearchParameters = event.currentTarget as HTMLInputElement;
+
+  // Clear the existing search parameters
+  clearLinkParams();
+
+  if (quickSearchParameters != null) {
+    const link = document.getElementById('export_current_view') as HTMLLinkElement;
+    const search_parameter = `q=${quickSearchParameters.value}`;
+    const linkUpdated = link?.href + '&' + search_parameter;
+    link.setAttribute('href', linkUpdated);
+  }
+}
+
 /**
  * Initialize Quicksearch Event listener/handlers.
  */
 export function initQuickSearch(): void {
-  const quicksearch = document.getElementById("quicksearch") as HTMLInputElement;
-  const clearbtn = document.getElementById("quicksearch_clear") as HTMLAnchorElement;
+  const quicksearch = document.getElementById('quicksearch') as HTMLInputElement;
+  const clearbtn = document.getElementById('quicksearch_clear') as HTMLAnchorElement;
   if (isTruthy(quicksearch)) {
-    quicksearch.addEventListener("keyup", quickSearchEventHandler, {
-      passive: true
-    })
-    quicksearch.addEventListener("search", quickSearchEventHandler, {
-      passive: true
-    })
+    quicksearch.addEventListener('keyup', quickSearchEventHandler, {
+      passive: true,
+    });
+    quicksearch.addEventListener('search', quickSearchEventHandler, {
+      passive: true,
+    });
+    quicksearch.addEventListener('change', handleQuickSearchParams, {
+      passive: true,
+    });
+
     if (isTruthy(clearbtn)) {
-      clearbtn.addEventListener("click", async () => {
-        const search = new Event('search');
-        quicksearch.value = '';
-        await new Promise(f => setTimeout(f, 100));
-        quicksearch.dispatchEvent(search);
-      }, {
-        passive: true
-      })
+      clearbtn.addEventListener(
+        'click',
+        async () => {
+          const search = new Event('search');
+          quicksearch.value = '';
+          await new Promise(f => setTimeout(f, 100));
+          quicksearch.dispatchEvent(search);
+          clearLinkParams();
+        },
+        {
+          passive: true,
+        },
+      );
     }
   }
 }

+ 5 - 0
netbox/project-static/styles/overrides/_tabler.scss

@@ -39,3 +39,8 @@ table a {
   // Adjust table anchor link contrast as not enough contrast in dark mode
   filter: brightness(110%);
 }
+
+// Override background color alpha value
+[data-bs-theme=dark] ::selection {
+  background-color: rgba(var(--tblr-primary-rgb),.48)
+}

+ 8 - 8
netbox/project-static/yarn.lock

@@ -1754,10 +1754,10 @@ graphql@16.8.1:
   resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07"
   integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==
 
-gridstack@10.1.2:
-  version "10.1.2"
-  resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.1.2.tgz#58b5ae0057a8aa5e4f6563041c4ca2def3aa4268"
-  integrity sha512-Nn27XGQ68WtBC513cKQQ4t/dA2uuN/xnNUU50puXEJv6IFk5SzT0Dnsq68GpopO1n0tXUKZKm1Rw7uOUMDz1KQ==
+gridstack@10.2.0:
+  version "10.2.0"
+  resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.2.0.tgz#4ba9c7ee69a730851721a9f5cb33dc55026ded1f"
+  integrity sha512-svKAOq/dfinpvhe/nnxdyZOOEd9qynXiOPHvL96PALE0yWChWp/6lechnqKwud0tL/rRyAfMJ6Hh/z2fS13pBA==
 
 has-bigints@^1.0.1, has-bigints@^1.0.2:
   version "1.0.2"
@@ -2482,10 +2482,10 @@ safe-regex-test@^1.0.3:
     es-errors "^1.3.0"
     is-regex "^1.1.4"
 
-sass@1.77.2:
-  version "1.77.2"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.2.tgz#18d4ed2eefc260cdc8099c5439ec1303fd5863aa"
-  integrity sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==
+sass@1.77.4:
+  version "1.77.4"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.4.tgz#92059c7bfc56b827c56eb116778d157ec017a5cd"
+  integrity sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==
   dependencies:
     chokidar ">=3.0.0 <4.0.0"
     immutable "^4.0.0"

+ 1 - 1
netbox/templates/core/object_jobs.html

@@ -5,7 +5,7 @@
   <div class="row mb-3">
     <div class="col col-md-12">
       <div class="card">
-        <div class="card-body table-responsive">
+        <div class="table-responsive">
           {% render_table table 'inc/table.html' %}
           {% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
         </div>

+ 2 - 2
netbox/templates/extras/script/base.html

@@ -4,7 +4,7 @@
 {% load log_levels %}
 {% load i18n %}
 
-{% block title %}{{ script }}{% endblock %}
+{% block title %}{{ script.python_class.name }}{% endblock %}
 
 {% block object_identifier %}
   {{ script.full_name }}
@@ -17,7 +17,7 @@
 
 {% block subtitle %}
   <div class="text-secondary fs-5">
-    {{ script.Meta.description|markdown }}
+    {{ script.python_class.Meta.description|markdown }}
   </div>
 {% endblock subtitle %}
 

+ 3 - 3
netbox/templates/extras/script_list.html

@@ -56,15 +56,15 @@
                 <tr>
                   <td>
                     {% if script.is_executable %}
-                      <a href="{% url 'extras:script' script.pk %}" id="{{ script.module }}.{{ script.class_name }}">{{ script.name }}</a>
+                      <a href="{% url 'extras:script' script.pk %}" id="{{ script.module }}.{{ script.class_name }}">{{ script.python_class.name }}</a>
                     {% else %}
-                      <a href="{% url 'extras:script_jobs' script.pk %}" id="{{ script.module }}.{{ script.class_name }}">{{ script.name }}</a>
+                      <a href="{% url 'extras:script_jobs' script.pk %}" id="{{ script.module }}.{{ script.class_name }}">{{ script.python_class.name }}</a>
                       <span class="text-danger">
                         <i class="mdi mdi-alert" title="{% trans "Script is no longer present in the source file" %}"></i>
                       </span>
                     {% endif %}
                   </td>
-                  <td>{{ script.description|markdown|placeholder }}</td>
+                  <td>{{ script.python_class.Meta.description|markdown|placeholder }}</td>
                   {% if last_job %}
                     <td>
                       <a href="{% url 'extras:script_result' job_pk=last_job.pk %}">{{ last_job.created|isodatetime }}</a>

+ 1 - 1
netbox/templates/virtualization/cluster.html

@@ -59,7 +59,7 @@
               <th scope="row"><i class="mdi mdi-chip"></i> {% trans "Memory" %}</th>
               <td>
                   {% if memory_sum %}
-                      {{ memory_sum|humanize_megabytes }}
+                      <span title={{ memory_sum }}>{{ memory_sum|humanize_megabytes }}</span>
                   {% else %}
                       {{ ''|placeholder }}
                   {% endif %}

+ 1 - 1
netbox/templates/virtualization/virtualmachine.html

@@ -125,7 +125,7 @@
                     <th scope="row"><i class="mdi mdi-chip"></i> {% trans "Memory" %}</th>
                     <td>
                         {% if object.memory %}
-                            {{ object.memory|humanize_megabytes }}
+                            <span title={{ object.memory }}>{{ object.memory|humanize_megabytes }}</span>
                         {% else %}
                             {{ ''|placeholder }}
                         {% endif %}

BIN
netbox/translations/de/LC_MESSAGES/django.mo


Разница между файлами не показана из-за своего большого размера
+ 1242 - 1009
netbox/translations/de/LC_MESSAGES/django.po


+ 29 - 29
netbox/translations/en/LC_MESSAGES/django.po

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-06-04 05:02+0000\n"
+"POT-Creation-Date: 2024-06-05 05:02+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -965,7 +965,7 @@ msgstr ""
 #: netbox/extras/forms/filtersets.py:143 netbox/extras/forms/filtersets.py:183
 #: netbox/extras/forms/filtersets.py:199 netbox/extras/forms/filtersets.py:230
 #: netbox/extras/forms/filtersets.py:254 netbox/extras/forms/filtersets.py:450
-#: netbox/extras/forms/filtersets.py:488 netbox/ipam/forms/filtersets.py:99
+#: netbox/extras/forms/filtersets.py:485 netbox/ipam/forms/filtersets.py:99
 #: netbox/ipam/forms/filtersets.py:266 netbox/ipam/forms/filtersets.py:307
 #: netbox/ipam/forms/filtersets.py:382 netbox/ipam/forms/filtersets.py:475
 #: netbox/ipam/forms/filtersets.py:534 netbox/ipam/forms/filtersets.py:552
@@ -1577,9 +1577,9 @@ msgid "Creation"
 msgstr ""
 
 #: netbox/core/forms/filtersets.py:71 netbox/extras/forms/filtersets.py:470
-#: netbox/extras/forms/filtersets.py:513 netbox/extras/tables/tables.py:183
+#: netbox/extras/forms/filtersets.py:510 netbox/extras/tables/tables.py:183
 #: netbox/extras/tables/tables.py:504 netbox/templates/core/job.html:20
-#: netbox/templates/extras/objectchange.html:51
+#: netbox/templates/extras/objectchange.html:52
 #: netbox/tenancy/tables/contacts.py:90 netbox/vpn/tables/l2vpn.py:59
 msgid "Object Type"
 msgstr ""
@@ -1619,9 +1619,9 @@ msgstr ""
 #: netbox/core/forms/filtersets.py:123 netbox/dcim/forms/bulk_edit.py:361
 #: netbox/dcim/forms/filtersets.py:353 netbox/dcim/forms/filtersets.py:397
 #: netbox/dcim/forms/model_forms.py:258 netbox/extras/forms/filtersets.py:465
-#: netbox/extras/forms/filtersets.py:508
+#: netbox/extras/forms/filtersets.py:505
 #: netbox/templates/dcim/rackreservation.html:58
-#: netbox/templates/extras/objectchange.html:35
+#: netbox/templates/extras/objectchange.html:36
 #: netbox/templates/extras/savedfilter.html:21
 #: netbox/templates/inc/user_menu.html:15 netbox/templates/users/token.html:21
 #: netbox/templates/users/user.html:6 netbox/templates/users/user.html:14
@@ -1976,7 +1976,7 @@ msgstr ""
 #: netbox/extras/tables/tables.py:509 netbox/extras/tables/tables.py:574
 #: netbox/netbox/tables/tables.py:243 netbox/templates/extras/eventrule.html:84
 #: netbox/templates/extras/journalentry.html:18
-#: netbox/templates/extras/objectchange.html:57
+#: netbox/templates/extras/objectchange.html:58
 #: netbox/tenancy/tables/contacts.py:93 netbox/vpn/tables/l2vpn.py:64
 msgid "Object"
 msgstr ""
@@ -4172,7 +4172,7 @@ msgid "Connection"
 msgstr ""
 
 #: netbox/dcim/forms/filtersets.py:1254 netbox/extras/forms/bulk_edit.py:316
-#: netbox/extras/forms/bulk_import.py:242 netbox/extras/forms/filtersets.py:476
+#: netbox/extras/forms/bulk_import.py:242 netbox/extras/forms/filtersets.py:473
 #: netbox/extras/forms/model_forms.py:551 netbox/extras/tables/tables.py:512
 #: netbox/templates/extras/journalentry.html:30
 msgid "Kind"
@@ -7144,23 +7144,23 @@ msgstr ""
 msgid "Tenant groups"
 msgstr ""
 
-#: netbox/extras/forms/filtersets.py:454 netbox/extras/forms/filtersets.py:492
+#: netbox/extras/forms/filtersets.py:454 netbox/extras/forms/filtersets.py:489
 msgid "After"
 msgstr ""
 
-#: netbox/extras/forms/filtersets.py:459 netbox/extras/forms/filtersets.py:497
+#: netbox/extras/forms/filtersets.py:459 netbox/extras/forms/filtersets.py:494
 msgid "Before"
 msgstr ""
 
-#: netbox/extras/forms/filtersets.py:487 netbox/extras/tables/tables.py:456
+#: netbox/extras/forms/filtersets.py:484 netbox/extras/tables/tables.py:456
 #: netbox/extras/tables/tables.py:542 netbox/extras/tables/tables.py:567
-#: netbox/templates/extras/objectchange.html:31
+#: netbox/templates/extras/objectchange.html:32
 msgid "Time"
 msgstr ""
 
-#: netbox/extras/forms/filtersets.py:501 netbox/extras/forms/model_forms.py:282
+#: netbox/extras/forms/filtersets.py:498 netbox/extras/forms/model_forms.py:282
 #: netbox/extras/tables/tables.py:470 netbox/templates/extras/eventrule.html:77
-#: netbox/templates/extras/objectchange.html:45
+#: netbox/templates/extras/objectchange.html:46
 msgid "Action"
 msgstr ""
 
@@ -8256,7 +8256,7 @@ msgid "Full Name"
 msgstr ""
 
 #: netbox/extras/tables/tables.py:483
-#: netbox/templates/extras/objectchange.html:67
+#: netbox/templates/extras/objectchange.html:68
 msgid "Request ID"
 msgstr ""
 
@@ -10275,7 +10275,7 @@ msgid "Journal Entries"
 msgstr ""
 
 #: netbox/netbox/navigation/menu.py:359
-#: netbox/templates/extras/objectchange.html:8
+#: netbox/templates/extras/objectchange.html:9
 #: netbox/templates/extras/objectchange_list.html:4
 msgid "Change Log"
 msgstr ""
@@ -10734,8 +10734,8 @@ msgstr ""
 #: netbox/templates/extras/configcontext.html:70
 #: netbox/templates/extras/eventrule.html:72
 #: netbox/templates/extras/htmx/script_result.html:56
-#: netbox/templates/extras/objectchange.html:123
-#: netbox/templates/extras/objectchange.html:141
+#: netbox/templates/extras/objectchange.html:124
+#: netbox/templates/extras/objectchange.html:142
 #: netbox/templates/extras/webhook.html:67
 #: netbox/templates/extras/webhook.html:79
 #: netbox/templates/inc/panel_table.html:13
@@ -12308,48 +12308,48 @@ msgstr ""
 msgid "New Journal Entry"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:28
+#: netbox/templates/extras/objectchange.html:29
 #: netbox/templates/users/objectpermission.html:42
 msgid "Change"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:78
+#: netbox/templates/extras/objectchange.html:79
 msgid "Difference"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:81
+#: netbox/templates/extras/objectchange.html:82
 msgid "Previous"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:84
+#: netbox/templates/extras/objectchange.html:85
 msgid "Next"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:92
+#: netbox/templates/extras/objectchange.html:93
 msgid "Object Created"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:94
+#: netbox/templates/extras/objectchange.html:95
 msgid "Object Deleted"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:96
+#: netbox/templates/extras/objectchange.html:97
 msgid "No Changes"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:110
+#: netbox/templates/extras/objectchange.html:111
 msgid "Pre-Change Data"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:121
+#: netbox/templates/extras/objectchange.html:122
 msgid "Warning: Comparing non-atomic change to previous change record"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:130
+#: netbox/templates/extras/objectchange.html:131
 msgid "Post-Change Data"
 msgstr ""
 
-#: netbox/templates/extras/objectchange.html:153
+#: netbox/templates/extras/objectchange.html:162
 #, python-format
 msgid "See All %(count)s Changes"
 msgstr ""

Разница между файлами не показана из-за своего большого размера
+ 1236 - 1003
netbox/translations/fr/LC_MESSAGES/django.po


Разница между файлами не показана из-за своего большого размера
+ 1236 - 1003
netbox/translations/pt/LC_MESSAGES/django.po


Разница между файлами не показана из-за своего большого размера
+ 1236 - 1003
netbox/translations/ru/LC_MESSAGES/django.po


Разница между файлами не показана из-за своего большого размера
+ 1236 - 1003
netbox/translations/tr/LC_MESSAGES/django.po


+ 1 - 1
netbox/utilities/templates/buttons/export.html

@@ -4,7 +4,7 @@
     <i class="mdi mdi-download"></i> {% trans "Export" %}
   </button>
   <ul class="dropdown-menu dropdown-menu-end">
-    <li><a class="dropdown-item" href="?{% if url_params %}{{ url_params }}&{% endif %}export=table">{% trans "Current View" %}</a></li>
+    <li><a id="export_current_view" class="dropdown-item" href="?{% if url_params %}{{ url_params }}&{% endif %}export=table">{% trans "Current View" %}</a></li>
     <li><a class="dropdown-item" href="?{% if url_params %}{{ url_params }}&{% endif %}export">{% trans "All Data" %} ({{ data_format }})</a></li>
     {% if export_templates %}
       <li>

+ 14 - 12
netbox/utilities/templatetags/helpers.py

@@ -1,14 +1,9 @@
-import datetime
 import json
 from typing import Dict, Any
 from urllib.parse import quote
 
 from django import template
-from django.conf import settings
-from django.template.defaultfilters import date
 from django.urls import NoReverseMatch, reverse
-from django.utils import timezone
-from django.utils.safestring import mark_safe
 
 from core.models import ObjectType
 from utilities.forms import get_selected_values, TableConfigForm
@@ -92,15 +87,22 @@ def humanize_speed(speed):
 @register.filter()
 def humanize_megabytes(mb):
     """
-    Express a number of megabytes in the most suitable unit (e.g. gigabytes or terabytes).
+    Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.).
     """
     if not mb:
-        return ''
-    if not mb % 1048576:  # 1024^2
-        return f'{int(mb / 1048576)} TB'
-    if not mb % 1024:
-        return f'{int(mb / 1024)} GB'
-    return f'{mb} MB'
+        return ""
+
+    PB_SIZE = 1000000000
+    TB_SIZE = 1000000
+    GB_SIZE = 1000
+
+    if mb >= PB_SIZE:
+        return f"{mb / PB_SIZE:.2f} PB"
+    if mb >= TB_SIZE:
+        return f"{mb / TB_SIZE:.2f} TB"
+    if mb >= GB_SIZE:
+        return f"{mb / GB_SIZE:.2f} GB"
+    return f"{mb} MB"
 
 
 @register.filter()

+ 7 - 7
requirements.txt

@@ -1,6 +1,6 @@
 Django==5.0.6
 django-cors-headers==4.3.1
-django-debug-toolbar==4.3.0
+django-debug-toolbar==4.4.2
 django-filter==24.2
 django-htmx==1.17.3
 django-graphiql-debug-toolbar==0.2.0
@@ -15,23 +15,23 @@ django-tables2==2.7.0
 django-timezone-field==6.1.0
 djangorestframework==3.15.1
 drf-spectacular==0.27.2
-drf-spectacular-sidecar==2024.5.1
+drf-spectacular-sidecar==2024.6.1
 feedparser==6.0.11
 gunicorn==22.0.0
 Jinja2==3.1.4
 Markdown==3.6
-mkdocs-material==9.5.24
+mkdocs-material==9.5.26
 mkdocstrings[python-legacy]==0.25.1
-netaddr==1.2.1
+netaddr==1.3.0
 nh3==0.2.17
 Pillow==10.3.0
 psycopg[c,pool]==3.1.19
 PyYAML==6.0.1
-requests==2.32.2
+requests==2.32.3
 social-auth-app-django==5.4.1
 social-auth-core==4.5.4
-strawberry-graphql==0.230.0
-strawberry-graphql-django==0.40.0
+strawberry-graphql==0.234.0
+strawberry-graphql-django==0.42.0
 svgwrite==1.4.3
 tablib==3.6.1
 tzdata==2024.1

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