nautobot 3.0.0a2__py3-none-any.whl → 3.0.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (659) hide show
  1. nautobot/apps/choices.py +4 -2
  2. nautobot/apps/filters.py +7 -9
  3. nautobot/apps/models.py +2 -2
  4. nautobot/apps/ui.py +13 -1
  5. nautobot/apps/utils.py +8 -0
  6. nautobot/circuits/filters.py +3 -2
  7. nautobot/circuits/navigation.py +3 -2
  8. nautobot/circuits/templates/circuits/circuit_create.html +3 -3
  9. nautobot/circuits/templates/circuits/circuittermination_create.html +9 -24
  10. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +6 -6
  11. nautobot/circuits/templates/circuits/inc/speed_widget.html +12 -12
  12. nautobot/circuits/tests/integration/test_circuit.py +10 -13
  13. nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +0 -3
  14. nautobot/circuits/views.py +6 -2
  15. nautobot/cloud/filters.py +1 -1
  16. nautobot/cloud/navigation.py +3 -2
  17. nautobot/core/api/schema.py +1 -1
  18. nautobot/core/api/serializers.py +6 -1
  19. nautobot/core/api/urls.py +2 -0
  20. nautobot/core/api/views.py +12 -0
  21. nautobot/core/apps/__init__.py +11 -10
  22. nautobot/core/celery/__init__.py +3 -5
  23. nautobot/core/checks.py +46 -0
  24. nautobot/core/choices.py +1 -1
  25. nautobot/core/cli/bootstrap_v3_to_v5.py +105 -13
  26. nautobot/core/cli/migrate_deprecated_templates.py +227 -0
  27. nautobot/core/constants.py +3 -0
  28. nautobot/core/context_processors.py +9 -1
  29. nautobot/core/filters.py +4 -0
  30. nautobot/core/forms/__init__.py +2 -0
  31. nautobot/core/forms/forms.py +1 -1
  32. nautobot/core/forms/widgets.py +21 -2
  33. nautobot/core/jobs/__init__.py +62 -3
  34. nautobot/core/jobs/groups.py +31 -1
  35. nautobot/core/management/commands/generate_test_data.py +28 -9
  36. nautobot/core/models/__init__.py +11 -0
  37. nautobot/core/models/generics.py +9 -1
  38. nautobot/core/models/tree_queries.py +10 -5
  39. nautobot/core/models/utils.py +1 -1
  40. nautobot/core/settings.py +35 -19
  41. nautobot/core/settings.yaml +17 -33
  42. nautobot/core/signals.py +12 -1
  43. nautobot/core/tables.py +13 -6
  44. nautobot/core/templates/40x.html +1 -1
  45. nautobot/core/templates/500.html +2 -2
  46. nautobot/core/templates/admin/base.html +1 -2
  47. nautobot/core/templates/admin/change_list.html +9 -12
  48. nautobot/core/templates/admin/config/config.html +12 -12
  49. nautobot/core/templates/admin/index.html +3 -3
  50. nautobot/core/templates/base_django.html +1 -2
  51. nautobot/core/templates/buttons/export.html +1 -1
  52. nautobot/core/templates/components/button/dropdown.html +5 -3
  53. nautobot/core/templates/components/panel/body_wrapper_generic_table.html +1 -1
  54. nautobot/core/templates/components/panel/header_extra_content_table.html +1 -1
  55. nautobot/core/templates/components/panel/panel.html +3 -3
  56. nautobot/core/templates/components/tab/content_wrapper.html +6 -7
  57. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +1 -1
  58. nautobot/core/templates/echarts/echarts.html +22 -9
  59. nautobot/core/templates/generic/object_bulk_add_component.html +2 -1
  60. nautobot/core/templates/generic/object_bulk_create.html +6 -5
  61. nautobot/core/templates/generic/object_bulk_delete.html +1 -1
  62. nautobot/core/templates/generic/object_bulk_destroy.html +3 -3
  63. nautobot/core/templates/generic/object_bulk_edit.html +1 -1
  64. nautobot/core/templates/generic/object_bulk_import.html +1 -1
  65. nautobot/core/templates/generic/object_bulk_remove.html +2 -2
  66. nautobot/core/templates/generic/object_bulk_update.html +5 -4
  67. nautobot/core/templates/generic/object_create.html +5 -4
  68. nautobot/core/templates/generic/object_delete.html +1 -1
  69. nautobot/core/templates/generic/object_detail.html +1 -1
  70. nautobot/core/templates/generic/object_edit.html +1 -1
  71. nautobot/core/templates/generic/object_import.html +2 -1
  72. nautobot/core/templates/generic/object_list.html +12 -4
  73. nautobot/core/templates/generic/object_notes.html +5 -3
  74. nautobot/core/templates/generic/object_retrieve.html +4 -5
  75. nautobot/core/templates/graphene/graphiql.html +7 -8
  76. nautobot/core/templates/home.html +1 -1
  77. nautobot/core/templates/import_success.html +2 -1
  78. nautobot/core/templates/inc/computed_fields/panel_data.html +1 -1
  79. nautobot/core/templates/inc/created_updated.html +7 -3
  80. nautobot/core/templates/inc/custom_fields/panel_data.html +1 -1
  81. nautobot/core/templates/inc/footer.html +3 -1
  82. nautobot/core/templates/inc/form_static_field.html +6 -0
  83. nautobot/core/templates/inc/header.html +11 -1
  84. nautobot/core/templates/inc/image_attachments.html +2 -1
  85. nautobot/core/templates/inc/media.html +14 -0
  86. nautobot/core/templates/inc/nav_menu.html +3 -9
  87. nautobot/core/templates/inc/object_details_advanced_panel.html +2 -2
  88. nautobot/core/templates/inc/search_panel.html +4 -4
  89. nautobot/core/templates/login.html +4 -2
  90. nautobot/core/templates/nautobot_config.py.j2 +6 -11
  91. nautobot/core/templates/redoc_ui.html +7 -0
  92. nautobot/core/templates/rest_framework/api.html +103 -2
  93. nautobot/core/templates/search.html +1 -1
  94. nautobot/core/templates/swagger_ui.html +17 -3
  95. nautobot/core/templates/system_jobs/import_objects.html +1 -2
  96. nautobot/core/templates/utilities/confirmation_form.html +2 -2
  97. nautobot/core/templates/utilities/obj_table.html +10 -2
  98. nautobot/core/templates/utilities/render_field.html +7 -7
  99. nautobot/core/templates/utilities/render_jinja2.html +2 -2
  100. nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +37 -4
  101. nautobot/core/templates/utilities/theme_preview.html +19 -3
  102. nautobot/core/templates/widgets/number_input_with_choices.html +44 -0
  103. nautobot/core/templates/widgets/selectwithdisabled_option.html +3 -1
  104. nautobot/core/templatetags/helpers.py +76 -18
  105. nautobot/core/testing/api.py +68 -9
  106. nautobot/core/testing/filters.py +0 -23
  107. nautobot/core/testing/integration.py +41 -17
  108. nautobot/core/testing/mixins.py +2 -0
  109. nautobot/core/testing/utils.py +18 -4
  110. nautobot/core/testing/views.py +104 -13
  111. nautobot/core/tests/integration/test_app_home.py +34 -30
  112. nautobot/core/tests/integration/test_app_navbar.py +3 -0
  113. nautobot/core/tests/integration/test_filters.py +48 -11
  114. nautobot/core/tests/integration/test_theme.py +22 -21
  115. nautobot/core/tests/nautobot_config.py +3 -0
  116. nautobot/core/tests/nautobot_config_without_example_apps.py +4 -0
  117. nautobot/core/tests/runner.py +8 -1
  118. nautobot/core/tests/test_api.py +5 -3
  119. nautobot/core/tests/test_breadcrumbs.py +27 -28
  120. nautobot/core/tests/test_checks.py +28 -0
  121. nautobot/core/tests/test_cli.py +40 -0
  122. nautobot/core/tests/test_config.py +2 -1
  123. nautobot/core/tests/test_forms.py +55 -13
  124. nautobot/core/tests/test_jobs.py +144 -3
  125. nautobot/core/tests/test_nautobot_server.py +2 -0
  126. nautobot/core/tests/test_navigations.py +76 -1
  127. nautobot/core/tests/test_patch_social_django.py +42 -0
  128. nautobot/core/tests/test_renderers.py +59 -0
  129. nautobot/core/tests/test_settings_schema.py +1 -0
  130. nautobot/core/tests/test_tables.py +3 -1
  131. nautobot/core/tests/test_templatetags_helpers.py +62 -13
  132. nautobot/core/tests/test_templatetags_ui_framework.py +4 -4
  133. nautobot/core/tests/test_titles.py +0 -16
  134. nautobot/core/tests/test_tree_queries.py +14 -1
  135. nautobot/core/tests/test_ui.py +123 -4
  136. nautobot/core/tests/test_utils.py +72 -5
  137. nautobot/core/tests/test_views.py +159 -31
  138. nautobot/core/ui/breadcrumbs.py +70 -29
  139. nautobot/core/ui/bulk_buttons.py +1 -1
  140. nautobot/core/ui/choices.py +143 -27
  141. nautobot/core/ui/constants.py +76 -12
  142. nautobot/core/ui/echarts.py +15 -20
  143. nautobot/core/ui/object_detail.py +143 -55
  144. nautobot/core/ui/titles.py +3 -6
  145. nautobot/core/urls.py +20 -9
  146. nautobot/core/utils/cache.py +2 -1
  147. nautobot/core/utils/filtering.py +28 -18
  148. nautobot/core/utils/lookup.py +49 -8
  149. nautobot/core/utils/module_loading.py +21 -0
  150. nautobot/core/utils/patch_social_django.py +128 -0
  151. nautobot/core/views/__init__.py +38 -1
  152. nautobot/core/views/generic.py +3 -3
  153. nautobot/core/views/mixins.py +45 -22
  154. nautobot/core/views/renderers.py +4 -3
  155. nautobot/core/views/viewsets.py +2 -1
  156. nautobot/data_validation/apps.py +1 -5
  157. nautobot/data_validation/custom_validators.py +4 -4
  158. nautobot/data_validation/filters.py +1 -1
  159. nautobot/data_validation/forms.py +40 -0
  160. nautobot/data_validation/migrations/0001_initial.py +0 -7
  161. nautobot/data_validation/migrations/0002_data_migration_from_app.py +3 -14
  162. nautobot/data_validation/models.py +16 -7
  163. nautobot/data_validation/navigation.py +8 -1
  164. nautobot/data_validation/tables.py +12 -5
  165. nautobot/data_validation/templates/data_validation/datacompliance_tab.html +1 -0
  166. nautobot/data_validation/templates/data_validation/device_constraints.html +61 -0
  167. nautobot/data_validation/tests/__init__.py +2 -2
  168. nautobot/data_validation/tests/migrations/test_migrations.py +83 -3
  169. nautobot/data_validation/tests/test_data_compliance_rules.py +12 -7
  170. nautobot/data_validation/tests/test_filters.py +8 -6
  171. nautobot/data_validation/tests/test_models.py +15 -0
  172. nautobot/data_validation/tests/test_views.py +190 -32
  173. nautobot/data_validation/urls.py +2 -5
  174. nautobot/data_validation/views.py +73 -40
  175. nautobot/dcim/api/serializers.py +3 -13
  176. nautobot/dcim/apps.py +4 -0
  177. nautobot/dcim/choices.py +65 -0
  178. nautobot/dcim/constants.py +7 -0
  179. nautobot/dcim/custom_validators.py +84 -0
  180. nautobot/dcim/factory.py +1 -1
  181. nautobot/dcim/filter_mixins.py +353 -4
  182. nautobot/dcim/{filters/__init__.py → filters.py} +15 -36
  183. nautobot/dcim/forms.py +90 -4
  184. nautobot/dcim/migrations/0075_interface_duplex_interface_speed_and_more.py +32 -0
  185. nautobot/dcim/migrations/{0075_add_deviceclusterassignment.py → 0076_add_deviceclusterassignment.py} +1 -1
  186. nautobot/dcim/migrations/{0076_device_cluster_to_clusters_data_migration.py → 0077_device_cluster_to_clusters_data_migration.py} +1 -1
  187. nautobot/dcim/migrations/{0077_remove_device_cluster.py → 0078_remove_device_cluster.py} +1 -1
  188. nautobot/dcim/migrations/0079_remove_device_location_tenant_name_uniqueness.py +16 -0
  189. nautobot/dcim/migrations/0080_device_name_data_migration.py +59 -0
  190. nautobot/dcim/migrations/0081_alter_device_device_redundancy_group_priority_and_more.py +25 -0
  191. nautobot/dcim/models/device_component_templates.py +33 -1
  192. nautobot/dcim/models/device_components.py +98 -64
  193. nautobot/dcim/models/devices.py +30 -20
  194. nautobot/dcim/navigation.py +7 -6
  195. nautobot/dcim/tables/devices.py +18 -0
  196. nautobot/dcim/tables/devicetypes.py +8 -1
  197. nautobot/dcim/tables/racks.py +0 -2
  198. nautobot/dcim/tables/template_code.py +15 -15
  199. nautobot/dcim/templates/dcim/cable_connect.html +28 -112
  200. nautobot/dcim/templates/dcim/cable_trace.html +0 -4
  201. nautobot/dcim/templates/dcim/{cable_edit.html → cable_update.html} +1 -1
  202. nautobot/dcim/templates/dcim/consoleport.html +7 -6
  203. nautobot/dcim/templates/dcim/consoleserverport.html +7 -6
  204. nautobot/dcim/templates/dcim/device/config.html +2 -2
  205. nautobot/dcim/templates/dcim/device/lldp_neighbors.html +1 -1
  206. nautobot/dcim/templates/dcim/device/status.html +8 -8
  207. nautobot/dcim/templates/dcim/device.html +1 -1
  208. nautobot/dcim/templates/dcim/device_component_add.html +2 -2
  209. nautobot/dcim/templates/dcim/device_create.html +5 -3
  210. nautobot/dcim/templates/dcim/device_interface_delete.html +1 -1
  211. nautobot/dcim/templates/dcim/device_list.html +73 -10
  212. nautobot/dcim/templates/dcim/devicebay.html +1 -1
  213. nautobot/dcim/templates/dcim/devicebay_populate.html +2 -2
  214. nautobot/dcim/templates/dcim/devicetype_component_add.html +2 -2
  215. nautobot/dcim/templates/dcim/footer_convert_to_contact_or_team_record.html +14 -0
  216. nautobot/dcim/templates/dcim/frontport.html +10 -9
  217. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  218. nautobot/dcim/templates/dcim/inc/edit_form_softwareversion_js.html +2 -2
  219. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +1 -1
  220. nautobot/dcim/templates/dcim/inc/rack_elevation.html +1 -1
  221. nautobot/dcim/templates/dcim/interface.html +35 -7
  222. nautobot/dcim/templates/dcim/interface_bulk_delete.html +1 -1
  223. nautobot/dcim/templates/dcim/interface_edit.html +2 -0
  224. nautobot/dcim/templates/dcim/inventoryitem.html +1 -1
  225. nautobot/dcim/templates/dcim/inventoryitem_add.html +3 -1
  226. nautobot/dcim/templates/dcim/inventoryitem_bulk_delete.html +1 -1
  227. nautobot/dcim/templates/dcim/inventoryitem_edit.html +3 -1
  228. nautobot/dcim/templates/dcim/module/base.html +49 -9
  229. nautobot/dcim/templates/dcim/module_consoleports.html +1 -1
  230. nautobot/dcim/templates/dcim/module_consoleserverports.html +1 -1
  231. nautobot/dcim/templates/dcim/module_frontports.html +1 -1
  232. nautobot/dcim/templates/dcim/module_interfaces.html +1 -1
  233. nautobot/dcim/templates/dcim/module_list.html +57 -8
  234. nautobot/dcim/templates/dcim/module_modulebays.html +1 -1
  235. nautobot/dcim/templates/dcim/module_poweroutlets.html +1 -1
  236. nautobot/dcim/templates/dcim/module_powerports.html +1 -1
  237. nautobot/dcim/templates/dcim/module_rearports.html +1 -1
  238. nautobot/dcim/templates/dcim/modulefamily_retrieve.html +1 -1
  239. nautobot/dcim/templates/dcim/moduletype_list.html +2 -2
  240. nautobot/dcim/templates/dcim/moduletype_retrieve.html +49 -9
  241. nautobot/dcim/templates/dcim/platform_create.html +1 -1
  242. nautobot/dcim/templates/dcim/poweroutlet.html +1 -1
  243. nautobot/dcim/templates/dcim/powerport.html +6 -5
  244. nautobot/dcim/templates/dcim/rack_elevation_list.html +17 -5
  245. nautobot/dcim/templates/dcim/rack_retrieve.html +22 -15
  246. nautobot/dcim/templates/dcim/rearport.html +8 -7
  247. nautobot/dcim/templates/dcim/trace/cable.html +1 -1
  248. nautobot/dcim/templates/dcim/virtualchassis_add_member.html +16 -14
  249. nautobot/dcim/templates/dcim/virtualchassis_update.html +15 -7
  250. nautobot/dcim/tests/integration/test_controller.py +4 -6
  251. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +1 -5
  252. nautobot/dcim/tests/integration/test_create_device.py +0 -2
  253. nautobot/dcim/tests/integration/test_device_bulk_operations.py +1 -3
  254. nautobot/dcim/tests/integration/test_fileinputpicker.py +6 -10
  255. nautobot/dcim/tests/integration/test_location_bulk_operations.py +0 -2
  256. nautobot/dcim/tests/integration/test_module_bay_position.py +3 -4
  257. nautobot/dcim/tests/test_api.py +194 -6
  258. nautobot/dcim/tests/test_custom_validators.py +229 -0
  259. nautobot/dcim/tests/test_filters.py +55 -7
  260. nautobot/dcim/tests/test_forms.py +110 -8
  261. nautobot/dcim/tests/test_graphql.py +44 -1
  262. nautobot/dcim/tests/test_models.py +328 -4
  263. nautobot/dcim/tests/test_tables.py +160 -0
  264. nautobot/dcim/tests/test_views.py +132 -29
  265. nautobot/dcim/urls.py +64 -21
  266. nautobot/dcim/utils.py +3 -3
  267. nautobot/dcim/views.py +777 -397
  268. nautobot/extras/api/views.py +60 -45
  269. nautobot/extras/choices.py +2 -13
  270. nautobot/extras/datasources/git.py +3 -1
  271. nautobot/extras/{filters/mixins.py → filter_mixins.py} +1 -1
  272. nautobot/extras/{filters/customfields.py → filter_mixins_customfields.py} +42 -6
  273. nautobot/extras/{filters/__init__.py → filters.py} +33 -48
  274. nautobot/extras/forms/forms.py +14 -15
  275. nautobot/extras/forms/mixins.py +0 -41
  276. nautobot/extras/jobs.py +2 -0
  277. nautobot/extras/jobs_ui.py +4 -3
  278. nautobot/extras/management/__init__.py +11 -0
  279. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +4 -1
  280. nautobot/extras/migrations/0127_approval_workflow_models.py +6 -6
  281. nautobot/extras/migrations/0129_jobresult_debug_log_count_jobresult_error_log_count_and_more.py +37 -0
  282. nautobot/extras/migrations/0130_jobresult_generate_log_entry_counts.py +42 -0
  283. nautobot/extras/migrations/0131_configcontext_device_families.py +18 -0
  284. nautobot/extras/models/__init__.py +1 -2
  285. nautobot/extras/models/approvals.py +33 -14
  286. nautobot/extras/models/change_logging.py +4 -0
  287. nautobot/extras/models/contacts.py +2 -0
  288. nautobot/extras/models/groups.py +44 -5
  289. nautobot/extras/models/jobs.py +60 -4
  290. nautobot/extras/models/mixins.py +28 -0
  291. nautobot/extras/models/models.py +23 -2
  292. nautobot/extras/models/secrets.py +1 -0
  293. nautobot/extras/models/statuses.py +0 -15
  294. nautobot/extras/navigation.py +13 -9
  295. nautobot/extras/plugins/__init__.py +33 -55
  296. nautobot/extras/plugins/marketplace_manifest.yml +49 -1
  297. nautobot/extras/plugins/tables.py +3 -3
  298. nautobot/extras/plugins/urls.py +2 -21
  299. nautobot/extras/plugins/utils.py +1 -33
  300. nautobot/extras/plugins/views.py +0 -9
  301. nautobot/extras/querysets.py +8 -0
  302. nautobot/extras/signals.py +20 -19
  303. nautobot/extras/tables.py +64 -68
  304. nautobot/extras/templates/django_ajax_tables/ajax_wrapper.html +2 -0
  305. nautobot/extras/templates/extras/approval_dashboard.html +7 -5
  306. nautobot/extras/templates/extras/approvalworkflowdefinition_update.html +4 -2
  307. nautobot/extras/templates/extras/approvalworkflowstage_retrieve.html +20 -12
  308. nautobot/extras/templates/extras/configcontext_update.html +1 -0
  309. nautobot/extras/templates/extras/configcontextschema_validation.html +2 -2
  310. nautobot/extras/templates/extras/dynamicgroup_retrieve.html +11 -5
  311. nautobot/extras/templates/extras/dynamicgroup_update.html +1 -1
  312. nautobot/extras/templates/extras/gitrepository_result.html +0 -2
  313. nautobot/extras/templates/extras/inc/approval_buttons_column.html +20 -6
  314. nautobot/extras/templates/extras/inc/bulk_edit_overridable_field.html +8 -7
  315. nautobot/extras/templates/extras/inc/configcontext_format.html +10 -3
  316. nautobot/extras/templates/extras/inc/graphqlquery_execute.html +71 -0
  317. nautobot/extras/templates/extras/inc/job_tiles.html +15 -3
  318. nautobot/extras/templates/extras/inc/json_format.html +10 -3
  319. nautobot/extras/templates/extras/inc/overridable_field.html +13 -12
  320. nautobot/extras/templates/extras/job.html +29 -12
  321. nautobot/extras/templates/extras/job_bulk_edit.html +18 -0
  322. nautobot/extras/templates/extras/job_edit.html +52 -46
  323. nautobot/extras/templates/extras/job_list.html +29 -25
  324. nautobot/extras/templates/extras/marketplace.html +5 -9
  325. nautobot/extras/templates/extras/object_configcontext.html +1 -1
  326. nautobot/extras/templates/extras/object_dynamicgroups.html +2 -2
  327. nautobot/extras/templates/extras/objectchange_retrieve.html +19 -39
  328. nautobot/extras/templates/extras/plugin_detail.html +29 -24
  329. nautobot/extras/templates/extras/plugins_list.html +16 -26
  330. nautobot/extras/templates/extras/role_retrieve.html +64 -0
  331. nautobot/extras/templates/extras/scheduledjob.html +4 -2
  332. nautobot/extras/templates/extras/secret_create.html +1 -1
  333. nautobot/extras/templatetags/custom_links.py +12 -12
  334. nautobot/extras/templatetags/job_buttons.py +14 -12
  335. nautobot/extras/test_jobs/invalid_import.py +9 -0
  336. nautobot/extras/test_jobs/log_counts_by_level.py +23 -0
  337. nautobot/extras/test_jobs/missing_import.py +11 -0
  338. nautobot/extras/tests/integration/test_computedfields.py +8 -9
  339. nautobot/extras/tests/integration/test_configcontextschema.py +27 -26
  340. nautobot/extras/tests/integration/test_customfields.py +9 -10
  341. nautobot/extras/tests/integration/test_dynamicgroups.py +12 -9
  342. nautobot/extras/tests/integration/test_plugin_banner.py +3 -0
  343. nautobot/extras/tests/integration/test_plugins.py +18 -6
  344. nautobot/extras/tests/integration/test_relationships.py +0 -2
  345. nautobot/extras/tests/test_api.py +90 -18
  346. nautobot/extras/tests/test_approvals.py +38 -38
  347. nautobot/extras/tests/test_changelog.py +59 -5
  348. nautobot/extras/tests/test_customfields.py +22 -13
  349. nautobot/extras/tests/test_customfields_filters.py +479 -0
  350. nautobot/extras/tests/test_dynamicgroups.py +39 -1
  351. nautobot/extras/tests/test_filters.py +57 -22
  352. nautobot/extras/tests/test_forms.py +18 -21
  353. nautobot/extras/tests/test_jobs.py +25 -4
  354. nautobot/extras/tests/test_migrations.py +1 -0
  355. nautobot/extras/tests/test_models.py +51 -33
  356. nautobot/extras/tests/test_plugins.py +36 -10
  357. nautobot/extras/tests/test_utils.py +3 -4
  358. nautobot/extras/tests/test_views.py +52 -112
  359. nautobot/extras/urls.py +0 -14
  360. nautobot/extras/views.py +164 -71
  361. nautobot/ipam/factory.py +7 -0
  362. nautobot/ipam/filter_mixins.py +38 -0
  363. nautobot/ipam/filters.py +53 -38
  364. nautobot/ipam/formfields.py +1 -1
  365. nautobot/ipam/forms.py +6 -3
  366. nautobot/ipam/migrations/0030_ipam__namespaces.py +13 -0
  367. nautobot/ipam/migrations/0031_ipam___data_migrations.py +4 -1
  368. nautobot/ipam/migrations/0054_namespace_tenant.py +25 -0
  369. nautobot/ipam/models.py +29 -2
  370. nautobot/ipam/navigation.py +3 -2
  371. nautobot/ipam/signals.py +71 -0
  372. nautobot/ipam/tables.py +19 -6
  373. nautobot/ipam/templates/ipam/inc/toggle_available.html +10 -10
  374. nautobot/ipam/templates/ipam/inc/vlangroup_header.html +1 -0
  375. nautobot/ipam/templates/ipam/ipaddress.html +14 -0
  376. nautobot/ipam/templates/ipam/ipaddress_merge.html +3 -3
  377. nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +1 -0
  378. nautobot/ipam/templates/ipam/namespace_ip_addresses.html +1 -1
  379. nautobot/ipam/templates/ipam/namespace_prefixes.html +1 -1
  380. nautobot/ipam/templates/ipam/namespace_update.html +15 -0
  381. nautobot/ipam/templates/ipam/namespace_vrfs.html +1 -1
  382. nautobot/ipam/templates/ipam/prefix_delete.html +1 -1
  383. nautobot/ipam/templates/ipam/prefix_list.html +14 -13
  384. nautobot/ipam/templates/ipam/vlan_interfaces.html +1 -1
  385. nautobot/ipam/templates/ipam/vlan_vminterfaces.html +1 -1
  386. nautobot/ipam/tests/migration/test_migrations.py +89 -0
  387. nautobot/ipam/tests/test_api.py +13 -6
  388. nautobot/ipam/tests/test_filters.py +36 -1
  389. nautobot/ipam/tests/test_forms.py +1 -1
  390. nautobot/ipam/tests/test_models.py +44 -2
  391. nautobot/ipam/tests/test_tables.py +1 -2
  392. nautobot/ipam/tests/test_utils.py +1 -1
  393. nautobot/ipam/tests/test_views.py +13 -14
  394. nautobot/ipam/ui.py +0 -17
  395. nautobot/ipam/utils/migrations.py +16 -2
  396. nautobot/ipam/utils/testing.py +9 -3
  397. nautobot/ipam/views.py +53 -11
  398. nautobot/load_balancers/__init__.py +0 -0
  399. nautobot/load_balancers/api/__init__.py +1 -0
  400. nautobot/load_balancers/api/serializers.py +75 -0
  401. nautobot/load_balancers/api/urls.py +23 -0
  402. nautobot/load_balancers/api/views.py +61 -0
  403. nautobot/load_balancers/apps.py +17 -0
  404. nautobot/load_balancers/choices.py +167 -0
  405. nautobot/load_balancers/filters.py +225 -0
  406. nautobot/load_balancers/forms.py +532 -0
  407. nautobot/load_balancers/management/commands/__init__.py +0 -0
  408. nautobot/load_balancers/management/commands/generate_load_balancer_models_test_data.py +38 -0
  409. nautobot/load_balancers/migrations/0001_initial.py +465 -0
  410. nautobot/load_balancers/migrations/0002_create_default_statuses_pool_members.py +31 -0
  411. nautobot/load_balancers/migrations/__init__.py +0 -0
  412. nautobot/load_balancers/models.py +423 -0
  413. nautobot/load_balancers/navigation.py +80 -0
  414. nautobot/load_balancers/tables.py +255 -0
  415. nautobot/load_balancers/tests/__init__.py +474 -0
  416. nautobot/load_balancers/tests/test_api.py +353 -0
  417. nautobot/load_balancers/tests/test_filters.py +134 -0
  418. nautobot/load_balancers/tests/test_forms.py +266 -0
  419. nautobot/load_balancers/tests/test_models.py +195 -0
  420. nautobot/load_balancers/tests/test_views.py +229 -0
  421. nautobot/load_balancers/urls.py +17 -0
  422. nautobot/load_balancers/views.py +248 -0
  423. nautobot/project-static/dist/css/github-dark.min.css +10 -0
  424. nautobot/project-static/dist/css/github.min.css +10 -0
  425. nautobot/project-static/dist/css/nautobot.css +1 -11
  426. nautobot/project-static/dist/css/nautobot.css.map +1 -1
  427. nautobot/project-static/dist/js/libraries.js +1 -1
  428. nautobot/project-static/dist/js/libraries.js.map +1 -1
  429. nautobot/project-static/dist/js/nautobot.js +1 -1
  430. nautobot/project-static/dist/js/nautobot.js.map +1 -1
  431. nautobot/project-static/js/cabletrace.js +1 -1
  432. nautobot/project-static/js/forms.js +13 -0
  433. nautobot/project-static/js/interface_filtering.js +20 -16
  434. nautobot/project-static/nautobot-icons/battery-3.svg +3 -0
  435. nautobot/project-static/nautobot-icons/bus-globe.svg +3 -0
  436. nautobot/project-static/nautobot-icons/bus-shield-check.svg +3 -0
  437. nautobot/project-static/nautobot-icons/bus-shield.svg +3 -0
  438. nautobot/project-static/nautobot-icons/cloud.svg +1 -1
  439. nautobot/project-static/nautobot-icons/control-panel.svg +1 -1
  440. nautobot/project-static/nautobot-icons/device-lifecycle.svg +1 -1
  441. nautobot/project-static/nautobot-icons/elements.svg +1 -1
  442. nautobot/project-static/nautobot-icons/extensibility.svg +3 -0
  443. nautobot/project-static/nautobot-icons/hammer.svg +1 -1
  444. nautobot/project-static/nautobot-icons/organization.svg +3 -0
  445. nautobot/project-static/nautobot-icons/secrets.svg +1 -1
  446. nautobot/project-static/nautobot-icons/security.svg +3 -0
  447. nautobot/project-static/nautobot-icons/server.svg +1 -1
  448. nautobot/project-static/nautobot-icons/star-filled.svg +1 -1
  449. nautobot/project-static/nautobot-icons/star.svg +1 -1
  450. nautobot/tenancy/api/serializers.py +1 -0
  451. nautobot/tenancy/api/views.py +2 -1
  452. nautobot/tenancy/{filters/__init__.py → filters.py} +2 -10
  453. nautobot/tenancy/navigation.py +3 -1
  454. nautobot/tenancy/tests/test_filters.py +0 -2
  455. nautobot/tenancy/views.py +2 -1
  456. nautobot/ui/package-lock.json +87 -4
  457. nautobot/ui/package.json +2 -1
  458. nautobot/ui/src/js/collapse.js +3 -3
  459. nautobot/ui/src/js/nautobot.js +16 -1
  460. nautobot/ui/src/js/select2.js +53 -2
  461. nautobot/ui/src/scss/colors.scss +1 -1
  462. nautobot/ui/src/scss/nautobot.scss +112 -30
  463. nautobot/ui/webpack.config.js +13 -0
  464. nautobot/users/templates/users/preferences.html +11 -2
  465. nautobot/users/templates/users/profile.html +45 -12
  466. nautobot/users/templates/users/sessionkey_delete.html +1 -1
  467. nautobot/users/tests/test_api.py +4 -0
  468. nautobot/users/views.py +4 -2
  469. nautobot/virtualization/filters.py +6 -1
  470. nautobot/virtualization/models.py +1 -68
  471. nautobot/virtualization/navigation.py +3 -2
  472. nautobot/virtualization/templates/virtualization/virtual_machine_vminterface_delete.html +1 -1
  473. nautobot/virtualization/templates/virtualization/virtualmachine_list.html +2 -2
  474. nautobot/virtualization/templates/virtualization/virtualmachine_update.html +3 -1
  475. nautobot/virtualization/tests/test_api.py +3 -0
  476. nautobot/virtualization/tests/test_filters.py +10 -1
  477. nautobot/virtualization/tests/test_models.py +45 -4
  478. nautobot/virtualization/views.py +4 -1
  479. nautobot/vpn/__init__.py +0 -0
  480. nautobot/vpn/api/serializers.py +113 -0
  481. nautobot/vpn/api/urls.py +19 -0
  482. nautobot/vpn/api/views.py +70 -0
  483. nautobot/vpn/apps.py +8 -0
  484. nautobot/vpn/choices.py +171 -0
  485. nautobot/vpn/factory.py +219 -0
  486. nautobot/vpn/filters.py +234 -0
  487. nautobot/vpn/forms.py +487 -0
  488. nautobot/vpn/homepage.py +19 -0
  489. nautobot/vpn/migrations/0001_initial.py +541 -0
  490. nautobot/vpn/migrations/0002_populate_defaults.py +199 -0
  491. nautobot/vpn/migrations/__init__.py +0 -0
  492. nautobot/vpn/models.py +535 -0
  493. nautobot/vpn/navigation.py +98 -0
  494. nautobot/vpn/tables.py +383 -0
  495. nautobot/vpn/templates/vpn/vpnprofile_create.html +150 -0
  496. nautobot/vpn/tests/__init__.py +0 -0
  497. nautobot/vpn/tests/test_api.py +336 -0
  498. nautobot/vpn/tests/test_filters.py +139 -0
  499. nautobot/vpn/tests/test_forms.py +293 -0
  500. nautobot/vpn/tests/test_models.py +147 -0
  501. nautobot/vpn/tests/test_views.py +300 -0
  502. nautobot/vpn/urls.py +16 -0
  503. nautobot/vpn/views.py +495 -0
  504. nautobot/wireless/navigation.py +3 -2
  505. nautobot/wireless/tests/integration/test_radio_profile.py +1 -5
  506. nautobot/wireless/tests/test_api.py +1 -1
  507. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/METADATA +15 -15
  508. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/RECORD +514 -572
  509. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/entry_points.txt +1 -0
  510. nautobot/circuits/templates/circuits/circuit.html +0 -2
  511. nautobot/circuits/templates/circuits/circuit_edit.html +0 -2
  512. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -2
  513. nautobot/circuits/templates/circuits/circuit_update.html +0 -1
  514. nautobot/circuits/templates/circuits/circuittermination.html +0 -2
  515. nautobot/circuits/templates/circuits/circuittermination_edit.html +0 -2
  516. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +0 -2
  517. nautobot/circuits/templates/circuits/circuittermination_update.html +0 -1
  518. nautobot/circuits/templates/circuits/circuittype.html +0 -2
  519. nautobot/circuits/templates/circuits/circuittype_retrieve.html +0 -2
  520. nautobot/circuits/templates/circuits/inc/circuit_termination.html +0 -85
  521. nautobot/circuits/templates/circuits/provider.html +0 -2
  522. nautobot/circuits/templates/circuits/provider_edit.html +0 -2
  523. nautobot/circuits/templates/circuits/provider_retrieve.html +0 -1
  524. nautobot/circuits/templates/circuits/provider_update.html +0 -1
  525. nautobot/circuits/templates/circuits/providernetwork.html +0 -2
  526. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
  527. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +0 -2
  528. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +0 -2
  529. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +0 -2
  530. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +0 -2
  531. nautobot/core/templates/buttons/import.html +0 -9
  532. nautobot/data_validation/template_content.py +0 -42
  533. nautobot/data_validation/templates/data_validation/datacompliance_retrieve.html +0 -1
  534. nautobot/dcim/filters/mixins.py +0 -354
  535. nautobot/dcim/templates/dcim/controller/base.html +0 -2
  536. nautobot/dcim/templates/dcim/controller_retrieve.html +0 -2
  537. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +0 -2
  538. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +0 -2
  539. nautobot/dcim/templates/dcim/device/base.html +0 -2
  540. nautobot/dcim/templates/dcim/device/consoleports.html +0 -2
  541. nautobot/dcim/templates/dcim/device/consoleserverports.html +0 -2
  542. nautobot/dcim/templates/dcim/device/devicebays.html +0 -2
  543. nautobot/dcim/templates/dcim/device/frontports.html +0 -2
  544. nautobot/dcim/templates/dcim/device/interfaces.html +0 -2
  545. nautobot/dcim/templates/dcim/device/inventory.html +0 -2
  546. nautobot/dcim/templates/dcim/device/modulebays.html +0 -2
  547. nautobot/dcim/templates/dcim/device/poweroutlets.html +0 -2
  548. nautobot/dcim/templates/dcim/device/powerports.html +0 -2
  549. nautobot/dcim/templates/dcim/device/rearports.html +0 -2
  550. nautobot/dcim/templates/dcim/device/wireless.html +0 -2
  551. nautobot/dcim/templates/dcim/device_component.html +0 -2
  552. nautobot/dcim/templates/dcim/device_edit.html +0 -2
  553. nautobot/dcim/templates/dcim/devicefamily_retrieve.html +0 -2
  554. nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +0 -2
  555. nautobot/dcim/templates/dcim/devicetype.html +0 -2
  556. nautobot/dcim/templates/dcim/devicetype_edit.html +0 -2
  557. nautobot/dcim/templates/dcim/devicetype_retrieve.html +0 -2
  558. nautobot/dcim/templates/dcim/inc/device_napalm_tabs.html +0 -1
  559. nautobot/dcim/templates/dcim/interfaceredundancygroup_retrieve.html +0 -2
  560. nautobot/dcim/templates/dcim/location.html +0 -2
  561. nautobot/dcim/templates/dcim/location_edit.html +0 -2
  562. nautobot/dcim/templates/dcim/location_retrieve.html +0 -243
  563. nautobot/dcim/templates/dcim/locationtype.html +0 -2
  564. nautobot/dcim/templates/dcim/locationtype_retrieve.html +0 -2
  565. nautobot/dcim/templates/dcim/manufacturer.html +0 -2
  566. nautobot/dcim/templates/dcim/modulebay_retrieve.html +0 -1
  567. nautobot/dcim/templates/dcim/platform.html +0 -2
  568. nautobot/dcim/templates/dcim/powerfeed.html +0 -2
  569. nautobot/dcim/templates/dcim/powerfeed_retrieve.html +0 -2
  570. nautobot/dcim/templates/dcim/powerpanel.html +0 -2
  571. nautobot/dcim/templates/dcim/powerpanel_edit.html +0 -2
  572. nautobot/dcim/templates/dcim/powerpanel_retrieve.html +0 -2
  573. nautobot/dcim/templates/dcim/rack.html +0 -2
  574. nautobot/dcim/templates/dcim/rack_edit.html +0 -2
  575. nautobot/dcim/templates/dcim/rackgroup.html +0 -2
  576. nautobot/dcim/templates/dcim/rackreservation.html +0 -2
  577. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +0 -2
  578. nautobot/dcim/templates/dcim/softwareversion_retrieve.html +0 -2
  579. nautobot/dcim/templates/dcim/virtualchassis.html +0 -2
  580. nautobot/dcim/templates/dcim/virtualchassis_add.html +0 -2
  581. nautobot/dcim/templates/dcim/virtualchassis_edit.html +0 -2
  582. nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +0 -2
  583. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +0 -2
  584. nautobot/dcim/ui.py +0 -29
  585. nautobot/extras/templates/extras/computedfield.html +0 -2
  586. nautobot/extras/templates/extras/computedfield_retrieve.html +0 -2
  587. nautobot/extras/templates/extras/configcontext.html +0 -2
  588. nautobot/extras/templates/extras/configcontext_edit.html +0 -2
  589. nautobot/extras/templates/extras/configcontext_retrieve.html +0 -2
  590. nautobot/extras/templates/extras/configcontextschema.html +0 -2
  591. nautobot/extras/templates/extras/configcontextschema_edit.html +0 -2
  592. nautobot/extras/templates/extras/contact_retrieve.html +0 -2
  593. nautobot/extras/templates/extras/customfield.html +0 -2
  594. nautobot/extras/templates/extras/customfield_edit.html +0 -2
  595. nautobot/extras/templates/extras/customfield_retrieve.html +0 -2
  596. nautobot/extras/templates/extras/customlink.html +0 -2
  597. nautobot/extras/templates/extras/dynamicgroup.html +0 -2
  598. nautobot/extras/templates/extras/dynamicgroup_edit.html +0 -2
  599. nautobot/extras/templates/extras/exporttemplate.html +0 -2
  600. nautobot/extras/templates/extras/gitrepository.html +0 -2
  601. nautobot/extras/templates/extras/gitrepository_object_edit.html +0 -2
  602. nautobot/extras/templates/extras/graphqlquery.html +0 -2
  603. nautobot/extras/templates/extras/graphqlquery_list.html +0 -1
  604. nautobot/extras/templates/extras/graphqlquery_retrieve.html +0 -97
  605. nautobot/extras/templates/extras/job_detail.html +0 -2
  606. nautobot/extras/templates/extras/jobbutton_retrieve.html +0 -2
  607. nautobot/extras/templates/extras/jobhook.html +0 -2
  608. nautobot/extras/templates/extras/jobqueue_retrieve.html +0 -2
  609. nautobot/extras/templates/extras/jobresult.html +0 -2
  610. nautobot/extras/templates/extras/metadatatype_retrieve.html +0 -2
  611. nautobot/extras/templates/extras/note.html +0 -2
  612. nautobot/extras/templates/extras/note_retrieve.html +0 -1
  613. nautobot/extras/templates/extras/object_changelog.html +0 -2
  614. nautobot/extras/templates/extras/object_notes.html +0 -2
  615. nautobot/extras/templates/extras/objectchange.html +0 -2
  616. nautobot/extras/templates/extras/objectchange_list.html +0 -3
  617. nautobot/extras/templates/extras/relationship.html +0 -1
  618. nautobot/extras/templates/extras/secret.html +0 -1
  619. nautobot/extras/templates/extras/secret_edit.html +0 -1
  620. nautobot/extras/templates/extras/secretsgroup.html +0 -2
  621. nautobot/extras/templates/extras/secretsgroup_edit.html +0 -2
  622. nautobot/extras/templates/extras/secretsgroup_retrieve.html +0 -2
  623. nautobot/extras/templates/extras/status.html +0 -2
  624. nautobot/extras/templates/extras/tag.html +0 -2
  625. nautobot/extras/templates/extras/tag_edit.html +0 -2
  626. nautobot/extras/templates/extras/tag_retrieve.html +0 -2
  627. nautobot/extras/templates/extras/team_retrieve.html +0 -2
  628. nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +0 -4
  629. nautobot/ipam/templates/ipam/namespace_retrieve.html +0 -1
  630. nautobot/ipam/templates/ipam/prefix.html +0 -2
  631. nautobot/ipam/templates/ipam/prefix_edit.html +0 -1
  632. nautobot/ipam/templates/ipam/prefix_retrieve.html +0 -2
  633. nautobot/ipam/templates/ipam/rir.html +0 -2
  634. nautobot/ipam/templates/ipam/routetarget.html +0 -1
  635. nautobot/ipam/templates/ipam/service.html +0 -2
  636. nautobot/ipam/templates/ipam/service_edit.html +0 -2
  637. nautobot/ipam/templates/ipam/service_retrieve.html +0 -2
  638. nautobot/ipam/templates/ipam/vlan.html +0 -2
  639. nautobot/ipam/templates/ipam/vlan_edit.html +0 -2
  640. nautobot/ipam/templates/ipam/vlan_retrieve.html +0 -2
  641. nautobot/ipam/templates/ipam/vlangroup.html +0 -2
  642. nautobot/ipam/templates/ipam/vrf.html +0 -1
  643. nautobot/tenancy/templates/tenancy/tenant.html +0 -2
  644. nautobot/tenancy/templates/tenancy/tenant_edit.html +0 -2
  645. nautobot/tenancy/templates/tenancy/tenantgroup.html +0 -2
  646. nautobot/tenancy/templates/tenancy/tenantgroup_retrieve.html +0 -1
  647. nautobot/virtualization/templates/virtualization/clustergroup.html +0 -2
  648. nautobot/virtualization/templates/virtualization/clustertype.html +0 -2
  649. nautobot/virtualization/templates/virtualization/virtualmachine.html +0 -2
  650. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +0 -2
  651. nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +0 -2
  652. nautobot/wireless/templates/wireless/radioprofile_retrieve.html +0 -2
  653. nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +0 -2
  654. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +0 -2
  655. /nautobot/dcim/templates/dcim/{cable.html → cable_retrieve.html} +0 -0
  656. /nautobot/tenancy/{filters/mixins.py → filter_mixins.py} +0 -0
  657. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/LICENSE.txt +0 -0
  658. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/NOTICE +0 -0
  659. {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/WHEEL +0 -0
nautobot/tenancy/views.py CHANGED
@@ -12,7 +12,7 @@ from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
12
12
  from nautobot.core.views.viewsets import NautobotUIViewSet
13
13
  from nautobot.dcim.models import Controller, ControllerManagedDeviceGroup, Device, Location, Rack, RackReservation
14
14
  from nautobot.extras.models import DynamicGroup
15
- from nautobot.ipam.models import IPAddress, Prefix, VLAN, VRF
15
+ from nautobot.ipam.models import IPAddress, Namespace, Prefix, VLAN, VRF
16
16
  from nautobot.tenancy.api import serializers
17
17
  from nautobot.virtualization.models import Cluster, VirtualMachine
18
18
 
@@ -104,6 +104,7 @@ class TenantUIViewSet(NautobotUIViewSet):
104
104
  IPAddress,
105
105
  # TODO: Should we include child locations of the filtered locations in the location_count below?
106
106
  Location,
107
+ Namespace,
107
108
  Prefix,
108
109
  Rack,
109
110
  RackReservation,
@@ -17,7 +17,7 @@
17
17
  "graphiql": "2.4.7",
18
18
  "graphql": "16.10.0",
19
19
  "graphql-ws": "5.13.1",
20
- "highlight.js": "11.9.0",
20
+ "highlight.js": "^11.11.1",
21
21
  "htmx.org": "^2.0.6",
22
22
  "jquery": "^3.7.1",
23
23
  "jquery-ui": "^1.14.1",
@@ -32,6 +32,7 @@
32
32
  "devDependencies": {
33
33
  "@eslint/js": "^9.32.0",
34
34
  "autoprefixer": "^10.4.20",
35
+ "copy-webpack-plugin": "^13.0.1",
35
36
  "css-loader": "^7.1.2",
36
37
  "eslint": "^9.32.0",
37
38
  "eslint-plugin-import": "^2.32.0",
@@ -2055,6 +2056,30 @@
2055
2056
  "toggle-selection": "^1.0.6"
2056
2057
  }
2057
2058
  },
2059
+ "node_modules/copy-webpack-plugin": {
2060
+ "version": "13.0.1",
2061
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz",
2062
+ "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==",
2063
+ "dev": true,
2064
+ "license": "MIT",
2065
+ "dependencies": {
2066
+ "glob-parent": "^6.0.1",
2067
+ "normalize-path": "^3.0.0",
2068
+ "schema-utils": "^4.2.0",
2069
+ "serialize-javascript": "^6.0.2",
2070
+ "tinyglobby": "^0.2.12"
2071
+ },
2072
+ "engines": {
2073
+ "node": ">= 18.12.0"
2074
+ },
2075
+ "funding": {
2076
+ "type": "opencollective",
2077
+ "url": "https://opencollective.com/webpack"
2078
+ },
2079
+ "peerDependencies": {
2080
+ "webpack": "^5.1.0"
2081
+ }
2082
+ },
2058
2083
  "node_modules/cosmiconfig": {
2059
2084
  "version": "9.0.0",
2060
2085
  "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
@@ -3507,9 +3532,9 @@
3507
3532
  }
3508
3533
  },
3509
3534
  "node_modules/highlight.js": {
3510
- "version": "11.9.0",
3511
- "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz",
3512
- "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==",
3535
+ "version": "11.11.1",
3536
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
3537
+ "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
3513
3538
  "license": "BSD-3-Clause",
3514
3539
  "engines": {
3515
3540
  "node": ">=12.0.0"
@@ -4467,6 +4492,16 @@
4467
4492
  "dev": true,
4468
4493
  "license": "MIT"
4469
4494
  },
4495
+ "node_modules/normalize-path": {
4496
+ "version": "3.0.0",
4497
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
4498
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
4499
+ "dev": true,
4500
+ "license": "MIT",
4501
+ "engines": {
4502
+ "node": ">=0.10.0"
4503
+ }
4504
+ },
4470
4505
  "node_modules/normalize-range": {
4471
4506
  "version": "0.1.2",
4472
4507
  "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
@@ -6028,6 +6063,54 @@
6028
6063
  "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
6029
6064
  "license": "MIT"
6030
6065
  },
6066
+ "node_modules/tinyglobby": {
6067
+ "version": "0.2.15",
6068
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
6069
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
6070
+ "dev": true,
6071
+ "license": "MIT",
6072
+ "dependencies": {
6073
+ "fdir": "^6.5.0",
6074
+ "picomatch": "^4.0.3"
6075
+ },
6076
+ "engines": {
6077
+ "node": ">=12.0.0"
6078
+ },
6079
+ "funding": {
6080
+ "url": "https://github.com/sponsors/SuperchupuDev"
6081
+ }
6082
+ },
6083
+ "node_modules/tinyglobby/node_modules/fdir": {
6084
+ "version": "6.5.0",
6085
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
6086
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
6087
+ "dev": true,
6088
+ "license": "MIT",
6089
+ "engines": {
6090
+ "node": ">=12.0.0"
6091
+ },
6092
+ "peerDependencies": {
6093
+ "picomatch": "^3 || ^4"
6094
+ },
6095
+ "peerDependenciesMeta": {
6096
+ "picomatch": {
6097
+ "optional": true
6098
+ }
6099
+ }
6100
+ },
6101
+ "node_modules/tinyglobby/node_modules/picomatch": {
6102
+ "version": "4.0.3",
6103
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
6104
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
6105
+ "dev": true,
6106
+ "license": "MIT",
6107
+ "engines": {
6108
+ "node": ">=12"
6109
+ },
6110
+ "funding": {
6111
+ "url": "https://github.com/sponsors/jonschlinkert"
6112
+ }
6113
+ },
6031
6114
  "node_modules/to-regex-range": {
6032
6115
  "version": "5.0.1",
6033
6116
  "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
nautobot/ui/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "graphiql": "2.4.7",
24
24
  "graphql": "16.10.0",
25
25
  "graphql-ws": "5.13.1",
26
- "highlight.js": "11.9.0",
26
+ "highlight.js": "^11.11.1",
27
27
  "htmx.org": "^2.0.6",
28
28
  "jquery": "^3.7.1",
29
29
  "jquery-ui": "^1.14.1",
@@ -38,6 +38,7 @@
38
38
  "devDependencies": {
39
39
  "@eslint/js": "^9.32.0",
40
40
  "autoprefixer": "^10.4.20",
41
+ "copy-webpack-plugin": "^13.0.1",
41
42
  "css-loader": "^7.1.2",
42
43
  "eslint": "^9.32.0",
43
44
  "eslint-plugin-import": "^2.32.0",
@@ -5,7 +5,7 @@
5
5
  * ---
6
6
  * Critical difference between this and default Bootstrap 5 collapse implementation is that Bootstrap only supports
7
7
  * toggling individual panel states without an option to toggle them collectively. See an explanation below:
8
- * Bootstrap 5 on "Collapse All" button click: | Nautobot on "Collapse All" button click:
8
+ * Bootstrap 5 on "Collapse All Groups" button click: | Nautobot on "Collapse All Groups" button click:
9
9
  * * X [expanded] -> [collapsed] | * X [expanded] -> [collapsed]
10
10
  * * Y [collapsed] -> [expanded] | * Y [collapsed] -> [collapsed]
11
11
  * * Z [expanded] -> [collapsed] | * Z [expanded] -> [collapsed]
@@ -45,7 +45,7 @@ export const initializeCollapseToggleAll = () => {
45
45
  .filter((collapseToggleAll) => areAll(getCollapseToggleAllTargets(collapseToggleAll), 'collapsed'))
46
46
  .forEach((collapseToggleAll) => {
47
47
  collapseToggleAll.setAttribute('aria-expanded', 'false');
48
- collapseToggleAll.textContent = 'Expand All';
48
+ collapseToggleAll.textContent = 'Expand All Groups';
49
49
  });
50
50
 
51
51
  const onShownBsCollapse = () =>
@@ -53,7 +53,7 @@ export const initializeCollapseToggleAll = () => {
53
53
  .filter((collapseToggleAll) => areAll(getCollapseToggleAllTargets(collapseToggleAll), 'expanded'))
54
54
  .forEach((collapseToggleAll) => {
55
55
  collapseToggleAll.setAttribute('aria-expanded', 'true');
56
- collapseToggleAll.textContent = 'Collapse All';
56
+ collapseToggleAll.textContent = 'Collapse All Groups';
57
57
  });
58
58
 
59
59
  // Using event delegation pattern here to avoid re-creating listeners each time DOM is modified.
@@ -15,7 +15,6 @@ import flatpickr from 'flatpickr';
15
15
  window.flatpickr = flatpickr;
16
16
 
17
17
  import hljs from 'highlight.js/lib/core';
18
- import 'highlight.js/styles/github.css';
19
18
  import graphql from 'highlight.js/lib/languages/graphql';
20
19
  import json from 'highlight.js/lib/languages/json';
21
20
  import xml from 'highlight.js/lib/languages/xml';
@@ -109,4 +108,20 @@ document.addEventListener('DOMContentLoaded', () => {
109
108
  event.detail.path = isFavorite ? element.dataset.deleteUrl : element.dataset.addUrl;
110
109
  };
111
110
  window.setRequestUrl = setRequestUrl;
111
+
112
+ // Remove the blur after clicking the footer links that are opening mostly in the new tab
113
+ // Keeping focus on those items is what keeps the tooltip as well
114
+ document.querySelectorAll('a[data-bs-toggle="tooltip"], div[data-bs-toggle="tooltip"] > a').forEach((el) => {
115
+ el.addEventListener('click', () => {
116
+ el.blur();
117
+ });
118
+ });
119
+
120
+ // When modal is being closed, bootstrap automatically restore the focus on the element that was triggering the modal
121
+ // As a result, after modal close tooltip was triggered as well
122
+ document.addEventListener('hidden.bs.modal', () => {
123
+ document.querySelectorAll('[data-bs-toggle="tooltip"] > a').forEach((el) => {
124
+ el.blur();
125
+ });
126
+ });
112
127
  });
@@ -81,7 +81,7 @@ const initializeSelect2 = (context, selector, options) =>
81
81
  [...getElement(context).querySelectorAll(selector)].forEach((element) =>
82
82
  $(element).select2({
83
83
  allowClear: true,
84
- placeholder: element.getAttribute('placeholder') || '---------',
84
+ placeholder: '---------',
85
85
  selectionCssClass: 'select2--small',
86
86
  theme: 'bootstrap-5',
87
87
  width: 'off',
@@ -292,14 +292,65 @@ const initializeDynamicChoiceSelection = (context, dropdownParent = null) => {
292
292
  });
293
293
  };
294
294
 
295
- const initializeMultiValueChar = (context, dropdownParent = null) =>
295
+ const initializeMultiValueChar = (context, dropdownParent = null) => {
296
296
  initializeSelect2(context, '.nautobot-select2-multi-value-char', {
297
297
  dropdownParent,
298
298
  language: { noResults: () => 'Type something to add it as an option' },
299
299
  multiple: true,
300
300
  tags: true,
301
+ tokenSeparators: [','],
301
302
  });
302
303
 
304
+ // Ensure pressing Enter in the Select2 search adds the current token instead of submitting the form
305
+ [...getElement(context).querySelectorAll('.nautobot-select2-multi-value-char')].forEach((element) => {
306
+ $(element).on('select2:open', () => {
307
+ const container = document.querySelector('.select2-container--open');
308
+ if (!container) {
309
+ return;
310
+ }
311
+ const search = container.querySelector('input.select2-search__field');
312
+ if (!search) {
313
+ return;
314
+ }
315
+
316
+ // Avoid stacking multiple handlers
317
+ if (search.getAttribute('data-enter-binds')) {
318
+ return;
319
+ }
320
+ search.setAttribute('data-enter-binds', '1');
321
+
322
+ search.addEventListener('keydown', (ev) => {
323
+ if (ev.key === 'Enter') {
324
+ ev.preventDefault();
325
+ ev.stopPropagation();
326
+ const val = search.value.trim();
327
+ if (!val) {
328
+ return;
329
+ }
330
+ const sel = $(element).get(0);
331
+ // If option doesn't exist, create it; otherwise select it
332
+ const found = Array.prototype.find.call(sel.options, (opt) => String(opt.value) === String(val));
333
+ if (found) {
334
+ found.selected = true;
335
+ } else {
336
+ sel.add(new Option(val, val, true, true));
337
+ }
338
+ // Clear the search box and notify Select2
339
+ search.value = '';
340
+ $(element).trigger('change');
341
+ // Close the dropdown so it doesn't linger after add
342
+ try {
343
+ $(element).select2('close');
344
+ // eslint-disable-next-line no-unused-vars
345
+ } catch (exception) {
346
+ // Intentional no-op
347
+ }
348
+ }
349
+ });
350
+ });
351
+ });
352
+ };
353
+
303
354
  const initializeStaticChoiceSelection = (context, dropdownParent = null) =>
304
355
  initializeSelect2(context, '.nautobot-select2-static', { dropdownParent });
305
356
 
@@ -36,7 +36,7 @@ $gray-3-dark: #b5b5b5;
36
36
 
37
37
  $blue-0-dark: #339dff;
38
38
  $blue-1-dark: #1a2936;
39
- $blue-2-dark: #0e1C2B;
39
+ $blue-2-dark: #0e1c2b;
40
40
  $orange-0-dark: #ff9933;
41
41
  $orange-1-dark: #2a1c0f;
42
42
  $orange-2-dark: #3d2a16;
@@ -414,8 +414,8 @@ $btn-close-opacity: 0.68;
414
414
  $btn-close-hover-opacity: 1;
415
415
  $btn-close-focus-opacity: 1;
416
416
  $btn-close-disabled-opacity: 0.31;
417
- $btn-close-filter: invert(1%) sepia(10%) saturate(233%) hue-rotate(314deg) brightness(99%) contrast(81%);
418
- $btn-close-filter-dark: invert(96%) sepia(0%) saturate(1%) hue-rotate(250deg) brightness(86%) contrast(91%);
417
+ $btn-close-filter: invert(1%) sepia(10%) saturate(233%) hue-rotate(314deg) brightness(99%) contrast(81%); /* $black-0: #1a1a1a; */
418
+ $btn-close-filter-dark: invert(100%); /* $black-0-dark: #ffffff; */
419
419
  $btn-close-white-filter: $btn-close-filter-dark;
420
420
 
421
421
  /* Code */
@@ -431,6 +431,18 @@ $kbd-bg: var(--#{$prefix}secondary-bg);
431
431
  /* 4. Include any default map overrides here */
432
432
  $theme-colors-rgb-dark: map-loop($theme-colors-dark, to-rgb, "$value");
433
433
 
434
+ /* Breakpoints */
435
+ $sidenav-width-for-breakpoints: 240px; // this is only for calculations below; sidenav has separate variable in rem in Layout section
436
+
437
+ $grid-breakpoints: (
438
+ xs: 0,
439
+ sm: 576px + $sidenav-width-for-breakpoints,
440
+ md: 768px + $sidenav-width-for-breakpoints,
441
+ lg: 992px + $sidenav-width-for-breakpoints,
442
+ xl: 1200px + $sidenav-width-for-breakpoints,
443
+ xxl: 1400px + $sidenav-width-for-breakpoints
444
+ );
445
+
434
446
  /* 5. Include remainder of required parts */
435
447
  @import "bootstrap/scss/maps";
436
448
  @import "bootstrap/scss/mixins";
@@ -746,12 +758,6 @@ $nautobot-chevron-svg: "<svg viewBox='0 0 17 20' fill='none' xmlns='http://www.w
746
758
  }
747
759
  }
748
760
 
749
- @mixin nb-firefox-only {
750
- @supports (-moz-appearance: none) {
751
- @content;
752
- }
753
- }
754
-
755
761
  /* Links */
756
762
  a,
757
763
  button {
@@ -901,6 +907,12 @@ $table-variants: (
901
907
 
902
908
  color: var(--#{$prefix}table-color);
903
909
  border-color: var(--#{$prefix}table-border-color);
910
+
911
+ @if $color == "primary" or $color == "info" {
912
+ a {
913
+ text-decoration: underline;
914
+ }
915
+ }
904
916
  }
905
917
  }
906
918
 
@@ -909,6 +921,10 @@ $table-variants: (
909
921
  white-space: nowrap;
910
922
  }
911
923
 
924
+ table.attr-table td:nth-child(1) {
925
+ width: 25%;
926
+ }
927
+
912
928
  /* Buttons */
913
929
  .btn {
914
930
  --#{$prefix}btn-box-shadow: #{$btn-box-shadow};
@@ -1114,6 +1130,11 @@ textarea {
1114
1130
  }
1115
1131
  }
1116
1132
 
1133
+ .nb-form-check-input-sm {
1134
+ height: 1rem; /* 16px */
1135
+ width: 1rem; /* 16px */
1136
+ }
1137
+
1117
1138
  .form-text {
1118
1139
  display: block;
1119
1140
  font-weight: $font-weight-normal;
@@ -1251,6 +1272,18 @@ textarea {
1251
1272
  }
1252
1273
  }
1253
1274
 
1275
+ .card-body {
1276
+ .nav-tabs {
1277
+ margin-inline: $card-spacer-x * -1;
1278
+ }
1279
+
1280
+ .tab-content {
1281
+ > .tab-pane {
1282
+ padding-block-start: $card-spacer-y;
1283
+ }
1284
+ }
1285
+ }
1286
+
1254
1287
  .card-header {
1255
1288
  position: relative;
1256
1289
  text-transform: uppercase;
@@ -1275,11 +1308,13 @@ textarea {
1275
1308
  &.bg-danger,
1276
1309
  &.bg-info,
1277
1310
  &.bg-primary,
1311
+ &.bg-secondary,
1278
1312
  &.bg-success,
1279
1313
  &.bg-warning,
1280
1314
  &.text-bg-danger,
1281
1315
  &.text-bg-info,
1282
1316
  &.text-bg-primary,
1317
+ &.text-bg-secondary,
1283
1318
  &.text-bg-success,
1284
1319
  &.text-bg-warning {
1285
1320
  --#{$prefix}badge-color: var(--#{$prefix}body-bg);
@@ -1384,6 +1419,11 @@ textarea {
1384
1419
  }
1385
1420
  }
1386
1421
 
1422
+ /* Alerts */
1423
+ .alert:is(.alert-primary, .alert-info) a {
1424
+ text-decoration: underline;
1425
+ }
1426
+
1387
1427
  /* Progress bars */
1388
1428
  .progress {
1389
1429
  td & {
@@ -1413,6 +1453,14 @@ textarea {
1413
1453
  }
1414
1454
  }
1415
1455
 
1456
+ /* Code */
1457
+ pre:not(:has(code.hljs)) { /* Do not include highlight.js in this rule because it has its own set of styles. */
1458
+ background: var(--#{$prefix}secondary-bg);
1459
+ border-radius: $border-radius;
1460
+ padding-block: map.get($spacers, 8);
1461
+ padding-inline: map.get($spacers, 10);
1462
+ }
1463
+
1416
1464
  /* Collapse */
1417
1465
  .nb-collapse-toggle {
1418
1466
  @include transition($btn-transition);
@@ -1427,7 +1475,7 @@ textarea {
1427
1475
  display: inline-block; /* `transform` does not work on standard `inline` elements, like `span`, hence `inline-block`. */
1428
1476
  }
1429
1477
 
1430
- &:not([aria-expanded="true"]) > * {
1478
+ &:not([aria-expanded="true"]) > .mdi-chevron-down {
1431
1479
  transform: rotate(-90deg); /* Rotate chevron icon when collapse is closed. */
1432
1480
  }
1433
1481
  }
@@ -1452,7 +1500,8 @@ textarea {
1452
1500
  $nb-drawer-closed-width: 0;
1453
1501
  $nb-drawer-open-width: 20rem; /* 320px */
1454
1502
  $sidenav-width-collapsed: 4rem; /* 64px */
1455
- $sidenav-width-expanded: 15rem; /* 240px */
1503
+ $sidenav-width-expanded: ($sidenav-width-for-breakpoints / 16px) * 1rem; /* 16px is default browser conversion rate */
1504
+ /* we're converting to rem to have better web accessibility support */
1456
1505
 
1457
1506
  * {
1458
1507
  margin: 0;
@@ -1515,8 +1564,8 @@ body {
1515
1564
  /* Sidenav (a.k.a. navbar, nav menu, sidebar) */
1516
1565
  #sidenav {
1517
1566
  $sidenav-chevron-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill-rule='evenodd' clip-rule='evenodd' d='M14.53 5.46967C14.8229 5.76256 14.8229 6.23744 14.53 6.53033L10.7928 10.2676C10.388 10.6724 10.1167 10.9444 9.92461 11.1708C9.73817 11.3904 9.67071 11.5171 9.6393 11.6137C9.55773 11.8648 9.55773 12.1352 9.6393 12.3863C9.67071 12.4829 9.73817 12.6096 9.92461 12.8292C10.1167 13.0556 10.388 13.3276 10.7928 13.7324L14.53 17.4697C14.8229 17.7626 14.8229 18.2374 14.53 18.5303C14.2371 18.8232 13.7623 18.8232 13.4694 18.5303L9.73211 14.7931L9.71059 14.7715C9.33288 14.3939 9.01761 14.0786 8.7811 13.8C8.53443 13.5094 8.32969 13.2098 8.21272 12.8498C8.03326 12.2975 8.03326 11.7025 8.21272 11.1502C8.32969 10.7902 8.53443 10.4906 8.7811 10.2C9.01761 9.9214 9.33287 9.60615 9.71058 9.22845L9.73211 9.20693L13.4694 5.46967C13.7623 5.17678 14.2371 5.17678 14.53 5.46967Z' fill='#{$nav-white-0}'/></svg>";
1518
- $sidenav-favorite-icon-svg: "<svg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path d='M9.13784 4.72433C10.0591 2.8819 10.5197 1.96069 11.143 1.66508C11.6854 1.40782 12.3146 1.40782 12.8571 1.66508C13.4804 1.96069 13.941 2.88191 14.8622 4.72434L15.2215 5.4429C15.5059 6.01177 15.6481 6.29621 15.8562 6.51399C16.0403 6.70676 16.2612 6.86077 16.5058 6.96694C16.782 7.08689 17.0981 7.12201 17.7302 7.19225L18.0564 7.22849C20.2646 7.47385 21.3687 7.59653 21.8677 8.10561C22.3013 8.54802 22.5055 9.16639 22.4205 9.78001C22.3227 10.4861 21.5086 11.242 19.8805 12.7539L19.5361 13.0736C18.9804 13.5897 18.7025 13.8477 18.5419 14.1604C18.4 14.4368 18.3244 14.7424 18.3211 15.0531C18.3174 15.4046 18.4446 15.7671 18.699 16.4921V16.4921C19.5294 18.8587 19.9446 20.042 19.673 20.7338C19.4374 21.3339 18.927 21.7836 18.3021 21.9418C17.5816 22.1241 16.4767 21.5717 14.267 20.4668L13.4311 20.0489C12.9064 19.7865 12.644 19.6553 12.3688 19.6037C12.1251 19.558 11.8749 19.558 11.6312 19.6037C11.356 19.6553 11.0937 19.7865 10.5689 20.0489L9.73299 20.4668C7.52325 21.5717 6.41838 22.1241 5.69791 21.9418C5.07298 21.7836 4.56261 21.3339 4.32703 20.7338C4.05543 20.042 4.47062 18.8587 5.30101 16.4921V16.4921C5.55541 15.7671 5.68261 15.4046 5.67891 15.0531C5.67565 14.7424 5.60005 14.4368 5.45811 14.1604C5.29751 13.8477 5.01964 13.5897 4.46388 13.0736L4.11954 12.7539C2.49141 11.242 1.67734 10.4861 1.57953 9.78001C1.49453 9.16639 1.69867 8.54802 2.13229 8.10561C2.63127 7.59653 3.73538 7.47385 5.9436 7.22849L6.26976 7.19225C6.90189 7.12201 7.21795 7.08689 7.49423 6.96694C7.73879 6.86077 7.95965 6.70676 8.14383 6.51399C8.35189 6.29621 8.49411 6.01178 8.77855 5.44291L9.13784 4.72433Z' fill='none' stroke='#{$nav-white-0}' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>";
1519
- $sidenav-favorite-icon-svg-filled: "<svg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path d='M9.13784 4.72433C10.0591 2.8819 10.5197 1.96069 11.143 1.66508C11.6854 1.40782 12.3146 1.40782 12.8571 1.66508C13.4804 1.96069 13.941 2.88191 14.8622 4.72434L15.2215 5.4429C15.5059 6.01177 15.6481 6.29621 15.8562 6.51399C16.0403 6.70676 16.2612 6.86077 16.5058 6.96694C16.782 7.08689 17.0981 7.12201 17.7302 7.19225L18.0564 7.22849C20.2646 7.47385 21.3687 7.59653 21.8677 8.10561C22.3013 8.54802 22.5055 9.16639 22.4205 9.78001C22.3227 10.4861 21.5086 11.242 19.8805 12.7539L19.5361 13.0736C18.9804 13.5897 18.7025 13.8477 18.5419 14.1604C18.4 14.4368 18.3244 14.7424 18.3211 15.0531C18.3174 15.4046 18.4446 15.7671 18.699 16.4921V16.4921C19.5294 18.8587 19.9446 20.042 19.673 20.7338C19.4374 21.3339 18.927 21.7836 18.3021 21.9418C17.5816 22.1241 16.4767 21.5717 14.267 20.4668L13.4311 20.0489C12.9064 19.7865 12.644 19.6553 12.3688 19.6037C12.1251 19.558 11.8749 19.558 11.6312 19.6037C11.356 19.6553 11.0937 19.7865 10.5689 20.0489L9.73299 20.4668C7.52325 21.5717 6.41838 22.1241 5.69791 21.9418C5.07298 21.7836 4.56261 21.3339 4.32703 20.7338C4.05543 20.042 4.47062 18.8587 5.30101 16.4921V16.4921C5.55541 15.7671 5.68261 15.4046 5.67891 15.0531C5.67565 14.7424 5.60005 14.4368 5.45811 14.1604C5.29751 13.8477 5.01964 13.5897 4.46388 13.0736L4.11954 12.7539C2.49141 11.242 1.67734 10.4861 1.57953 9.78001C1.49453 9.16639 1.69867 8.54802 2.13229 8.10561C2.63127 7.59653 3.73538 7.47385 5.9436 7.22849L6.26976 7.19225C6.90189 7.12201 7.21795 7.08689 7.49423 6.96694C7.73879 6.86077 7.95965 6.70676 8.14383 6.51399C8.35189 6.29621 8.49411 6.01178 8.77855 5.44291L9.13784 4.72433Z' fill='#{$nav-white-0}' stroke='#{$nav-white-0}' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>";
1567
+ $sidenav-favorite-icon-svg: "<svg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path d='M11.4189 0.599609C11.8569 0.444608 12.3438 0.470222 12.7656 0.676758C13.1382 0.85937 13.3661 1.1983 13.5303 1.48926C13.7037 1.79665 13.8896 2.21226 14.1113 2.7041L16.4121 7.80957H20.7764C21.3853 7.80957 21.8928 7.80944 22.2793 7.84277C22.6369 7.87368 23.0791 7.9417 23.4111 8.22754C23.8327 8.59073 24.0486 9.13456 23.9902 9.68359C23.9441 10.116 23.6675 10.4639 23.4268 10.7266C23.1665 11.0102 22.7947 11.3503 22.3486 11.7588L18.7549 15.0479L20.415 19.7119C20.6345 20.3287 20.8155 20.837 20.9189 21.2324C21.0129 21.5918 21.1024 22.0532 20.9238 22.4707C20.7004 22.993 20.2266 23.3717 19.6621 23.4785C19.2108 23.5637 18.7714 23.3814 18.4346 23.2158C18.064 23.0337 17.5972 22.7531 17.0312 22.4131L12 19.3887L6.96875 22.4131C6.40288 22.7531 5.93606 23.0337 5.56543 23.2158C5.22855 23.3813 4.78918 23.5638 4.33789 23.4785C3.77339 23.3717 3.29963 22.993 3.07617 22.4707C2.89765 22.0532 2.9871 21.5918 3.08105 21.2324C3.18447 20.837 3.36558 20.3286 3.58496 19.7119L5.24414 15.0479L1.65137 11.7588C1.20524 11.3502 0.833466 11.0103 0.573242 10.7266C0.332409 10.4639 0.0559191 10.116 0.00976562 9.68359C-0.048592 9.13464 0.168374 8.59073 0.589844 8.22754L0.717773 8.13086C1.02957 7.92557 1.40768 7.86983 1.7207 7.84277C2.10716 7.80943 2.61462 7.80957 3.22363 7.80957H7.58789L9.88867 2.7041C10.1103 2.21236 10.2963 1.79663 10.4697 1.48926C10.6339 1.19837 10.862 0.859412 11.2344 0.676758L11.4189 0.599609ZM12.0918 1.97266C12.0325 1.94907 11.9664 1.94881 11.9072 1.97266C11.8903 1.99137 11.8406 2.05132 11.7588 2.19629C11.6253 2.43288 11.4699 2.77672 11.2363 3.29492L8.74121 8.83203C8.62278 9.09452 8.35775 9.26367 8.06641 9.26367H3.22363C2.58589 9.26367 2.15619 9.26459 1.84961 9.29102C1.65621 9.30775 1.57052 9.33069 1.54395 9.33887C1.4994 9.38481 1.47564 9.44621 1.47656 9.50977C1.4907 9.53411 1.53727 9.6094 1.66699 9.75098C1.87346 9.97601 2.18793 10.2644 2.65527 10.6924L6.60254 14.3066C6.81725 14.5033 6.89362 14.8073 6.79688 15.0801L4.97656 20.1943C4.74783 20.8372 4.59263 21.2751 4.50879 21.5957C4.45591 21.798 4.44774 21.8941 4.44629 21.9258C4.47718 21.982 4.52974 22.0236 4.5918 22.042C4.62177 22.0343 4.71557 22.0082 4.90723 21.9141C5.20782 21.7664 5.61016 21.5255 6.2002 21.1709L11.6162 17.916C11.8518 17.7744 12.1481 17.7744 12.3838 17.916L17.7998 21.1709C18.39 21.5256 18.7921 21.7664 19.0928 21.9141C19.2823 22.0072 19.3761 22.0339 19.4072 22.042C19.4695 22.0238 19.5216 21.982 19.5527 21.9258C19.5512 21.8941 19.5441 21.798 19.4912 21.5957C19.4073 21.2751 19.2522 20.8372 19.0234 20.1943L17.2031 15.0801C17.1064 14.8074 17.183 14.5034 17.3975 14.3066L21.3447 10.6924C21.8119 10.2645 22.1265 9.97601 22.333 9.75098C22.4617 9.61056 22.5079 9.53469 22.5225 9.50977C22.5233 9.44589 22.5 9.38489 22.4551 9.33887C22.4274 9.3304 22.3416 9.30754 22.1504 9.29102C21.8438 9.2646 21.414 9.26367 20.7764 9.26367H15.9336C15.6422 9.26359 15.3771 9.09454 15.2588 8.83203L12.7637 3.29492C12.53 2.7766 12.3747 2.43289 12.2412 2.19629C12.1584 2.04951 12.108 1.99058 12.0918 1.97266Z' fill='#{$nav-white-0}'/></svg>";
1568
+ $sidenav-favorite-icon-svg-filled: "<svg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path d='M11.4189 0.599457C11.8569 0.444456 12.3438 0.470069 12.7656 0.676605C13.1383 0.859207 13.3671 1.19809 13.5312 1.48911C13.7046 1.79644 13.8897 2.21229 14.1113 2.70395L16.4121 7.80942H20.7773C21.386 7.80942 21.8929 7.80931 22.2793 7.84262C22.6369 7.87353 23.0791 7.94253 23.4111 8.22836C23.8325 8.59154 24.0496 9.13456 23.9912 9.68344C23.9451 10.1159 23.6676 10.4637 23.4268 10.7264C23.1665 11.0101 22.7947 11.3502 22.3486 11.7586L18.7559 15.0477L20.415 19.7118C20.6345 20.3285 20.8155 20.8368 20.9189 21.2323C21.0129 21.5917 21.1024 22.053 20.9238 22.4706C20.7003 22.9929 20.2267 23.3716 19.6621 23.4784C19.2108 23.5635 18.7714 23.3812 18.4346 23.2157C18.0641 23.0336 17.598 22.7529 17.0322 22.4129L12 19.3885L6.96875 22.4129C6.40284 22.753 5.93608 23.0336 5.56543 23.2157C5.22855 23.3811 4.78918 23.5636 4.33789 23.4784C3.77348 23.3715 3.29961 22.9928 3.07617 22.4706C2.89773 22.0531 2.98711 21.5916 3.08105 21.2323C3.18447 20.8368 3.36655 20.3284 3.58594 19.7118L5.24414 15.0477L1.65137 11.7586C1.20515 11.35 0.833472 11.0102 0.573242 10.7264C0.33238 10.4637 0.0558689 10.1159 0.00976562 9.68344C-0.0485905 9.1345 0.168395 8.59155 0.589844 8.22836L0.717773 8.13071C1.02957 7.92542 1.40768 7.86968 1.7207 7.84262C2.10718 7.80926 2.61454 7.80942 3.22363 7.80942H7.58789L9.88867 2.70395C10.1103 2.21223 10.2963 1.79647 10.4697 1.48911C10.6339 1.19814 10.8628 0.859214 11.2354 0.676605L11.4189 0.599457Z' fill='#{$nav-white-0}'/></svg>";
1520
1569
  $sidenav-favorite-size: 1.25rem; /* 20px */
1521
1570
  $sidenav-link-gap: map.get($spacers, 5);
1522
1571
  $sidenav-link-segment-icon-height: 5.625rem; /* 90px */
@@ -1547,10 +1596,11 @@ body {
1547
1596
  @mixin filter-nav-orange-0 {
1548
1597
  /*
1549
1598
  * CSS workaround to change element color (including its `background-image`)
1550
- * from white to any given color, `$orange-0` in this case.
1599
+ * from white to any given color, `$orange-0-dark` in this case. Though it
1600
+ * evaluates to `#ff9938`, not the exact `#ff9933`, it is _good enough_.
1551
1601
  * Generated with: https://codepen.io/jumarjuaton/full/mdJYWYq
1552
1602
  */
1553
- filter: invert(50%) sepia(99%) saturate(1810%) hue-rotate(3deg) brightness(93%) contrast(94%);
1603
+ filter: invert(57%) sepia(100%) saturate(478%) hue-rotate(336deg) brightness(141%) contrast(101%);
1554
1604
  }
1555
1605
 
1556
1606
  @mixin filter-nav-gray-3 {
@@ -1558,7 +1608,7 @@ body {
1558
1608
  * CSS workaround to change element color (including its `background-image`) from white to `$nav-gray-3`.
1559
1609
  * Generated with: https://codepen.io/jumarjuaton/full/mdJYWYq
1560
1610
  */
1561
- filter: invert(39%) sepia(6%) saturate(1228%) hue-rotate(166deg) brightness(54%) contrast(86%);
1611
+ filter: invert(69%) sepia(15%) saturate(1%) hue-rotate(311deg) brightness(223%) contrast(98%);
1562
1612
  }
1563
1613
 
1564
1614
  @include box-shadow(0.0625rem 0 0 0 $navy-2, $box-shadow);
@@ -1633,7 +1683,7 @@ body {
1633
1683
  }
1634
1684
 
1635
1685
  img {
1636
- height: 1.875rem; /* 30px */
1686
+ height: 2rem; /* 32px */
1637
1687
  }
1638
1688
  }
1639
1689
 
@@ -1655,19 +1705,20 @@ body {
1655
1705
  min-width: $sidenav-link-width;
1656
1706
 
1657
1707
  /*
1658
- * FIXME(norbert-mieczkowski-codilime): remove this Firefox hack when it fixes its bug: https://bugzilla.mozilla.org/show_bug.cgi?id=995020.
1708
+ * FIXME(norbert-mieczkowski-codilime): remove this hack when browsers fix their bug: https://bugzilla.mozilla.org/show_bug.cgi?id=995020.
1709
+ * Bug has already been observed in Firefox and Safari, Chrome is confirmed to be _clean_.
1659
1710
  * Workaround based on: https://www.answeroverflow.com/m/1353731321620598945.
1660
1711
  */
1661
- @include nb-firefox-only {
1662
- flex-direction: row;
1663
- padding-block: map.get($spacers, 0);
1664
- padding-inline: map.get($spacers, 20);
1665
- writing-mode: vertical-lr;
1712
+ /* hack */
1713
+ flex-direction: row;
1714
+ padding-block: map.get($spacers, 0);
1715
+ padding-inline: map.get($spacers, 20);
1716
+ writing-mode: vertical-lr;
1666
1717
 
1667
- > * {
1668
- writing-mode: horizontal-tb;
1669
- }
1718
+ > * {
1719
+ writing-mode: horizontal-tb;
1670
1720
  }
1721
+ /* endhack */
1671
1722
  }
1672
1723
 
1673
1724
  .nb-sidenav-link {
@@ -1683,7 +1734,7 @@ body {
1683
1734
  width: $sidenav-link-width;
1684
1735
 
1685
1736
  &-active {
1686
- color: $orange-0;
1737
+ color: $orange-0-dark;
1687
1738
  }
1688
1739
 
1689
1740
  &::before { /* Segment icon */
@@ -1818,7 +1869,7 @@ body {
1818
1869
  }
1819
1870
 
1820
1871
  &:has(+ .nb-sidenav-flyout .nb-sidenav-link-active) { /* When list item contains an active link */
1821
- color: $orange-0;
1872
+ color: $orange-0-dark;
1822
1873
 
1823
1874
  > :first-child, /* Nav menu tab icon */
1824
1875
  > :last-child::after { /* Chevron icon */
@@ -1852,7 +1903,7 @@ body {
1852
1903
  @include fade-in;
1853
1904
  @include transition($transition-base);
1854
1905
  right: -0.8125rem; /* -13px */
1855
- top: 1.375rem; /* 22px */
1906
+ top: 1.4375rem; /* 23px */
1856
1907
 
1857
1908
  &::before { /* Chevron icon */
1858
1909
  @include chevron(1rem, $navy-0); /* 16px */
@@ -2233,11 +2284,11 @@ ul.nb-software-image-hierarchy {
2233
2284
 
2234
2285
  ul.nb-tree-hierarchy {
2235
2286
  list-style-type: none;
2236
- padding-block-start: map.get($spacers, 0);
2287
+ padding-inline-start: map.get($spacers, 0);
2237
2288
 
2238
2289
  ul {
2239
2290
  list-style-type: "↳ ";
2240
- padding-block-start: map.get($spacers, 4);
2291
+ padding-inline-start: 1.125rem; /* 18px */
2241
2292
  }
2242
2293
  }
2243
2294
 
@@ -2330,6 +2381,11 @@ pre code.hljs {
2330
2381
  border-radius: $border-radius;
2331
2382
  }
2332
2383
 
2384
+ /* Swagger docs */
2385
+ pre.version, pre.version-stamp {
2386
+ background-color: inherit !important;
2387
+ }
2388
+
2333
2389
  /* Rendered Markdown */
2334
2390
  .nb-rendered-markdown {
2335
2391
  table {
@@ -2436,3 +2492,29 @@ pre code.hljs {
2436
2492
  font-size: 1em;
2437
2493
  }
2438
2494
  }
2495
+
2496
+ .nb-lg-max-width {
2497
+ max-width: 960px;
2498
+ }
2499
+
2500
+ /* Workaround to fix `d-none` being overridden by `d-md-flex` (and possibly other `d-{display}` classes). */
2501
+ .d-none {
2502
+ display: none !important;
2503
+ }
2504
+
2505
+ /* Dark mode workaround */
2506
+ @include color-mode(dark, true) {
2507
+ .invert-in-dark-mode {
2508
+ filter: invert(1) hue-rotate(180deg);
2509
+ }
2510
+ }
2511
+
2512
+ /*
2513
+ * FIXME(norbert-mieczkowski-codilime): bootstrap-filestyle library, which is used by `ClearableFileInput` widget,
2514
+ * currently in version 1.2.3, still uses Bootstrap 3. This `.hidden` class "polyfill" is required until the library
2515
+ * is updated or removed/replaced completely. Bootstrap 5 supports file inputs out of the box, so it may be a good
2516
+ * time to get rid of bootstrap-filestyle.
2517
+ */
2518
+ .hidden {
2519
+ @extend .d-none;
2520
+ }