diff --git a/docs/release-notes/version-4.0.md b/docs/release-notes/version-4.0.md index e2502df8c..507b8dcdd 100644 --- a/docs/release-notes/version-4.0.md +++ b/docs/release-notes/version-4.0.md @@ -2,6 +2,10 @@ ## v4.0.0 (FUTURE) +### Breaking Changes + +* The deprecated `device_role` & `device_role_id` filters for devices have been removed. (Use `role` and `role_id` instead.) + ### New Features #### Complete UI Refresh ([#12128](https://github.com/netbox-community/netbox/issues/12128)) @@ -26,3 +30,5 @@ The NetBox user interface has been completely refreshed and updated. * [#14657](https://github.com/netbox-community/netbox/issues/14657) - Remove backward compatibility for old permissions mapping under `ActionsMixin` * [#14658](https://github.com/netbox-community/netbox/issues/14658) - Remove backward compatibility for importing `process_webhook()` (now `extras.webhooks.send_webhook()`) * [#14740](https://github.com/netbox-community/netbox/issues/14740) - Remove the obsolete `BootstrapMixin` form mixin class +* [#15099](https://github.com/netbox-community/netbox/issues/15099) - Remove obsolete `device_role` and `device_role_id` filters for devices +* [#15100](https://github.com/netbox-community/netbox/issues/15100) - Remove obsolete `NullableCharField` class diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 68edc93f6..4810e9cab 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1288,18 +1288,6 @@ class DeviceComponentFilterSet(django_filters.FilterSet): to_field_name='name', label=_('Virtual Chassis'), ) - # TODO: Remove in v4.0 - device_role_id = django_filters.ModelMultipleChoiceFilter( - field_name='device__role', - queryset=DeviceRole.objects.all(), - label=_('Device role (ID)'), - ) - device_role = django_filters.ModelMultipleChoiceFilter( - field_name='device__role__slug', - queryset=DeviceRole.objects.all(), - to_field_name='slug', - label=_('Device role (slug)'), - ) def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/project-static/dist/netbox.css b/netbox/project-static/dist/netbox.css index 48a70fd10..e016f0923 100644 Binary files a/netbox/project-static/dist/netbox.css and b/netbox/project-static/dist/netbox.css differ diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 50b9ca705..71b1fc774 100644 Binary files a/netbox/project-static/dist/netbox.js and b/netbox/project-static/dist/netbox.js differ diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index 431f5e626..8f4dde4e2 100644 Binary files a/netbox/project-static/dist/netbox.js.map and b/netbox/project-static/dist/netbox.js.map differ diff --git a/netbox/project-static/src/links.ts b/netbox/project-static/src/links.ts deleted file mode 100644 index d39f3605b..000000000 --- a/netbox/project-static/src/links.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { isTruthy, getElements } from './util'; - -/** - * Allow any element to be made "clickable" with the use of the `data-href` attribute. - */ -export function initLinks(): void { - for (const link of getElements('*[data-href]')) { - const href = link.getAttribute('data-href'); - if (isTruthy(href)) { - link.addEventListener('click', () => { - window.location.assign(href); - }); - } - } -} diff --git a/netbox/project-static/src/netbox.ts b/netbox/project-static/src/netbox.ts index 8c274c64b..59faab222 100644 --- a/netbox/project-static/src/netbox.ts +++ b/netbox/project-static/src/netbox.ts @@ -12,7 +12,6 @@ import { initInterfaceTable } from './tables'; import { initSideNav } from './sidenav'; import { initDashboard } from './dashboard'; import { initRackElevation } from './racks'; -import { initLinks } from './links'; import { initHtmx } from './htmx'; function initDocument(): void { @@ -31,7 +30,6 @@ function initDocument(): void { initSideNav, initDashboard, initRackElevation, - initLinks, initHtmx, ]) { init(); diff --git a/netbox/project-static/styles/netbox.scss b/netbox/project-static/styles/netbox.scss index 0fece199b..3afaaa9fc 100644 --- a/netbox/project-static/styles/netbox.scss +++ b/netbox/project-static/styles/netbox.scss @@ -5,7 +5,6 @@ @import '../node_modules/@tabler/core/src/scss/vendor/tom-select'; // Overrides of external libraries -@import 'overrides/slim-select'; @import 'overrides/tabler'; // Transitional styling to ease migration of templates from NetBox v3.x diff --git a/netbox/project-static/styles/overrides/_slim-select.scss b/netbox/project-static/styles/overrides/_slim-select.scss deleted file mode 100644 index e9f079d44..000000000 --- a/netbox/project-static/styles/overrides/_slim-select.scss +++ /dev/null @@ -1,195 +0,0 @@ -// SlimSelect Style Overrides. - -$height: $input-height; -$white: $white; -$font-color: $input-color; -$font-placeholder-color: $input-placeholder-color; -$font-disabled-color: $form-select-disabled-color; -$primary-color: $primary; -$border-color: $form-select-border-color; -$search-highlight-color: $yellow; -$border-radius: $form-select-border-radius; -$spacing-l: $input-padding-x; -$spacing-m: $input-padding-x; -$spacing-s: $input-padding-x; - -:root { - // Light Mode Variables. - --nbx-select-content-bg: #{$form-select-bg}; - --nbx-select-option-selected-bg: #{$gray-300}; - --nbx-select-option-hover-bg: #{$blue}; - --nbx-select-option-hover-color: #{$white}; - --nbx-select-placeholder-color: #{$gray-500}; - --nbx-select-value-color: #{$white}; - &[data-netbox-color-mode='dark'] { - // Dark Mode Variables. - --nbx-select-content-bg: #{$gray-900}; - --nbx-select-option-selected-bg: #{$gray-500}; - --nbx-select-option-hover-bg: #{$blue-200}; - --nbx-select-option-hover-color: #{color-contrast($blue-200)}; - --nbx-select-placeholder-color: #{$gray-700}; - --nbx-select-value-color: #{$black}; - } -} - -@import '../node_modules/slim-select/src/slim-select/slimselect'; - -.ss-main { - color: $form-select-color; - - .ss-single-selected, - .ss-multi-selected { - padding: $form-select-padding-y $input-padding-x $form-select-padding-y $form-select-padding-x; - background-color: $form-select-bg; - border: $form-select-border-width solid $input-border-color; - &[disabled] { - color: $form-select-disabled-color; - background-color: $form-select-disabled-bg; - border-color: $form-select-disabled-border-color; - } - } - - div.ss-multi-selected .ss-values .ss-disabled, - div.ss-single-selected span.placeholder .ss-disabled { - color: var(--nbx-select-placeholder-color); - } - - .ss-single-selected { - span.ss-arrow { - // Inherit the arrow color from the parent (see color selector). - span.arrow-down, - span.arrow-up { - border-color: currentColor; - color: $text-muted; - } - } - // Don't show the depth indicator outside of the menu. - .placeholder .depth { - display: none; - } - span.placeholder > *, - span.placeholder { - line-height: $input-line-height; - } - } - - .ss-multi-selected { - align-items: center; - padding-right: $input-padding-x; - padding-left: $input-padding-x; - - .ss-values { - .ss-disabled { - padding: 4px 0; - } - .ss-value { - color: var(--nbx-select-value-color); - border-radius: $badge-border-radius; - - // Don't show the depth indicator outside of the menu. - .depth { - display: none; - } - } - } - .ss-add { - margin: 0 0.75rem; - } - } - - .ss-content { - background-color: var(--nbx-select-content-bg); - .ss-list { - .ss-option { - &.ss-option-selected { - color: $body-color; - background-color: var(--nbx-select-option-selected-bg); - } - - &:hover { - color: var(--nbx-select-option-hover-color); - background-color: var(--nbx-select-option-hover-bg); - } - - &:last-child { - border-bottom-right-radius: $form-select-border-radius; - border-bottom-left-radius: $form-select-border-radius; - } - - &.ss-disabled { - background-color: unset; - &:hover { - color: $form-select-disabled-color; - } - } - - .depth { - // Lighten the dash prefix on nested options. - opacity: 0.3; - } - } - - &::-webkit-scrollbar { - right: 0; - width: 4px; - &:hover { - opacity: 0.8; - } - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - right: 0; - width: 2px; - background-color: var(--nbx-sidebar-scroll); - } - } - border-bottom-right-radius: $form-select-border-radius; - border-bottom-left-radius: $form-select-border-radius; - .ss-search { - padding-right: $spacer * 0.5; - - button { - margin-left: $spacer * 0.75; - } - - input[type='search'] { - color: $input-color; - background-color: $form-select-bg; - border: $input-border-width solid $input-border-color; - &:focus { - border-color: $form-select-focus-border-color; - outline: 0; - @if $enable-shadows { - @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); - } @else { - // Avoid using mixin so we can pass custom focus shadow properly - box-shadow: $form-select-focus-box-shadow; - } - } - } - } - } -} - -// Fix slim-select 1.x placeholder styling -.ss-main { - .ss-single-selected { - .placeholder { - cursor: pointer; - opacity: 1; - background-color: transparent !important; - } - } -} - -// Apply red border for fields inside a row with .has-errors -.has-errors { - .ss-single-selected, - .ss-multi-selected { - border-color: $red; - } -} diff --git a/netbox/utilities/fields.py b/netbox/utilities/fields.py index 65e01db81..d2c14c2c7 100644 --- a/netbox/utilities/fields.py +++ b/netbox/utilities/fields.py @@ -12,26 +12,10 @@ __all__ = ( 'ColorField', 'CounterCacheField', 'NaturalOrderingField', - 'NullableCharField', 'RestrictedGenericForeignKey', ) -# Deprecated: Retained only to ensure successful migration from early releases -# Use models.CharField(null=True) instead -# TODO: Remove in v4.0 -class NullableCharField(models.CharField): - description = "Stores empty values as NULL rather than ''" - - def to_python(self, value): - if isinstance(value, models.CharField): - return value - return value or '' - - def get_prep_value(self, value): - return value or None - - class ColorField(models.CharField): default_validators = [ColorValidator] description = "A hexadecimal RGB color code"