Compare commits

..

1 Commits

Author SHA1 Message Date
Jeremy Stretch
c3e111c769 Fixes #21102: Fix GraphiQL explorer UI 2026-01-12 14:34:17 -05:00
12 changed files with 23 additions and 76 deletions

View File

@@ -1,26 +1,20 @@
---
name: Deprecation
name: 🗑 Deprecation
type: Deprecation
description: Designation of a feature or behavior that will be removed in a future release
description: The removal of an existing feature or resource
labels: ["netbox", "type: deprecation"]
body:
- type: textarea
attributes:
label: Deprecated Functionality
label: Proposed Changes
description: >
Describe the feature(s) and/or behavior that is being flagged for deprecation.
validations:
required: true
- type: input
attributes:
label: Scheduled removal
description: In what future release will the deprecated functionality be removed?
Describe in detail the proposed changes. What is being removed?
validations:
required: true
- type: textarea
attributes:
label: Justification
description: Please provide justification for the deprecation.
description: Please provide justification for the proposed change(s).
validations:
required: true
- type: textarea

View File

@@ -1,20 +0,0 @@
---
name: 🗑️ Feature Removal
type: Removal
description: The removal of a deprecated feature or resource
labels: ["netbox", "type: removal"]
body:
- type: input
attributes:
label: Deprecation Issue
description: Specify the issue in which this deprecation was announced.
placeholder: "#1234"
validations:
required: true
- type: textarea
attributes:
label: Summary of Changes
description: >
List all changes necessary to remove the deprecated feature or resource.
validations:
required: true

View File

@@ -372,8 +372,8 @@ class IPAddressForm(TenancyForm, PrimaryModelForm):
'virtual_machine_id': instance.assigned_object.virtual_machine.pk,
})
# Disable object assignment fields if the IP address is designated as primary or OOB
if self.initial.get('primary_for_parent') or self.initial.get('oob_for_parent'):
# Disable object assignment fields if the IP address is designated as primary
if self.initial.get('primary_for_parent'):
self.fields['interface'].disabled = True
self.fields['vminterface'].disabled = True
self.fields['fhrpgroup'].disabled = True

View File

@@ -940,13 +940,6 @@ class IPAddress(ContactsMixin, PrimaryModel):
_("Cannot reassign IP address while it is designated as the primary IP for the parent object")
)
# can't use is_oob_ip as self.assigned_object might be changed
if hasattr(original_parent, 'oob_ip') and original_parent.oob_ip_id == self.pk:
if parent != original_parent:
raise ValidationError(
_("Cannot reassign IP address while it is designated as the OOB IP for the parent object")
)
# Validate IP status selection
if self.status == IPAddressStatusChoices.STATUS_SLAAC and self.family != 6:
raise ValidationError({

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
.docExplorerWrap{height:unset!important;min-width:unset!important;width:unset!important}.docExplorerWrap svg{display:unset}.doc-explorer-title{font-size:var(--font-size-h2);font-weight:var(--font-weight-medium)}.doc-explorer-rhs{display:none}.graphiql-explorer-root{font-family:var(--font-family-mono)!important;font-size:var(--font-size-body)!important;padding:0!important}.graphiql-explorer-root>div>div{border-color:hsla(var(--color-neutral),var(--alpha-background-heavy))!important;padding-top:var(--px-16)}.graphiql-explorer-root input{background:unset}.graphiql-explorer-root select{background:hsl(var(--color-base))!important;border:1px solid hsla(var(--color-neutral),var(--alpha-secondary));border-radius:var(--border-radius-4);color:hsl(var(--color-neutral))!important;margin:0 var(--px-8);padding:var(--px-4) var(--px-6)}.graphiql-operation-title-bar .toolbar-button{line-height:0;margin-left:var(--px-8);color:hsla(var(--color-neutral),var(--alpha-secondary, .6));font-size:var(--font-size-h3);vertical-align:middle}.graphiql-explorer-graphql-arguments input{line-height:0}.graphiql-explorer-actions{border-color:hsla(var(--color-neutral),var(--alpha-background-heavy))!important}
.docExplorerWrap{height:unset!important;min-width:unset!important;width:unset!important}.docExplorerWrap svg{display:unset}.doc-explorer-title{font-size:var(--font-size-h2);font-weight:var(--font-weight-medium)}.doc-explorer-rhs{display:none}.graphiql-explorer-root{font-family:var(--font-family-mono)!important;font-size:var(--font-size-body)!important;padding:0!important}.graphiql-explorer-root>div>div{padding-top:var(--px-16);border-color:hsla(var(--color-neutral),var(--alpha-background-heavy))!important}.graphiql-explorer-root>div{overflow:auto!important}.graphiql-explorer-root input{background:unset}.graphiql-explorer-root select{border:1px solid hsla(var(--color-neutral),var(--alpha-secondary));border-radius:var(--border-radius-4);margin:0 var(--px-8);padding:var(--px-4)var(--px-6);background:hsl(var(--color-base))!important;color:hsl(var(--color-neutral))!important}.toolbar-button{all:unset;cursor:pointer;margin-left:var(--px-6);color:hsl(var(--color-primary));line-height:0!important;font-size:var(--font-size-h3)!important}.graphiql-explorer-slug .toolbar-button,.graphiql-explorer-graphql-arguments .toolbar-button{font-size:inherit!important}.graphiql-explorer-graphql-arguments input{min-width:2rem;line-height:0}.graphiql-explorer-actions{border-color:hsla(var(--color-neutral),var(--alpha-background-heavy))!important}

View File

@@ -6,7 +6,7 @@
"license": "Apache-2.0",
"private": true,
"dependencies": {
"@graphiql/plugin-explorer": "3.2.6",
"@graphiql/plugin-explorer": "4.0.6",
"graphiql": "4.1.2",
"graphql": "16.12.0",
"js-cookie": "3.0.5",

View File

@@ -294,10 +294,10 @@
react-compiler-runtime "19.1.0-rc.1"
zustand "^5"
"@graphiql/plugin-explorer@3.2.6":
version "3.2.6"
resolved "https://registry.npmjs.org/@graphiql/plugin-explorer/-/plugin-explorer-3.2.6.tgz"
integrity sha512-MXzG/zVNzZfes4Em253bHyAbD/lwwAZkPKvxCAQkjz0i3dtcv4uF3D8iqJ7214iu3SCphbORYZZUC93fik1yew==
"@graphiql/plugin-explorer@4.0.6":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@graphiql/plugin-explorer/-/plugin-explorer-4.0.6.tgz#bec1207dc27334914590ab31f46c2e944bbf4ebf"
integrity sha512-TppIi92YPER3v70nlF01KTQrq9AiYqkZicSd1hpU7aqGmbqw/pLwBNLUEcfENBoJtw574Qxjswb01+GaYK0Tzw==
dependencies:
graphiql-explorer "^0.9.0"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-13 05:05+0000\n"
"POT-Creation-Date: 2026-01-08 05:04+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"
@@ -1822,6 +1822,7 @@ msgid "ASN Count"
msgstr ""
#: netbox/circuits/tables/virtual_circuits.py:64
#: netbox/netbox/navigation/menu.py:235
#: netbox/templates/circuits/virtualcircuit.html:87
#: netbox/templates/vpn/l2vpn.html:60 netbox/templates/vpn/tunnel.html:72
#: netbox/vpn/tables/tunnels.py:59
@@ -12189,10 +12190,6 @@ msgstr ""
msgid "L2VPNs"
msgstr ""
#: netbox/netbox/navigation/menu.py:235
msgid "L2VPN Terminations"
msgstr ""
#: netbox/netbox/navigation/menu.py:241
msgid "IKE Proposals"
msgstr ""
@@ -15941,7 +15938,7 @@ msgstr ""
#: netbox/users/forms/model_forms.py:126
msgid ""
"Tokens must be at least 40 characters in length. <strong>Be sure to record "
"your token</strong> prior to submitting this form, as it will no longer be "
"your key</strong> prior to submitting this form, as it will no longer be "
"accessible once the token has been created."
msgstr ""
@@ -16080,7 +16077,7 @@ msgid "write enabled"
msgstr ""
#: netbox/users/models/tokens.py:72
msgid "Permit create/update/delete operations using this token"
msgid "Permit create/update/delete operations using this key"
msgstr ""
#: netbox/users/models/tokens.py:76
@@ -16129,16 +16126,12 @@ msgstr ""
msgid "tokens"
msgstr ""
#: netbox/users/models/tokens.py:217
msgid "Unable to save v2 tokens: API_TOKEN_PEPPERS is not defined."
msgstr ""
#: netbox/users/models/tokens.py:222
#: netbox/users/models/tokens.py:219
#, python-brace-format
msgid "Invalid pepper ID: {id}. Check configured API_TOKEN_PEPPERS."
msgstr ""
#: netbox/users/models/tokens.py:235
#: netbox/users/models/tokens.py:232
#, python-brace-format
msgid ""
"Expiration time must be in the future. Current server time is {current_time} "

View File

@@ -123,7 +123,7 @@ class UserTokenForm(forms.ModelForm):
token = forms.CharField(
label=_('Token'),
help_text=_(
'Tokens must be at least 40 characters in length. <strong>Be sure to record your token</strong> prior to '
'Tokens must be at least 40 characters in length. <strong>Be sure to record your key</strong> prior to '
'submitting this form, as it will no longer be accessible once the token has been created.'
),
widget=forms.TextInput(

View File

@@ -69,7 +69,7 @@ class Token(models.Model):
write_enabled = models.BooleanField(
verbose_name=_('write enabled'),
default=True,
help_text=_('Permit create/update/delete operations using this token')
help_text=_('Permit create/update/delete operations using this key')
)
# For legacy v1 tokens, this field stores the plaintext 40-char token value. Not used for v2.
plaintext = models.CharField(
@@ -213,9 +213,6 @@ class Token(models.Model):
def clean(self):
super().clean()
if self.version == TokenVersionChoices.V2 and not settings.API_TOKEN_PEPPERS:
raise ValidationError(_("Unable to save v2 tokens: API_TOKEN_PEPPERS is not defined."))
if self._state.adding:
if self.pepper_id is not None and self.pepper_id not in settings.API_TOKEN_PEPPERS:
raise ValidationError(_(

View File

@@ -1,10 +1,9 @@
from datetime import timedelta
from django.core.exceptions import ValidationError
from django.test import TestCase, override_settings
from django.test import TestCase
from django.utils import timezone
from users.choices import TokenVersionChoices
from users.models import User, Token
from utilities.testing import create_test_user
@@ -95,15 +94,6 @@ class TokenTest(TestCase):
token.refresh_from_db()
self.assertEqual(token.description, 'New Description')
@override_settings(API_TOKEN_PEPPERS={})
def test_v2_without_peppers_configured(self):
"""
Attempting to save a v2 token without API_TOKEN_PEPPERS defined should raise a ValidationError.
"""
token = Token(version=TokenVersionChoices.V2)
with self.assertRaises(ValidationError):
token.clean()
class UserConfigTest(TestCase):