nautobot 2.4.21__py3-none-any.whl → 3.0.0a3__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.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/choices.py +2 -2
- nautobot/apps/filters.py +9 -9
- nautobot/apps/forms.py +2 -0
- nautobot/apps/models.py +7 -2
- nautobot/apps/ui.py +20 -1
- nautobot/apps/utils.py +2 -3
- nautobot/apps/views.py +7 -1
- nautobot/circuits/filters.py +8 -23
- nautobot/circuits/navigation.py +3 -1
- nautobot/circuits/templates/circuits/circuit_create.html +9 -9
- nautobot/circuits/templates/circuits/circuit_terminations_swap.html +2 -2
- nautobot/circuits/templates/circuits/circuittermination_create.html +24 -33
- nautobot/circuits/templates/circuits/inc/circuit_termination.html +10 -10
- nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +13 -13
- nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +6 -6
- nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +3 -3
- nautobot/circuits/templates/circuits/inc/speed_widget.html +13 -13
- nautobot/circuits/templates/circuits/provider_create.html +9 -9
- nautobot/circuits/tests/integration/test_circuit.py +19 -19
- nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +3 -0
- nautobot/circuits/tests/integration/test_relationships.py +4 -12
- nautobot/circuits/views.py +0 -2
- nautobot/cloud/filters.py +1 -13
- nautobot/cloud/navigation.py +3 -1
- nautobot/cloud/templates/cloud/cloudnetwork_update.html +9 -9
- nautobot/cloud/templates/cloud/cloudservice_update.html +6 -6
- nautobot/core/api/fields.py +30 -2
- nautobot/core/api/schema.py +1 -1
- nautobot/core/api/serializers.py +9 -2
- nautobot/core/api/urls.py +2 -0
- nautobot/core/api/views.py +58 -37
- nautobot/core/apps/__init__.py +6 -12
- nautobot/core/branching.py +83 -0
- nautobot/core/celery/__init__.py +11 -6
- nautobot/core/celery/backends.py +2 -0
- nautobot/core/celery/encoders.py +7 -0
- nautobot/core/celery/task.py +44 -0
- nautobot/core/checks.py +60 -0
- nautobot/core/cli/bootstrap_v3_to_v5.py +776 -0
- nautobot/core/constants.py +9 -0
- nautobot/core/context_processors.py +84 -0
- nautobot/core/filters.py +131 -2
- nautobot/core/forms/__init__.py +4 -2
- nautobot/core/forms/fields.py +10 -8
- nautobot/core/forms/forms.py +21 -9
- nautobot/core/forms/search.py +0 -15
- nautobot/core/forms/widgets.py +3 -2
- nautobot/core/graphql/__init__.py +8 -26
- nautobot/core/graphql/generators.py +16 -6
- nautobot/core/graphql/schema.py +1 -1
- nautobot/core/graphql/schema_init.py +1 -2
- nautobot/core/graphql/utils.py +7 -9
- nautobot/core/jobs/__init__.py +158 -0
- nautobot/core/management/commands/generate_test_data.py +28 -9
- nautobot/core/models/__init__.py +17 -2
- nautobot/core/models/fields.py +3 -2
- nautobot/core/models/generics.py +9 -1
- nautobot/core/models/name_color_content_types.py +1 -1
- nautobot/core/models/ordering.py +7 -5
- nautobot/core/models/querysets.py +77 -2
- nautobot/core/models/tree_queries.py +6 -4
- nautobot/core/settings.py +30 -16
- nautobot/core/settings.yaml +13 -7
- nautobot/core/tables.py +114 -44
- nautobot/core/templates/403.html +1 -1
- nautobot/core/templates/403_csrf_failure.html +1 -1
- nautobot/core/templates/404.html +1 -1
- nautobot/core/templates/40x.html +8 -8
- nautobot/core/templates/500.html +10 -10
- nautobot/core/templates/about.html +13 -12
- nautobot/core/templates/admin/actions.html +1 -1
- nautobot/core/templates/admin/app_index.html +3 -3
- nautobot/core/templates/admin/base.html +45 -52
- nautobot/core/templates/admin/base_site.html +0 -9
- nautobot/core/templates/admin/change_form.html +5 -5
- nautobot/core/templates/admin/change_list.html +8 -12
- nautobot/core/templates/admin/change_list_results.html +3 -3
- nautobot/core/templates/admin/config/config.html +24 -24
- nautobot/core/templates/admin/delete_confirmation.html +5 -5
- nautobot/core/templates/admin/edit_inline/stacked.html +5 -5
- nautobot/core/templates/admin/edit_inline/tabular.html +3 -3
- nautobot/core/templates/admin/includes/fieldset.html +15 -15
- nautobot/core/templates/admin/index.html +8 -8
- nautobot/core/templates/admin/submit_line.html +5 -5
- nautobot/core/templates/base_django.html +36 -32
- nautobot/core/templates/buttons/add.html +1 -1
- nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +2 -2
- nautobot/core/templates/buttons/export.html +17 -18
- nautobot/core/templates/buttons/job_import.html +2 -2
- nautobot/core/templates/components/breadcrumbs.html +19 -17
- nautobot/core/templates/components/button/dropdown.html +7 -5
- nautobot/core/templates/components/echarts.html +2 -0
- nautobot/core/templates/components/layout/one_over_two.html +3 -3
- nautobot/core/templates/components/layout/two_over_one.html +3 -3
- nautobot/core/templates/components/panel/body_content_data_table.html +2 -2
- nautobot/core/templates/components/panel/body_content_tags.html +1 -1
- nautobot/core/templates/components/panel/body_wrapper_generic.html +4 -2
- nautobot/core/templates/components/panel/body_wrapper_generic_table.html +1 -1
- nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +5 -3
- nautobot/core/templates/components/panel/body_wrapper_table.html +4 -2
- nautobot/core/templates/components/panel/footer_contacts_table.html +4 -4
- nautobot/core/templates/components/panel/footer_content_table.html +3 -3
- nautobot/core/templates/components/panel/grouping_toggle.html +12 -11
- nautobot/core/templates/components/panel/header_extra_content_table.html +2 -11
- nautobot/core/templates/components/panel/panel.html +6 -3
- nautobot/core/templates/components/panel/stats_panel_body.html +9 -7
- nautobot/core/templates/components/tab/content_wrapper.html +29 -1
- nautobot/core/templates/components/tab/label_wrapper.html +10 -2
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +11 -4
- nautobot/core/templates/echarts/echarts.html +20 -0
- nautobot/core/templates/exceptions/import_error.html +2 -2
- nautobot/core/templates/exceptions/permission_error.html +1 -1
- nautobot/core/templates/exceptions/programming_error.html +2 -2
- nautobot/core/templates/generic/object_bulk_add_component.html +29 -20
- nautobot/core/templates/generic/object_bulk_create.html +87 -75
- nautobot/core/templates/generic/object_bulk_destroy.html +35 -37
- nautobot/core/templates/generic/object_bulk_remove.html +30 -26
- nautobot/core/templates/generic/object_bulk_rename.html +53 -40
- nautobot/core/templates/generic/object_bulk_update.html +36 -29
- nautobot/core/templates/generic/object_create.html +40 -27
- nautobot/core/templates/generic/object_import.html +36 -24
- nautobot/core/templates/generic/object_list.html +279 -215
- nautobot/core/templates/generic/object_notes.html +21 -11
- nautobot/core/templates/generic/object_retrieve.html +161 -213
- nautobot/core/templates/graphene/graphiql.html +113 -60
- nautobot/core/templates/home.html +164 -87
- nautobot/core/templates/import_success.html +3 -2
- nautobot/core/templates/inc/ajax_loader.html +1 -1
- nautobot/core/templates/inc/computed_fields/panel_data.html +25 -13
- nautobot/core/templates/inc/created_updated.html +12 -7
- nautobot/core/templates/inc/custom_fields/panel_data.html +28 -16
- nautobot/core/templates/inc/custom_fields_panel.html +3 -3
- nautobot/core/templates/inc/dynamic_groups_panel.html +3 -3
- nautobot/core/templates/inc/extras_features_edit_form_fields.html +15 -15
- nautobot/core/templates/inc/footer.html +90 -40
- nautobot/core/templates/inc/form_static_field.html +6 -0
- nautobot/core/templates/inc/header.html +75 -0
- nautobot/core/templates/inc/header_banners.html +17 -0
- nautobot/core/templates/inc/header_messages.html +6 -0
- nautobot/core/templates/inc/image_attachments.html +9 -9
- nautobot/core/templates/inc/javascript.html +7 -24
- nautobot/core/templates/inc/media.html +4 -29
- nautobot/core/templates/inc/modal.html +2 -2
- nautobot/core/templates/inc/nav_favorites.html +27 -0
- nautobot/core/templates/inc/nav_menu.html +150 -108
- nautobot/core/templates/inc/object_details_advanced_panel.html +84 -71
- nautobot/core/templates/inc/page_title.html +23 -0
- nautobot/core/templates/inc/paginator.html +39 -28
- nautobot/core/templates/inc/relationships/panel_override.html +3 -3
- nautobot/core/templates/inc/relationships_panel.html +3 -3
- nautobot/core/templates/inc/relationships_table_rows.html +1 -1
- nautobot/core/templates/inc/search_panel.html +22 -16
- nautobot/core/templates/inc/table.html +61 -36
- nautobot/core/templates/inc/tenancy_form_panel.html +3 -3
- nautobot/core/templates/login.html +17 -59
- nautobot/core/templates/modals/modal_theme.html +12 -23
- nautobot/core/templates/nautobot_config.py.j2 +6 -5
- nautobot/core/templates/panel_table.html +8 -12
- nautobot/core/templates/redoc_ui.html +80 -0
- nautobot/core/templates/rest_framework/api.html +43 -21
- nautobot/core/templates/search.html +12 -13
- nautobot/core/templates/swagger_ui.html +19 -4
- nautobot/core/templates/system_jobs/import_objects.html +70 -58
- nautobot/core/templates/template.css +0 -6
- nautobot/core/templates/utilities/comment_form.html +34 -0
- nautobot/core/templates/utilities/confirmation_form.html +17 -9
- nautobot/core/templates/utilities/obj_table.html +19 -11
- nautobot/core/templates/utilities/render_field.html +27 -21
- nautobot/core/templates/utilities/render_jinja2.html +22 -25
- nautobot/core/templates/utilities/templatetags/advanced_filter_indicator.html +8 -0
- nautobot/core/templates/utilities/templatetags/badge.html +1 -1
- nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +2 -3
- nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +482 -0
- nautobot/core/templates/utilities/templatetags/modal_form_as_dialog.html +14 -18
- nautobot/core/templates/utilities/templatetags/saved_view_modal.html +11 -11
- nautobot/core/templates/utilities/templatetags/table_config_form.html +51 -24
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/templatetags/utilization_graph.html +3 -3
- nautobot/core/templates/utilities/theme_preview.html +829 -566
- nautobot/core/templates/utilities/worker_status.html +42 -41
- nautobot/core/templates/widgets/selectwithdisabled_option.html +3 -1
- nautobot/core/templates/widgets/sluginput.html +2 -2
- nautobot/core/templatetags/buttons.py +38 -40
- nautobot/core/templatetags/helpers.py +105 -28
- nautobot/core/templatetags/ui_framework.py +17 -0
- nautobot/core/testing/api.py +76 -12
- nautobot/core/testing/filters.py +11 -27
- nautobot/core/testing/integration.py +128 -10
- nautobot/core/testing/mixins.py +7 -4
- nautobot/core/testing/utils.py +28 -5
- nautobot/core/testing/views.py +125 -27
- nautobot/core/tests/integration/test_app_home.py +39 -35
- nautobot/core/tests/integration/test_app_navbar.py +60 -67
- nautobot/core/tests/integration/test_filters.py +123 -55
- nautobot/core/tests/integration/test_general_functionality.py +1 -1
- nautobot/core/tests/integration/test_home.py +10 -18
- nautobot/core/tests/integration/test_import_objects_ui.py +2 -9
- nautobot/core/tests/integration/test_navbar.py +41 -16
- nautobot/core/tests/integration/test_swagger.py +1 -7
- nautobot/core/tests/integration/test_theme.py +3 -0
- nautobot/core/tests/nautobot_config_without_example_apps.py +4 -0
- nautobot/core/tests/runner.py +6 -1
- nautobot/core/tests/test_api.py +5 -3
- nautobot/core/tests/test_branching.py +154 -0
- nautobot/core/tests/test_breadcrumbs.py +7 -8
- nautobot/core/tests/test_checks.py +28 -0
- nautobot/core/tests/test_commands.py +0 -41
- nautobot/core/tests/test_config.py +2 -1
- nautobot/core/tests/test_csv.py +4 -7
- nautobot/core/tests/test_filters.py +326 -318
- nautobot/core/tests/test_forms.py +19 -30
- nautobot/core/tests/test_graphql.py +67 -57
- nautobot/core/tests/test_models.py +1 -1
- nautobot/core/tests/test_nautobot_server.py +2 -0
- nautobot/core/tests/test_navigations.py +78 -10
- nautobot/core/tests/test_tables.py +3 -1
- nautobot/core/tests/test_templatetags_helpers.py +61 -21
- nautobot/core/tests/test_templatetags_ui_framework.py +36 -18
- nautobot/core/tests/test_ui.py +207 -2
- nautobot/core/tests/test_utils.py +147 -2
- nautobot/core/tests/test_views.py +201 -64
- nautobot/core/tests/test_views_utils.py +1 -1
- nautobot/core/ui/breadcrumbs.py +2 -12
- nautobot/core/ui/choices.py +190 -0
- nautobot/core/ui/constants.py +86 -0
- nautobot/core/ui/echarts.py +474 -0
- nautobot/core/ui/nav.py +5 -1
- nautobot/core/ui/object_detail.py +180 -16
- nautobot/core/urls.py +13 -1
- nautobot/core/utils/cache.py +71 -0
- nautobot/core/utils/data.py +8 -5
- nautobot/core/utils/filtering.py +8 -2
- nautobot/core/utils/git.py +3 -3
- nautobot/core/utils/lookup.py +87 -13
- nautobot/core/utils/migrations.py +22 -0
- nautobot/core/utils/module_loading.py +26 -0
- nautobot/core/utils/permissions.py +9 -5
- nautobot/core/views/__init__.py +114 -63
- nautobot/core/views/generic.py +34 -27
- nautobot/core/views/mixins.py +49 -27
- nautobot/core/views/renderers.py +3 -5
- nautobot/core/views/utils.py +10 -5
- nautobot/core/views/viewsets.py +2 -1
- nautobot/data_validation/__init__.py +0 -0
- nautobot/data_validation/api/__init__.py +1 -0
- nautobot/data_validation/api/serializers.py +80 -0
- nautobot/data_validation/api/urls.py +20 -0
- nautobot/data_validation/api/views.py +44 -0
- nautobot/data_validation/apps.py +18 -0
- nautobot/data_validation/custom_validators.py +330 -0
- nautobot/data_validation/filters.py +133 -0
- nautobot/data_validation/form_mixin.py +25 -0
- nautobot/data_validation/forms.py +342 -0
- nautobot/data_validation/migrations/0001_initial.py +224 -0
- nautobot/data_validation/migrations/0002_data_migration_from_app.py +324 -0
- nautobot/data_validation/migrations/__init__.py +0 -0
- nautobot/data_validation/models.py +361 -0
- nautobot/data_validation/navigation.py +74 -0
- nautobot/data_validation/signals.py +30 -0
- nautobot/data_validation/tables.py +259 -0
- nautobot/data_validation/templates/data_validation/datacompliance_retrieve.html +1 -0
- nautobot/data_validation/templates/data_validation/datacompliance_tab.html +11 -0
- nautobot/data_validation/templates/data_validation/device_constraints.html +61 -0
- nautobot/data_validation/tests/__init__.py +20 -0
- nautobot/data_validation/tests/migrations/__init__.py +0 -0
- nautobot/data_validation/tests/migrations/test_migrations.py +489 -0
- nautobot/data_validation/tests/test_api.py +238 -0
- nautobot/data_validation/tests/test_custom_validators.py +423 -0
- nautobot/data_validation/tests/test_data_compliance_rules.py +85 -0
- nautobot/data_validation/tests/test_filters.py +240 -0
- nautobot/data_validation/tests/test_form_mixin.py +115 -0
- nautobot/data_validation/tests/test_models.py +393 -0
- nautobot/data_validation/tests/test_views.py +435 -0
- nautobot/data_validation/urls.py +21 -0
- nautobot/data_validation/views.py +227 -0
- nautobot/dcim/api/serializers.py +10 -13
- nautobot/dcim/api/urls.py +2 -0
- nautobot/dcim/api/views.py +7 -0
- nautobot/dcim/apps.py +4 -0
- nautobot/dcim/choices.py +16 -0
- nautobot/dcim/custom_validators.py +84 -0
- nautobot/dcim/filter_mixins.py +353 -4
- nautobot/dcim/{filters/__init__.py → filters.py} +70 -157
- nautobot/dcim/forms.py +12 -6
- nautobot/dcim/graphql/types.py +1 -0
- nautobot/dcim/migrations/0075_add_deviceclusterassignment.py +52 -0
- nautobot/dcim/migrations/0076_device_cluster_to_clusters_data_migration.py +40 -0
- nautobot/dcim/migrations/0077_remove_device_cluster.py +14 -0
- nautobot/dcim/migrations/0078_remove_device_location_tenant_name_uniqueness.py +16 -0
- nautobot/dcim/migrations/0079_device_name_data_migration.py +59 -0
- nautobot/dcim/models/__init__.py +2 -0
- nautobot/dcim/models/device_components.py +3 -1
- nautobot/dcim/models/devices.py +115 -51
- nautobot/dcim/navigation.py +7 -3
- nautobot/dcim/querysets.py +6 -0
- nautobot/dcim/signals.py +19 -0
- nautobot/dcim/tables/devices.py +9 -5
- nautobot/dcim/tables/template_code.py +191 -102
- nautobot/dcim/templates/dcim/cable.html +1 -1
- nautobot/dcim/templates/dcim/cable_connect.html +62 -146
- nautobot/dcim/templates/dcim/cable_retrieve.html +10 -10
- nautobot/dcim/templates/dcim/cable_trace.html +15 -17
- nautobot/dcim/templates/dcim/console_port_connection_list.html +2 -2
- nautobot/dcim/templates/dcim/consoleport.html +18 -17
- nautobot/dcim/templates/dcim/consoleserverport.html +18 -17
- nautobot/dcim/templates/dcim/controller_create.html +12 -8
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +1 -1
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +6 -6
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/device/config.html +17 -19
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +4 -4
- nautobot/dcim/templates/dcim/device/status.html +20 -20
- nautobot/dcim/templates/dcim/device_component_add.html +24 -15
- nautobot/dcim/templates/dcim/device_create.html +120 -120
- nautobot/dcim/templates/dcim/device_list.html +75 -12
- nautobot/dcim/templates/dcim/devicebay.html +7 -7
- nautobot/dcim/templates/dcim/devicebay_populate.html +29 -23
- nautobot/dcim/templates/dcim/deviceredundancygroup_create.html +6 -6
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/devicetype_component_add.html +25 -19
- nautobot/dcim/templates/dcim/devicetype_list.html +4 -4
- nautobot/dcim/templates/dcim/devicetype_update.html +9 -9
- nautobot/dcim/templates/dcim/footer_convert_to_contact_or_team_record.html +3 -3
- nautobot/dcim/templates/dcim/frontport.html +21 -20
- nautobot/dcim/templates/dcim/inc/cable_form.html +7 -7
- nautobot/dcim/templates/dcim/inc/cable_termination.html +1 -1
- nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +18 -9
- nautobot/dcim/templates/dcim/inc/detail_softwareversion_softwareimagefile_rows.html +1 -1
- nautobot/dcim/templates/dcim/inc/device_interface_filter.html +1 -1
- nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +10 -10
- nautobot/dcim/templates/dcim/inc/edit_form_softwareversion_js.html +2 -2
- nautobot/dcim/templates/dcim/inc/homepage_connections.html +2 -2
- nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +10 -10
- nautobot/dcim/templates/dcim/inc/rack_elevation.html +2 -2
- nautobot/dcim/templates/dcim/interface.html +42 -22
- nautobot/dcim/templates/dcim/interface_connection_list.html +2 -2
- nautobot/dcim/templates/dcim/interface_edit.html +26 -11
- nautobot/dcim/templates/dcim/interfaceredundancygroupassociation_create.html +3 -3
- nautobot/dcim/templates/dcim/inventoryitem.html +3 -3
- nautobot/dcim/templates/dcim/inventoryitem_add.html +21 -10
- nautobot/dcim/templates/dcim/inventoryitem_bulk_delete.html +1 -1
- nautobot/dcim/templates/dcim/inventoryitem_edit.html +6 -4
- nautobot/dcim/templates/dcim/location.html +1 -1
- nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +24 -18
- nautobot/dcim/templates/dcim/location_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/location_update.html +9 -9
- nautobot/dcim/templates/dcim/locationtype.html +0 -1
- nautobot/dcim/templates/dcim/module/base.html +67 -27
- nautobot/dcim/templates/dcim/module_consoleports.html +13 -15
- nautobot/dcim/templates/dcim/module_consoleserverports.html +13 -15
- nautobot/dcim/templates/dcim/module_frontports.html +13 -15
- nautobot/dcim/templates/dcim/module_interfaces.html +14 -16
- nautobot/dcim/templates/dcim/module_list.html +59 -10
- nautobot/dcim/templates/dcim/module_modulebays.html +12 -14
- nautobot/dcim/templates/dcim/module_poweroutlets.html +13 -15
- nautobot/dcim/templates/dcim/module_powerports.html +13 -15
- nautobot/dcim/templates/dcim/module_rearports.html +13 -15
- nautobot/dcim/templates/dcim/module_retrieve.html +3 -3
- nautobot/dcim/templates/dcim/module_update.html +15 -9
- nautobot/dcim/templates/dcim/modulebay_retrieve.html +0 -93
- nautobot/dcim/templates/dcim/modulefamily_retrieve.html +7 -7
- nautobot/dcim/templates/dcim/moduletype_list.html +2 -2
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +74 -35
- nautobot/dcim/templates/dcim/platform_create.html +9 -9
- nautobot/dcim/templates/dcim/power_port_connection_list.html +3 -3
- nautobot/dcim/templates/dcim/powerfeed.html +1 -1
- nautobot/dcim/templates/dcim/powerfeed_edit.html +15 -15
- nautobot/dcim/templates/dcim/poweroutlet.html +13 -13
- nautobot/dcim/templates/dcim/powerpanel.html +1 -1
- nautobot/dcim/templates/dcim/powerport.html +17 -16
- nautobot/dcim/templates/dcim/rack.html +1 -1
- nautobot/dcim/templates/dcim/rack_elevation.html +2 -2
- nautobot/dcim/templates/dcim/rack_elevation_list.html +21 -9
- nautobot/dcim/templates/dcim/rack_retrieve.html +75 -57
- nautobot/dcim/templates/dcim/rack_update.html +14 -14
- nautobot/dcim/templates/dcim/rackreservation.html +1 -1
- nautobot/dcim/templates/dcim/rackreservation_edit.html +6 -6
- nautobot/dcim/templates/dcim/rearport.html +19 -18
- nautobot/dcim/templates/dcim/trace/cable.html +1 -1
- nautobot/dcim/templates/dcim/trace/circuit.html +1 -1
- nautobot/dcim/templates/dcim/trace/device.html +1 -1
- nautobot/dcim/templates/dcim/trace/powerpanel.html +1 -1
- nautobot/dcim/templates/dcim/trace/termination.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_add_member.html +25 -16
- nautobot/dcim/templates/dcim/virtualchassis_create.html +6 -6
- nautobot/dcim/templates/dcim/virtualchassis_edit.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_update.html +36 -22
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +9 -9
- nautobot/dcim/tests/integration/test_controller.py +6 -6
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +7 -7
- nautobot/dcim/tests/integration/test_create_device.py +9 -9
- nautobot/dcim/tests/integration/test_device_bulk_operations.py +7 -2
- nautobot/dcim/tests/integration/test_fileinputpicker.py +5 -7
- nautobot/dcim/tests/integration/test_location_bulk_operations.py +2 -0
- nautobot/dcim/tests/integration/test_module_bay_position.py +4 -1
- nautobot/dcim/tests/test_api.py +86 -6
- nautobot/dcim/tests/test_custom_validators.py +229 -0
- nautobot/dcim/tests/test_filters.py +159 -110
- nautobot/dcim/tests/test_graphql.py +32 -36
- nautobot/dcim/tests/test_jobs.py +1 -1
- nautobot/dcim/tests/test_models.py +229 -1
- nautobot/dcim/tests/test_views.py +31 -20
- nautobot/dcim/utils.py +3 -3
- nautobot/dcim/views.py +77 -41
- nautobot/extras/api/serializers.py +83 -19
- nautobot/extras/api/urls.py +7 -0
- nautobot/extras/api/views.py +243 -140
- nautobot/extras/choices.py +34 -13
- nautobot/extras/constants.py +1 -1
- nautobot/extras/context_managers.py +26 -26
- nautobot/extras/datasources/git.py +22 -0
- nautobot/extras/datasources/registry.py +3 -0
- nautobot/extras/exceptions.py +5 -0
- nautobot/extras/factory.py +11 -1
- nautobot/extras/{filters/mixins.py → filter_mixins.py} +4 -3
- nautobot/extras/{filters/__init__.py → filters.py} +203 -58
- nautobot/extras/forms/base.py +2 -1
- nautobot/extras/forms/forms.py +225 -20
- nautobot/extras/forms/mixins.py +0 -41
- nautobot/extras/homepage.py +21 -2
- nautobot/extras/jobs.py +2 -8
- nautobot/extras/jobs_ui.py +2 -2
- nautobot/extras/management/__init__.py +9 -0
- nautobot/extras/managers.py +31 -22
- nautobot/extras/migrations/0126_approval_workflow_pre_check.py +58 -0
- nautobot/extras/migrations/0127_approval_workflow_models.py +266 -0
- nautobot/extras/migrations/0128_remove_job_approval_required_and_more.py +29 -0
- nautobot/extras/migrations/0129_jobresult_debug_log_count_jobresult_error_log_count_and_more.py +37 -0
- nautobot/extras/migrations/0130_jobresult_generate_log_entry_counts.py +42 -0
- nautobot/extras/models/__init__.py +14 -3
- nautobot/extras/models/approvals.py +556 -0
- nautobot/extras/models/change_logging.py +1 -0
- nautobot/extras/models/contacts.py +2 -0
- nautobot/extras/models/customfields.py +57 -22
- nautobot/extras/models/datasources.py +21 -0
- nautobot/extras/models/groups.py +2 -0
- nautobot/extras/models/jobs.py +122 -39
- nautobot/extras/models/metadata.py +2 -3
- nautobot/extras/models/mixins.py +129 -1
- nautobot/extras/models/models.py +22 -14
- nautobot/extras/models/relationships.py +47 -10
- nautobot/extras/models/secrets.py +1 -0
- nautobot/extras/models/statuses.py +0 -15
- nautobot/extras/models/tags.py +1 -1
- nautobot/extras/navigation.py +42 -15
- nautobot/extras/plugins/__init__.py +33 -55
- nautobot/extras/plugins/marketplace_manifest.yml +1 -23
- nautobot/extras/plugins/tables.py +8 -6
- nautobot/extras/plugins/urls.py +2 -21
- nautobot/extras/plugins/utils.py +1 -33
- nautobot/extras/plugins/validators.py +10 -10
- nautobot/extras/plugins/views.py +1 -5
- nautobot/extras/querysets.py +17 -21
- nautobot/extras/signals.py +23 -8
- nautobot/extras/tables.py +420 -99
- nautobot/extras/templates/extras/approval_dashboard.html +15 -0
- nautobot/extras/templates/extras/approval_workflow/approve.html +11 -0
- nautobot/extras/templates/extras/approval_workflow/comment.html +9 -0
- nautobot/extras/templates/extras/approval_workflow/deny.html +10 -0
- nautobot/extras/templates/extras/approvalworkflowdefinition_update.html +77 -0
- nautobot/extras/templates/extras/approvalworkflowstage_retrieve.html +29 -0
- nautobot/extras/templates/extras/configcontext_update.html +12 -12
- nautobot/extras/templates/extras/configcontextschema.html +1 -1
- nautobot/extras/templates/extras/configcontextschema_retrieve.html +9 -9
- nautobot/extras/templates/extras/configcontextschema_update.html +6 -6
- nautobot/extras/templates/extras/configcontextschema_validation.html +2 -2
- nautobot/extras/templates/extras/customfield_update.html +12 -12
- nautobot/extras/templates/extras/dynamicgroup.html +1 -1
- nautobot/extras/templates/extras/dynamicgroup_edit.html +1 -1
- nautobot/extras/templates/extras/dynamicgroup_retrieve.html +17 -17
- nautobot/extras/templates/extras/dynamicgroup_update.html +24 -24
- nautobot/extras/templates/extras/externalintegration_update.html +6 -6
- nautobot/extras/templates/extras/gitrepository.html +1 -1
- nautobot/extras/templates/extras/gitrepository_object_edit.html +1 -1
- nautobot/extras/templates/extras/gitrepository_result.html +1 -1
- nautobot/extras/templates/extras/gitrepository_retrieve.html +12 -12
- nautobot/extras/templates/extras/gitrepository_update.html +25 -7
- nautobot/extras/templates/extras/graphqlquery_retrieve.html +1 -1
- nautobot/extras/templates/extras/inc/approval_buttons_column.html +38 -0
- nautobot/extras/templates/extras/inc/bulk_edit_overridable_field.html +14 -13
- nautobot/extras/templates/extras/inc/configcontext_format.html +11 -4
- nautobot/extras/templates/extras/inc/graphqlquery_execute.html +7 -7
- nautobot/extras/templates/extras/inc/job_label.html +5 -5
- nautobot/extras/templates/extras/inc/job_table.html +23 -10
- nautobot/extras/templates/extras/inc/job_tiles.html +33 -21
- nautobot/extras/templates/extras/inc/jobresult.html +6 -6
- nautobot/extras/templates/extras/inc/json_format.html +11 -4
- nautobot/extras/templates/extras/inc/object_contact_header.html +6 -6
- nautobot/extras/templates/extras/inc/overridable_field.html +16 -15
- nautobot/extras/templates/extras/inc/panel_approvalworkflowstage.html +34 -0
- nautobot/extras/templates/extras/inc/panel_changelog.html +9 -9
- nautobot/extras/templates/extras/inc/panel_jobhistory.html +8 -6
- nautobot/extras/templates/extras/inc/tags_panel.html +3 -3
- nautobot/extras/templates/extras/job.html +154 -155
- nautobot/extras/templates/extras/job_approval_confirmation.html +4 -27
- nautobot/extras/templates/extras/job_bulk_edit.html +18 -1
- nautobot/extras/templates/extras/job_detail.html +1 -1
- nautobot/extras/templates/extras/job_edit.html +69 -64
- nautobot/extras/templates/extras/job_list.html +37 -60
- nautobot/extras/templates/extras/jobresult.html +1 -1
- nautobot/extras/templates/extras/jobresult_retrieve.html +17 -17
- nautobot/extras/templates/extras/marketplace.html +62 -71
- nautobot/extras/templates/extras/metadatatype_create.html +9 -9
- nautobot/extras/templates/extras/note.html +1 -1
- nautobot/extras/templates/extras/object_approvalworkflow.html +36 -0
- nautobot/extras/templates/extras/object_assign_contact_or_team.html +16 -7
- nautobot/extras/templates/extras/object_configcontext.html +20 -20
- nautobot/extras/templates/extras/object_new_contact.html +6 -6
- nautobot/extras/templates/extras/object_new_team.html +6 -6
- nautobot/extras/templates/extras/objectchange.html +1 -1
- nautobot/extras/templates/extras/objectchange_retrieve.html +37 -56
- nautobot/extras/templates/extras/plugin_detail.html +40 -41
- nautobot/extras/templates/extras/plugins_list.html +23 -38
- nautobot/extras/templates/extras/plugins_tiles.html +28 -28
- nautobot/extras/templates/extras/role_retrieve.html +112 -48
- nautobot/extras/templates/extras/scheduledjob.html +25 -28
- nautobot/extras/templates/extras/secret_create.html +11 -11
- nautobot/extras/templates/extras/secretsgroup_update.html +6 -6
- nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +3 -3
- nautobot/extras/templates/extras/status.html +1 -1
- nautobot/extras/templates/extras/tag.html +1 -1
- nautobot/extras/templates/extras/tag_update.html +3 -3
- nautobot/extras/templates/extras/templatetags/log_level.html +1 -1
- nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -2
- nautobot/extras/templates/extras/webhook.html +12 -12
- nautobot/extras/templatetags/approvals.py +19 -0
- nautobot/extras/templatetags/custom_links.py +12 -12
- nautobot/extras/templatetags/job_buttons.py +14 -12
- nautobot/extras/test_jobs/invalid_import.py +9 -0
- nautobot/extras/test_jobs/log_counts_by_level.py +23 -0
- nautobot/extras/test_jobs/missing_import.py +11 -0
- nautobot/extras/tests/integration/test_computedfields.py +5 -8
- nautobot/extras/tests/integration/test_configcontextschema.py +43 -48
- nautobot/extras/tests/integration/test_customfields.py +33 -33
- nautobot/extras/tests/integration/test_dynamicgroups.py +5 -10
- nautobot/extras/tests/integration/test_jobs.py +2 -4
- nautobot/extras/tests/integration/test_notes.py +3 -9
- nautobot/extras/tests/integration/test_plugin_banner.py +3 -0
- nautobot/extras/tests/integration/test_plugins.py +35 -27
- nautobot/extras/tests/integration/test_relationships.py +7 -11
- nautobot/extras/tests/integration/test_tagfilter.py +3 -11
- nautobot/extras/tests/test_api.py +786 -242
- nautobot/extras/tests/test_approvals.py +715 -0
- nautobot/extras/tests/test_changelog.py +18 -14
- nautobot/extras/tests/test_customfields.py +14 -13
- nautobot/extras/tests/test_datasources.py +1 -1
- nautobot/extras/tests/test_dynamicgroups.py +9 -4
- nautobot/extras/tests/test_filters.py +443 -13
- nautobot/extras/tests/test_forms.py +18 -57
- nautobot/extras/tests/test_jobs.py +25 -4
- nautobot/extras/tests/test_migrations.py +81 -1
- nautobot/extras/tests/test_models.py +378 -47
- nautobot/extras/tests/test_plugins.py +47 -13
- nautobot/extras/tests/test_relationships.py +7 -2
- nautobot/extras/tests/test_utils.py +2 -0
- nautobot/extras/tests/test_views.py +780 -493
- nautobot/extras/urls.py +36 -12
- nautobot/extras/utils.py +58 -12
- nautobot/extras/views.py +668 -209
- nautobot/ipam/factory.py +7 -0
- nautobot/ipam/filter_mixins.py +38 -0
- nautobot/ipam/filters.py +35 -71
- nautobot/ipam/formfields.py +1 -1
- nautobot/ipam/forms.py +6 -3
- nautobot/ipam/migrations/0030_ipam__namespaces.py +13 -0
- nautobot/ipam/migrations/0031_ipam___data_migrations.py +4 -1
- nautobot/ipam/migrations/0054_namespace_tenant.py +25 -0
- nautobot/ipam/models.py +29 -2
- nautobot/ipam/navigation.py +3 -1
- nautobot/ipam/querysets.py +1 -2
- nautobot/ipam/tables.py +26 -17
- nautobot/ipam/templates/ipam/inc/ipadress_edit_header.html +6 -6
- nautobot/ipam/templates/ipam/inc/service.html +8 -8
- nautobot/ipam/templates/ipam/inc/toggle_available.html +10 -10
- nautobot/ipam/templates/ipam/inc/vlangroup_header.html +3 -2
- nautobot/ipam/templates/ipam/ipaddress.html +27 -13
- nautobot/ipam/templates/ipam/ipaddress_assign.html +31 -24
- nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +3 -3
- nautobot/ipam/templates/ipam/ipaddress_edit.html +9 -9
- nautobot/ipam/templates/ipam/ipaddress_interfaces.html +7 -9
- nautobot/ipam/templates/ipam/ipaddress_merge.html +195 -186
- nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +7 -9
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +7 -5
- nautobot/ipam/templates/ipam/namespace_ip_addresses.html +1 -1
- nautobot/ipam/templates/ipam/namespace_prefixes.html +1 -1
- nautobot/ipam/templates/ipam/namespace_update.html +15 -0
- nautobot/ipam/templates/ipam/namespace_vrfs.html +1 -1
- nautobot/ipam/templates/ipam/prefix_create.html +9 -9
- nautobot/ipam/templates/ipam/prefix_list.html +15 -14
- nautobot/ipam/templates/ipam/prefix_retrieve.html +0 -1
- nautobot/ipam/templates/ipam/vlan.html +1 -1
- nautobot/ipam/templates/ipam/vlan_interfaces.html +1 -1
- nautobot/ipam/templates/ipam/vlan_update.html +6 -6
- nautobot/ipam/templates/ipam/vlan_vminterfaces.html +1 -1
- nautobot/ipam/templates/ipam/vrf_edit.html +15 -15
- nautobot/ipam/tests/integration/test_prefixes.py +5 -13
- nautobot/ipam/tests/migration/test_migrations.py +89 -0
- nautobot/ipam/tests/test_api.py +20 -7
- nautobot/ipam/tests/test_filters.py +10 -0
- nautobot/ipam/tests/test_forms.py +1 -1
- nautobot/ipam/tests/test_models.py +1 -1
- nautobot/ipam/tests/test_tables.py +1 -2
- nautobot/ipam/tests/test_utils.py +1 -1
- nautobot/ipam/tests/test_views.py +24 -21
- nautobot/ipam/ui.py +0 -17
- nautobot/ipam/utils/migrations.py +16 -2
- nautobot/ipam/utils/testing.py +9 -3
- nautobot/ipam/views.py +49 -7
- nautobot/project-static/dist/css/graphql-libraries.css +655 -0
- nautobot/project-static/dist/css/graphql-libraries.css.map +1 -0
- nautobot/project-static/dist/css/materialdesignicons.css +3 -0
- nautobot/project-static/dist/css/materialdesignicons.css.map +1 -0
- nautobot/project-static/dist/css/nautobot.css +13 -0
- nautobot/project-static/dist/css/nautobot.css.map +1 -0
- nautobot/project-static/dist/js/graphql-libraries.js +3 -0
- nautobot/project-static/dist/js/graphql-libraries.js.LICENSE.txt +62 -0
- nautobot/project-static/dist/js/graphql-libraries.js.map +1 -0
- nautobot/project-static/dist/js/libraries.js +3 -0
- nautobot/project-static/dist/js/libraries.js.LICENSE.txt +65 -0
- nautobot/project-static/dist/js/libraries.js.map +1 -0
- nautobot/project-static/dist/js/materialdesignicons.js +0 -0
- nautobot/project-static/dist/js/nautobot-graphiql.js +2 -0
- nautobot/project-static/dist/js/nautobot-graphiql.js.map +1 -0
- nautobot/project-static/dist/js/nautobot.js +2 -0
- nautobot/project-static/dist/js/nautobot.js.map +1 -0
- nautobot/project-static/fonts/Montserrat-v30-Bold.woff2 +0 -0
- nautobot/project-static/fonts/Montserrat-v30-Light.woff2 +0 -0
- nautobot/project-static/fonts/Montserrat-v30-Regular.woff2 +0 -0
- nautobot/project-static/fonts/Roboto-v48-Bold.woff2 +0 -0
- nautobot/project-static/fonts/Roboto-v48-Light.woff2 +0 -0
- nautobot/project-static/fonts/Roboto-v48-Regular.woff2 +0 -0
- nautobot/project-static/img/jinja_logo.svg +21 -92
- nautobot/project-static/js/cabletrace.js +1 -1
- nautobot/project-static/js/editor.js +4 -4
- nautobot/project-static/js/forms.js +67 -717
- nautobot/project-static/js/job_result.js +2 -2
- nautobot/project-static/nautobot-icons/360-degrees.svg +3 -0
- nautobot/project-static/nautobot-icons/arrow-decision.svg +3 -0
- nautobot/project-static/nautobot-icons/arrows-expand-rec.svg +3 -0
- nautobot/project-static/nautobot-icons/arrows-move-2-rec.svg +3 -0
- nautobot/project-static/nautobot-icons/arrows-move-rec.svg +3 -0
- nautobot/project-static/nautobot-icons/atom.svg +3 -0
- nautobot/project-static/nautobot-icons/battery-3.svg +3 -0
- nautobot/project-static/nautobot-icons/branch.svg +3 -0
- nautobot/project-static/nautobot-icons/briefcase-2.svg +3 -0
- nautobot/project-static/nautobot-icons/cable-data-2.svg +3 -0
- nautobot/project-static/nautobot-icons/cable-data.svg +3 -0
- nautobot/project-static/nautobot-icons/cast.svg +3 -0
- nautobot/project-static/nautobot-icons/check-circle.svg +3 -0
- nautobot/project-static/nautobot-icons/checkbox-circle.svg +3 -0
- nautobot/project-static/nautobot-icons/checkbox-rec.svg +3 -0
- nautobot/project-static/nautobot-icons/cloud-check.svg +3 -0
- nautobot/project-static/nautobot-icons/cloud-lightning.svg +3 -0
- nautobot/project-static/nautobot-icons/cloud-upload.svg +3 -0
- nautobot/project-static/nautobot-icons/cloud.svg +3 -0
- nautobot/project-static/nautobot-icons/compass.svg +3 -0
- nautobot/project-static/nautobot-icons/control-panel.svg +3 -0
- nautobot/project-static/nautobot-icons/credit-card.svg +3 -0
- nautobot/project-static/nautobot-icons/device-lifecycle.svg +3 -0
- nautobot/project-static/nautobot-icons/direction.svg +3 -0
- nautobot/project-static/nautobot-icons/elements.svg +3 -0
- nautobot/project-static/nautobot-icons/extensibility.svg +3 -0
- nautobot/project-static/nautobot-icons/globe-2.svg +3 -0
- nautobot/project-static/nautobot-icons/globe.svg +3 -0
- nautobot/project-static/nautobot-icons/hammer.svg +3 -0
- nautobot/project-static/nautobot-icons/history.svg +3 -0
- nautobot/project-static/nautobot-icons/ip.svg +3 -0
- nautobot/project-static/nautobot-icons/laptop.svg +3 -0
- nautobot/project-static/nautobot-icons/lightning.svg +3 -0
- nautobot/project-static/nautobot-icons/list-unordered.svg +3 -0
- nautobot/project-static/nautobot-icons/map-view.svg +3 -0
- nautobot/project-static/nautobot-icons/organization.svg +3 -0
- nautobot/project-static/nautobot-icons/pin-2.svg +3 -0
- nautobot/project-static/nautobot-icons/pin-3.svg +3 -0
- nautobot/project-static/nautobot-icons/plug.svg +3 -0
- nautobot/project-static/nautobot-icons/refresh-cw.svg +3 -0
- nautobot/project-static/nautobot-icons/rocket-2.svg +3 -0
- nautobot/project-static/nautobot-icons/rotate-cw.svg +3 -0
- nautobot/project-static/nautobot-icons/route.svg +3 -0
- nautobot/project-static/nautobot-icons/secrets.svg +3 -0
- nautobot/project-static/nautobot-icons/security.svg +3 -0
- nautobot/project-static/nautobot-icons/server-2.svg +3 -0
- nautobot/project-static/nautobot-icons/server.svg +3 -0
- nautobot/project-static/nautobot-icons/share.svg +3 -0
- nautobot/project-static/nautobot-icons/shield-check.svg +3 -0
- nautobot/project-static/nautobot-icons/sitemap-outline.svg +3 -0
- nautobot/project-static/nautobot-icons/sliders-vert-2.svg +3 -0
- nautobot/project-static/nautobot-icons/sliders-vert.svg +3 -0
- nautobot/project-static/nautobot-icons/star-filled.svg +3 -0
- nautobot/project-static/nautobot-icons/star.svg +3 -0
- nautobot/project-static/nautobot-icons/transform.svg +3 -0
- nautobot/project-static/nautobot-icons/wifi.svg +3 -0
- nautobot/tenancy/api/serializers.py +1 -0
- nautobot/tenancy/api/views.py +2 -1
- nautobot/tenancy/{filters/__init__.py → filters.py} +2 -10
- nautobot/tenancy/navigation.py +3 -1
- nautobot/tenancy/templates/tenancy/tenant_create.html +6 -6
- nautobot/tenancy/tests/test_filters.py +0 -2
- nautobot/tenancy/views.py +2 -1
- nautobot/ui/.gitignore +137 -0
- nautobot/ui/.node-version +1 -0
- nautobot/ui/.prettierignore +3 -0
- nautobot/ui/eslint.config.js +33 -0
- nautobot/ui/package-lock.json +6594 -0
- nautobot/ui/package.json +67 -0
- nautobot/ui/prettier.config.js +9 -0
- nautobot/ui/src/js/collapse.js +69 -0
- nautobot/ui/src/js/cookie.js +31 -0
- nautobot/ui/src/js/draggable.js +101 -0
- nautobot/ui/src/js/drawer.js +106 -0
- nautobot/ui/src/js/form.js +23 -0
- nautobot/ui/src/js/history.js +51 -0
- nautobot/ui/src/js/nautobot-graphiql.js +19 -0
- nautobot/ui/src/js/nautobot.js +128 -0
- nautobot/ui/src/js/search.js +274 -0
- nautobot/ui/src/js/select2.js +318 -0
- nautobot/ui/src/js/sidenav.js +87 -0
- nautobot/ui/src/js/tabs.js +139 -0
- nautobot/ui/src/js/theme.js +104 -0
- nautobot/ui/src/js/utils.js +54 -0
- nautobot/ui/src/scss/colors.scss +58 -0
- nautobot/ui/src/scss/nautobot.scss +2471 -0
- nautobot/ui/webpack.config.js +148 -0
- nautobot/users/apps.py +3 -0
- nautobot/users/filters.py +7 -11
- nautobot/users/forms.py +10 -0
- nautobot/users/models.py +8 -0
- nautobot/users/templates/users/advanced_settings_edit.html +31 -21
- nautobot/users/templates/users/api_tokens.html +61 -51
- nautobot/users/templates/users/base.html +23 -31
- nautobot/users/templates/users/change_password.html +29 -19
- nautobot/users/templates/users/preferences.html +55 -45
- nautobot/users/templates/users/profile.html +45 -14
- nautobot/users/tests/test_api.py +4 -0
- nautobot/users/urls.py +2 -0
- nautobot/users/views.py +70 -2
- nautobot/virtualization/api/views.py +1 -1
- nautobot/virtualization/filters.py +18 -32
- nautobot/virtualization/forms.py +22 -59
- nautobot/virtualization/models.py +1 -19
- nautobot/virtualization/navigation.py +3 -1
- nautobot/virtualization/tables.py +10 -6
- nautobot/virtualization/templates/virtualization/cluster.html +13 -13
- nautobot/virtualization/templates/virtualization/cluster_edit.html +6 -6
- nautobot/virtualization/templates/virtualization/inc/virtualmachine_vminterface_filter.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_component_add.html +24 -16
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_list.html +4 -4
- nautobot/virtualization/templates/virtualization/virtualmachine_update.html +27 -25
- nautobot/virtualization/templates/virtualization/vminterface.html +5 -5
- nautobot/virtualization/templates/virtualization/vminterface_edit.html +27 -11
- nautobot/virtualization/tests/test_api.py +3 -0
- nautobot/virtualization/tests/test_models.py +20 -5
- nautobot/virtualization/tests/test_views.py +3 -5
- nautobot/virtualization/urls.py +0 -11
- nautobot/virtualization/views.py +5 -122
- nautobot/vpn/__init__.py +0 -0
- nautobot/vpn/api/serializers.py +113 -0
- nautobot/vpn/api/urls.py +19 -0
- nautobot/vpn/api/views.py +70 -0
- nautobot/vpn/apps.py +8 -0
- nautobot/vpn/choices.py +171 -0
- nautobot/vpn/factory.py +209 -0
- nautobot/vpn/filters.py +233 -0
- nautobot/vpn/forms.py +486 -0
- nautobot/vpn/homepage.py +19 -0
- nautobot/vpn/migrations/0001_initial.py +541 -0
- nautobot/vpn/migrations/0002_populate_defaults.py +199 -0
- nautobot/vpn/migrations/__init__.py +0 -0
- nautobot/vpn/models.py +527 -0
- nautobot/vpn/navigation.py +98 -0
- nautobot/vpn/tables.py +380 -0
- nautobot/vpn/templates/vpn/vpnprofile.html +2 -0
- nautobot/vpn/templates/vpn/vpnprofile_create.html +150 -0
- nautobot/vpn/tests/__init__.py +0 -0
- nautobot/vpn/tests/test_api.py +341 -0
- nautobot/vpn/tests/test_filters.py +139 -0
- nautobot/vpn/tests/test_forms.py +294 -0
- nautobot/vpn/tests/test_models.py +97 -0
- nautobot/vpn/tests/test_views.py +281 -0
- nautobot/vpn/urls.py +16 -0
- nautobot/vpn/views.py +437 -0
- nautobot/wireless/filters.py +0 -8
- nautobot/wireless/navigation.py +3 -1
- nautobot/wireless/templates/wireless/wirelessnetwork_create.html +6 -6
- nautobot/wireless/tests/integration/test_radio_profile.py +3 -7
- nautobot/wireless/tests/test_api.py +1 -1
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/METADATA +5 -4
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/RECORD +802 -707
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/entry_points.txt +1 -0
- nautobot/core/management/commands/check_job_approval_status.py +0 -47
- nautobot/core/templates/search_form.html +0 -9
- nautobot/core/templates/utilities/templatetags/filter_form_modal.html +0 -87
- nautobot/dcim/filters/mixins.py +0 -354
- nautobot/extras/templates/extras/job_approval_request.html +0 -134
- nautobot/extras/templates/extras/scheduled_jobs_approval_queue_list.html +0 -28
- nautobot/ipam/mixins.py +0 -32
- nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +0 -4
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +0 -587
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +0 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +0 -6
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +0 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +0 -6865
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +0 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +0 -6
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +0 -1
- nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.eot +0 -0
- nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.svg +0 -288
- nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff +0 -0
- nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- nautobot/project-static/bootstrap-3.4.1-dist/js/bootstrap.js +0 -2580
- nautobot/project-static/bootstrap-3.4.1-dist/js/bootstrap.min.js +0 -6
- nautobot/project-static/bootstrap-3.4.1-dist/js/npm.js +0 -13
- nautobot/project-static/clipboard.js-2.0.9/clipboard.min.js +0 -7
- nautobot/project-static/css/base.css +0 -1040
- nautobot/project-static/css/dark.css +0 -282
- nautobot/project-static/flatpickr-4.6.9/flatpickr.min.js +0 -2
- nautobot/project-static/flatpickr-4.6.9/themes/light.min.css +0 -1
- nautobot/project-static/graphiql-1.5.16/graphiql.min.css +0 -12
- nautobot/project-static/graphiql-1.5.16/graphiql.min.js +0 -11
- nautobot/project-static/highlight.js-11.9.0/github-dark.min.css +0 -10
- nautobot/project-static/highlight.js-11.9.0/github.min.css +0 -10
- nautobot/project-static/highlight.js-11.9.0/highlight.min.js +0 -378
- nautobot/project-static/jquery/jquery-3.7.1.min.js +0 -2
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_444444_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_555555_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_777620_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_777777_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_cc0000_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_ffffff_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.css +0 -7
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.js +0 -6
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.structure.min.css +0 -5
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.theme.min.css +0 -5
- nautobot/project-static/js/homepage_layout.js +0 -182
- nautobot/project-static/js/nav_menu.js +0 -250
- nautobot/project-static/js/theme.js +0 -133
- nautobot/project-static/materialdesignicons-7.4.47/LICENSE +0 -20
- nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +0 -3
- nautobot/project-static/react-16.14.0/react.production.min.js +0 -32
- nautobot/project-static/react-dom-16.14.0/react-dom.production.min.js +0 -239
- nautobot/project-static/select2-4.0.13/i18n/af.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ar.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/az.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/bg.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/bn.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/bs.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ca.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/cs.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/da.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/de.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/dsb.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/el.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/en.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/es.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/et.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/eu.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/fa.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/fi.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/fr.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/gl.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/he.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/hi.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/hr.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/hsb.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/hu.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/hy.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/id.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/is.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/it.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ja.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ka.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/km.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ko.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/lt.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/lv.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/mk.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ms.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/nb.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ne.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/nl.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/pl.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ps.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/pt-BR.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/pt.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ro.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/ru.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sk.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sl.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sq.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sr-Cyrl.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sr.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/sv.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/th.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/tk.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/tr.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/uk.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/vi.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/zh-CN.js +0 -3
- nautobot/project-static/select2-4.0.13/i18n/zh-TW.js +0 -3
- nautobot/project-static/select2-4.0.13/select2.min.css +0 -1
- nautobot/project-static/select2-4.0.13/select2.min.js +0 -2
- nautobot/project-static/select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css +0 -7
- nautobot/project-static/subscriptions-transport-ws-0.9.18/client.min.js +0 -8
- nautobot/project-static/whatwg-fetch-3.6.2/fetch.umd.min.js +0 -8
- nautobot/virtualization/templates/virtualization/cluster_add_devices.html +0 -37
- /nautobot/extras/{filters/customfields.py → filter_mixins_customfields.py} +0 -0
- /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.ttf → dist/1fcc36272ea3e53d0031.ttf} +0 -0
- /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.eot → dist/2146c3c82b553977abc7.eot} +0 -0
- /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff → dist/e55a20c80650829ec5fd.woff} +0 -0
- /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 → dist/ec024da790d2972da002.woff2} +0 -0
- /nautobot/tenancy/{filters/mixins.py → filter_mixins.py} +0 -0
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/NOTICE +0 -0
- {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/WHEEL +0 -0
nautobot/core/settings.py
CHANGED
|
@@ -95,11 +95,12 @@ if "NAUTOBOT_DEPLOYMENT_ID" in os.environ and os.environ["NAUTOBOT_DEPLOYMENT_ID
|
|
|
95
95
|
DEPLOYMENT_ID = os.environ["NAUTOBOT_DEPLOYMENT_ID"]
|
|
96
96
|
|
|
97
97
|
# Device names are not guaranteed globally-unique by Nautobot but in practice they often are.
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
# Select how Devices are uniquely identified:
|
|
99
|
+
# - 'location_tenant_name': combination of Location + Tenant + Name
|
|
100
|
+
# - 'name': Device name must be globally unique
|
|
101
|
+
# - 'none': No enforced uniqueness (rely on other validation rules or custom validators)
|
|
102
|
+
if "NAUTOBOT_DEVICE_UNIQUENESS" in os.environ and os.environ["NAUTOBOT_DEVICE_UNIQUENESS"] != "":
|
|
103
|
+
DEVICE_UNIQUENESS = os.environ["NAUTOBOT_DEVICE_UNIQUENESS"]
|
|
103
104
|
|
|
104
105
|
# Event Brokers
|
|
105
106
|
EVENT_BROKERS = {}
|
|
@@ -312,9 +313,11 @@ REST_FRAMEWORK_VERSION = VERSION.rsplit(".", 1)[0] # Use major.minor as API ver
|
|
|
312
313
|
VERSION_MAJOR, VERSION_MINOR = [int(v) for v in REST_FRAMEWORK_VERSION.split(".")]
|
|
313
314
|
# We support all major.minor API versions from 2.0 to the present latest version.
|
|
314
315
|
# Similar logic exists in tasks.py, please keep them in sync!
|
|
315
|
-
if VERSION_MAJOR
|
|
316
|
+
if VERSION_MAJOR > 3:
|
|
316
317
|
raise RuntimeError(f"REST_FRAMEWORK_ALLOWED_VERSIONS needs to be updated to handle version {VERSION_MAJOR}")
|
|
317
|
-
REST_FRAMEWORK_ALLOWED_VERSIONS = [
|
|
318
|
+
REST_FRAMEWORK_ALLOWED_VERSIONS = ["2.0", "2.1", "2.2", "2.3", "2.4"] + [
|
|
319
|
+
f"{VERSION_MAJOR}.{minor}" for minor in range(0, VERSION_MINOR + 1)
|
|
320
|
+
]
|
|
318
321
|
|
|
319
322
|
REST_FRAMEWORK = {
|
|
320
323
|
"ALLOWED_VERSIONS": REST_FRAMEWORK_ALLOWED_VERSIONS,
|
|
@@ -403,6 +406,7 @@ SPECTACULAR_SETTINGS = {
|
|
|
403
406
|
# These choice enums need to be overridden because they get assigned to different names with the same choice set and
|
|
404
407
|
# result in this error:
|
|
405
408
|
# encountered multiple names for the same choice set
|
|
409
|
+
"ApprovalWorkflowStateChoices": "nautobot.extras.choices.ApprovalWorkflowStateChoices",
|
|
406
410
|
"JobExecutionTypeIntervalChoices": "nautobot.extras.choices.JobExecutionType",
|
|
407
411
|
# These choice enums need to be overridden because they get assigned to the `protocol` field and
|
|
408
412
|
# result in this error:
|
|
@@ -413,6 +417,7 @@ SPECTACULAR_SETTINGS = {
|
|
|
413
417
|
# result in this error:
|
|
414
418
|
# enum naming encountered a non-optimally resolvable collision for fields named "mode".
|
|
415
419
|
"InterfaceModeChoices": "nautobot.dcim.choices.InterfaceModeChoices",
|
|
420
|
+
"VPNPhase2PolicyChoices": "nautobot.vpn.choices.DhGroupChoices",
|
|
416
421
|
"WirelessNetworkModeChoices": "nautobot.wireless.choices.WirelessNetworkModeChoices",
|
|
417
422
|
},
|
|
418
423
|
# Create separate schema components for PATCH requests (fields generally are not `required` on PATCH)
|
|
@@ -446,8 +451,10 @@ DATABASES = {
|
|
|
446
451
|
}
|
|
447
452
|
|
|
448
453
|
# Ensure proper Unicode handling for MySQL
|
|
449
|
-
if DATABASES["default"]["ENGINE"]
|
|
450
|
-
DATABASES["default"]
|
|
454
|
+
if "mysql" in DATABASES["default"]["ENGINE"]:
|
|
455
|
+
DATABASES["default"].setdefault("OPTIONS", {})["charset"] = "utf8mb4"
|
|
456
|
+
DATABASES["default"].setdefault("TEST", {})["CHARSET"] = "utf8mb4"
|
|
457
|
+
DATABASES["default"]["TEST"]["COLLATION"] = "utf8mb4_0900_ai_ci"
|
|
451
458
|
|
|
452
459
|
# The secret key is used to encrypt session keys and salt passwords.
|
|
453
460
|
SECRET_KEY = os.getenv("NAUTOBOT_SECRET_KEY", "")
|
|
@@ -557,12 +564,14 @@ INSTALLED_APPS = [
|
|
|
557
564
|
"db_file_storage",
|
|
558
565
|
"nautobot.circuits",
|
|
559
566
|
"nautobot.cloud",
|
|
567
|
+
"nautobot.data_validation",
|
|
560
568
|
"nautobot.dcim",
|
|
561
569
|
"nautobot.ipam",
|
|
562
570
|
"nautobot.extras",
|
|
563
571
|
"nautobot.tenancy",
|
|
564
572
|
"nautobot.users",
|
|
565
573
|
"nautobot.virtualization",
|
|
574
|
+
"nautobot.vpn",
|
|
566
575
|
"nautobot.wireless",
|
|
567
576
|
"drf_spectacular",
|
|
568
577
|
"drf_spectacular_sidecar",
|
|
@@ -615,6 +624,7 @@ TEMPLATES = [
|
|
|
615
624
|
"django.contrib.messages.context_processors.messages",
|
|
616
625
|
"social_django.context_processors.backends",
|
|
617
626
|
"social_django.context_processors.login_redirect",
|
|
627
|
+
"nautobot.core.context_processors.nav_menu",
|
|
618
628
|
"nautobot.core.context_processors.settings",
|
|
619
629
|
"nautobot.core.context_processors.sso_auth",
|
|
620
630
|
],
|
|
@@ -634,6 +644,7 @@ TEMPLATES = [
|
|
|
634
644
|
"django.contrib.messages.context_processors.messages",
|
|
635
645
|
"social_django.context_processors.backends",
|
|
636
646
|
"social_django.context_processors.login_redirect",
|
|
647
|
+
"nautobot.core.context_processors.nav_menu",
|
|
637
648
|
"nautobot.core.context_processors.settings",
|
|
638
649
|
"nautobot.core.context_processors.sso_auth",
|
|
639
650
|
],
|
|
@@ -751,12 +762,15 @@ CONSTANCE_CONFIG = {
|
|
|
751
762
|
help_text="Number of days to retain object changelog history.\nSet this to 0 to retain changes indefinitely.",
|
|
752
763
|
field_type=int,
|
|
753
764
|
),
|
|
754
|
-
"
|
|
755
|
-
default=
|
|
756
|
-
help_text=
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
765
|
+
"DEVICE_UNIQUENESS": ConstanceConfigItem(
|
|
766
|
+
default="location_tenant_name",
|
|
767
|
+
help_text=(
|
|
768
|
+
"Select how Devices are uniquely identified:\n"
|
|
769
|
+
"- 'location_tenant_name': combination of Location + Tenant + Name\n"
|
|
770
|
+
"- 'name': Device name must be globally unique\n"
|
|
771
|
+
"- 'none': No enforced uniqueness (rely on other validation rules or custom validators)"
|
|
772
|
+
),
|
|
773
|
+
field_type=str,
|
|
760
774
|
),
|
|
761
775
|
"DEPLOYMENT_ID": ConstanceConfigItem(
|
|
762
776
|
default="",
|
|
@@ -861,7 +875,7 @@ CONSTANCE_CONFIG_FIELDSETS = {
|
|
|
861
875
|
"Change Logging": ["CHANGELOG_RETENTION"],
|
|
862
876
|
"Device Connectivity": ["NETWORK_DRIVERS", "PREFER_IPV4"],
|
|
863
877
|
"Installation Metrics": ["DEPLOYMENT_ID"],
|
|
864
|
-
"Natural Keys": ["
|
|
878
|
+
"Natural Keys": ["DEVICE_UNIQUENESS", "LOCATION_NAME_AS_NATURAL_KEY"],
|
|
865
879
|
"Pagination": ["PAGINATE_COUNT", "MAX_PAGE_SIZE", "PER_PAGE_DEFAULTS"],
|
|
866
880
|
"Performance": ["JOB_CREATE_FILE_MAX_SIZE"],
|
|
867
881
|
"Rack Elevation Rendering": [
|
nautobot/core/settings.yaml
CHANGED
|
@@ -758,16 +758,22 @@ properties:
|
|
|
758
758
|
"`nautobot-server send_installation_metrics`": "../tools/nautobot-server.md#send_installation_metrics"
|
|
759
759
|
type: "string"
|
|
760
760
|
version_added: "1.6.0"
|
|
761
|
-
|
|
762
|
-
default:
|
|
761
|
+
DEVICE_UNIQUENESS:
|
|
762
|
+
default: "location_tenant_name"
|
|
763
763
|
description: >-
|
|
764
764
|
`Device` names are not guaranteed globally-unique by Nautobot but in practice they often are.
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
765
|
+
Select how Devices are uniquely identified:
|
|
766
|
+
- 'location_tenant_name': combination of Location + Tenant + Name
|
|
767
|
+
- 'name': Device name must be globally unique
|
|
768
|
+
- 'none': No enforced uniqueness (rely on other validation rules or custom validators)
|
|
769
|
+
The `DEVICE_UNIQUENESS` setting also determines which fields Nautobot treats as the natural key for a Device.
|
|
770
|
+
- If set to "location_tenant_name", the natural key is the combination of Name, Tenant, and Location.
|
|
771
|
+
- If set to "name", the natural key is the device name alone.
|
|
772
|
+
- If set to "none", Nautobot falls back to using the primary key for uniqueness.
|
|
773
|
+
environment_variable: "NAUTOBOT_DEVICE_UNIQUENESS"
|
|
768
774
|
is_constance_config: true
|
|
769
|
-
type: "
|
|
770
|
-
version_added: "
|
|
775
|
+
type: "string"
|
|
776
|
+
version_added: "3.0.0"
|
|
771
777
|
EVENT_BROKERS:
|
|
772
778
|
default: {}
|
|
773
779
|
description: >-
|
nautobot/core/tables.py
CHANGED
|
@@ -29,14 +29,12 @@ logger = logging.getLogger(__name__)
|
|
|
29
29
|
|
|
30
30
|
class BaseTable(django_tables2.Table):
|
|
31
31
|
"""
|
|
32
|
-
Default table for object lists
|
|
33
|
-
|
|
34
|
-
:param user: Personalize table display for the given user (optional). Has no effect if AnonymousUser is passed.
|
|
32
|
+
Default table for object lists.
|
|
35
33
|
"""
|
|
36
34
|
|
|
37
35
|
class Meta:
|
|
38
36
|
attrs = {
|
|
39
|
-
"class": "table table-hover table-headings",
|
|
37
|
+
"class": "table table-hover nb-table-headings",
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
def __init__(
|
|
@@ -48,6 +46,7 @@ class BaseTable(django_tables2.Table):
|
|
|
48
46
|
hide_hierarchy_ui=False,
|
|
49
47
|
order_by=None,
|
|
50
48
|
data_transform_callback=None,
|
|
49
|
+
configurable=False,
|
|
51
50
|
**kwargs,
|
|
52
51
|
):
|
|
53
52
|
"""
|
|
@@ -57,7 +56,7 @@ class BaseTable(django_tables2.Table):
|
|
|
57
56
|
*args (list, optional): Passed through to django_tables2.Table
|
|
58
57
|
table_changes_pending (bool): TODO
|
|
59
58
|
saved_view (SavedView, optional): TODO
|
|
60
|
-
user (User, optional):
|
|
59
|
+
user (User, optional): Personalize table display for the given user (optional)
|
|
61
60
|
hide_hierarchy_ui (bool): Whether to display or hide hierarchy indentation of nested objects.
|
|
62
61
|
order_by (list, optional): Field(s) to sort by
|
|
63
62
|
data_transform_callback (function, optional): A function that takes the given `data` as an input and
|
|
@@ -115,6 +114,8 @@ class BaseTable(django_tables2.Table):
|
|
|
115
114
|
# Init table
|
|
116
115
|
super().__init__(*args, order_by=order_by, **kwargs)
|
|
117
116
|
|
|
117
|
+
self.configurable = configurable
|
|
118
|
+
|
|
118
119
|
if not isinstance(self.data, TableQuerysetData):
|
|
119
120
|
# LinkedCountColumns don't work properly if the data is a list of dicts instead of a queryset,
|
|
120
121
|
# as they rely on a `queryset.annotate()` call to gather the data.
|
|
@@ -369,12 +370,17 @@ class ToggleColumn(django_tables2.CheckBoxColumn):
|
|
|
369
370
|
default = kwargs.pop("default", "")
|
|
370
371
|
visible = kwargs.pop("visible", False)
|
|
371
372
|
if "attrs" not in kwargs:
|
|
372
|
-
kwargs["attrs"] = {
|
|
373
|
+
kwargs["attrs"] = {
|
|
374
|
+
"input": {"class": "form-check-input nb-form-check-input-sm mt-2"},
|
|
375
|
+
"td": {"class": "nb-w-0"},
|
|
376
|
+
}
|
|
373
377
|
super().__init__(*args, default=default, visible=visible, **kwargs)
|
|
374
378
|
|
|
375
379
|
@property
|
|
376
380
|
def header(self):
|
|
377
|
-
return mark_safe(
|
|
381
|
+
return mark_safe(
|
|
382
|
+
'<input type="checkbox" class="toggle form-check-input nb-form-check-input-sm mt-2" title="Toggle all" />'
|
|
383
|
+
)
|
|
378
384
|
|
|
379
385
|
|
|
380
386
|
class BooleanColumn(django_tables2.Column):
|
|
@@ -391,30 +397,55 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
391
397
|
"""
|
|
392
398
|
Render edit, delete, and changelog buttons for an object.
|
|
393
399
|
|
|
394
|
-
:
|
|
395
|
-
|
|
396
|
-
|
|
400
|
+
Args:
|
|
401
|
+
model (type(Model)): Model class to use for calculating URL view names
|
|
402
|
+
prepend_template (Optional[str]): Additional template content to render in the column
|
|
403
|
+
return_url_extra (Optional[str]): String to append to the return URL (e.g. for specifying a tab)
|
|
397
404
|
"""
|
|
398
405
|
|
|
399
406
|
buttons = ("changelog", "edit", "delete")
|
|
400
|
-
attrs = {
|
|
407
|
+
attrs = {
|
|
408
|
+
"td": {"class": "d-print-none text-end text-nowrap nb-actions nb-w-0"},
|
|
409
|
+
"tf": {"class": "nb-w-0"},
|
|
410
|
+
"th": {"class": "nb-actionable nb-w-0"},
|
|
411
|
+
}
|
|
401
412
|
# Note that braces are escaped to allow for string formatting prior to template rendering
|
|
402
|
-
template_code = """
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
<
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
413
|
+
template_code = """\
|
|
414
|
+
{{% if record.present_in_database %}}
|
|
415
|
+
<div class="dropdown">
|
|
416
|
+
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
417
|
+
<span class="mdi mdi-dots-vertical" aria-hidden="true"></span>
|
|
418
|
+
<span class="visually-hidden">Toggle Dropdown</span>
|
|
419
|
+
</button>
|
|
420
|
+
<ul class="dropdown-menu dropdown-menu-end">
|
|
421
|
+
{prepend_template}
|
|
422
|
+
{{% if "changelog" in buttons %}}
|
|
423
|
+
<li>
|
|
424
|
+
<a href="{{% url '{changelog_route}' {pk_field}=record.{pk_field} %}}" class="dropdown-item">
|
|
425
|
+
<span class="mdi mdi-history" aria-hidden="true"></span>
|
|
426
|
+
Change Log
|
|
427
|
+
</a>
|
|
428
|
+
</li>
|
|
429
|
+
{{% endif %}}
|
|
430
|
+
{{% if "edit" in buttons and perms.{app_label}.change_{model_name} %}}
|
|
431
|
+
<li>
|
|
432
|
+
<a href="{{% url '{edit_route}' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="dropdown-item text-warning">
|
|
433
|
+
<span class="mdi mdi-pencil" aria-hidden="true"></span>
|
|
434
|
+
Edit
|
|
435
|
+
</a>
|
|
436
|
+
</li>
|
|
437
|
+
{{% endif %}}
|
|
438
|
+
{{% if "delete" in buttons and perms.{app_label}.delete_{model_name} %}}
|
|
439
|
+
<li>
|
|
440
|
+
<a href="{{% url '{delete_route}' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="dropdown-item text-danger">
|
|
441
|
+
<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span>
|
|
442
|
+
Delete
|
|
443
|
+
</a>
|
|
444
|
+
</li>
|
|
445
|
+
{{% endif %}}
|
|
446
|
+
</ul>
|
|
447
|
+
</div>
|
|
448
|
+
{{% endif %}}
|
|
418
449
|
"""
|
|
419
450
|
|
|
420
451
|
def __init__(
|
|
@@ -423,15 +454,10 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
423
454
|
*args,
|
|
424
455
|
pk_field="pk",
|
|
425
456
|
buttons=None,
|
|
426
|
-
prepend_template=
|
|
457
|
+
prepend_template="",
|
|
427
458
|
return_url_extra="",
|
|
428
459
|
**kwargs,
|
|
429
460
|
):
|
|
430
|
-
if prepend_template:
|
|
431
|
-
prepend_template = prepend_template.replace("{", "{{")
|
|
432
|
-
prepend_template = prepend_template.replace("}", "}}")
|
|
433
|
-
self.template_code = prepend_template + self.template_code
|
|
434
|
-
|
|
435
461
|
app_label = model._meta.app_label
|
|
436
462
|
changelog_route = get_route_for_model(model, "changelog")
|
|
437
463
|
edit_route = get_route_for_model(model, "edit")
|
|
@@ -445,6 +471,7 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
445
471
|
delete_route=delete_route,
|
|
446
472
|
pk_field=pk_field,
|
|
447
473
|
buttons=buttons,
|
|
474
|
+
prepend_template=prepend_template,
|
|
448
475
|
)
|
|
449
476
|
|
|
450
477
|
super().__init__(template_code=template_code, *args, **kwargs)
|
|
@@ -460,6 +487,49 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
460
487
|
return ""
|
|
461
488
|
|
|
462
489
|
|
|
490
|
+
class ApprovalButtonsColumn(django_tables2.TemplateColumn):
|
|
491
|
+
"""
|
|
492
|
+
Render detail, changelog, approve, deny, and comment buttons for an approval workflow stage.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
model (type(Model)): Model class to use for calculating URL view names
|
|
496
|
+
return_url_extra (Optional[str]): String to append to the return URL (e.g. for specifying a tab)
|
|
497
|
+
"""
|
|
498
|
+
|
|
499
|
+
buttons = ("detail", "changelog", "approve", "deny")
|
|
500
|
+
attrs = {"td": {"class": "d-print-none text-end text-nowrap"}}
|
|
501
|
+
template_name = "extras/inc/approval_buttons_column.html"
|
|
502
|
+
|
|
503
|
+
def __init__(
|
|
504
|
+
self,
|
|
505
|
+
model,
|
|
506
|
+
*args,
|
|
507
|
+
buttons=None,
|
|
508
|
+
return_url_extra="",
|
|
509
|
+
**kwargs,
|
|
510
|
+
):
|
|
511
|
+
app_label = model._meta.app_label
|
|
512
|
+
changelog_route = get_route_for_model(model, "changelog")
|
|
513
|
+
approval_route = "extras:approvalworkflowstage_approve"
|
|
514
|
+
deny_route = "extras:approvalworkflowstage_deny"
|
|
515
|
+
|
|
516
|
+
super().__init__(template_name=self.template_name, *args, **kwargs)
|
|
517
|
+
|
|
518
|
+
self.extra_context.update(
|
|
519
|
+
{
|
|
520
|
+
"buttons": buttons or self.buttons,
|
|
521
|
+
"return_url_extra": return_url_extra,
|
|
522
|
+
"changelog_route": changelog_route,
|
|
523
|
+
"approval_route": approval_route,
|
|
524
|
+
"deny_route": deny_route,
|
|
525
|
+
"have_permission": f"perms.{app_label}.change_{model._meta.model_name}",
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
def header(self): # pylint: disable=invalid-overridden-method
|
|
530
|
+
return ""
|
|
531
|
+
|
|
532
|
+
|
|
463
533
|
class ChoiceFieldColumn(django_tables2.Column):
|
|
464
534
|
"""
|
|
465
535
|
Render a ChoiceField value inside a <span> indicating a particular CSS class. This is useful for displaying colored
|
|
@@ -471,7 +541,7 @@ class ChoiceFieldColumn(django_tables2.Column):
|
|
|
471
541
|
name = bound_column.name
|
|
472
542
|
css_class = getattr(record, f"get_{name}_class")()
|
|
473
543
|
label = getattr(record, f"get_{name}_display")()
|
|
474
|
-
return format_html('<span class="
|
|
544
|
+
return format_html('<span class="badge bg-{}">{}</span>', css_class, label)
|
|
475
545
|
return self.default
|
|
476
546
|
|
|
477
547
|
|
|
@@ -481,7 +551,7 @@ class ColorColumn(django_tables2.Column):
|
|
|
481
551
|
"""
|
|
482
552
|
|
|
483
553
|
def render(self, value):
|
|
484
|
-
return format_html('<span class="label color-block" style="background-color: #{}"> </span>', value)
|
|
554
|
+
return format_html('<span class="label nb-color-block" style="background-color: #{}"> </span>', value)
|
|
485
555
|
|
|
486
556
|
|
|
487
557
|
class ColoredLabelColumn(django_tables2.TemplateColumn):
|
|
@@ -491,7 +561,7 @@ class ColoredLabelColumn(django_tables2.TemplateColumn):
|
|
|
491
561
|
|
|
492
562
|
template_code = """
|
|
493
563
|
{% load helpers %}
|
|
494
|
-
{% if value %}<
|
|
564
|
+
{% if value %}<span class="badge" style="color: {{ value.color|fgcolor }}; background-color: #{{ value.color }}">{{ value }}</span>{% else %}—{% endif %}
|
|
495
565
|
"""
|
|
496
566
|
|
|
497
567
|
def __init__(self, *args, **kwargs):
|
|
@@ -589,11 +659,11 @@ class LinkedCountColumn(django_tables2.Column):
|
|
|
589
659
|
{k: (getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE) for k, v in self.url_params.items()}
|
|
590
660
|
)
|
|
591
661
|
if value > 1:
|
|
592
|
-
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
662
|
+
return format_html('<a href="{}" class="badge bg-primary">{}</a>', url, value)
|
|
593
663
|
if related_record is not None:
|
|
594
664
|
return helpers.hyperlinked_object(related_record, self.display_field)
|
|
595
665
|
if value == 1:
|
|
596
|
-
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
666
|
+
return format_html('<a href="{}" class="badge bg-primary">{}</a>', url, value)
|
|
597
667
|
return helpers.placeholder(value)
|
|
598
668
|
|
|
599
669
|
|
|
@@ -606,7 +676,7 @@ class TagColumn(django_tables2.TemplateColumn):
|
|
|
606
676
|
{% for tag in value.all %}
|
|
607
677
|
{% include 'utilities/templatetags/tag.html' %}
|
|
608
678
|
{% empty %}
|
|
609
|
-
<span class="text-
|
|
679
|
+
<span class="text-secondary">—</span>
|
|
610
680
|
{% endfor %}
|
|
611
681
|
"""
|
|
612
682
|
|
|
@@ -622,9 +692,9 @@ class ContentTypesColumn(django_tables2.ManyToManyColumn):
|
|
|
622
692
|
performance hit to querysets for table views. If this becomes an issue,
|
|
623
693
|
set `sort_items=False`.
|
|
624
694
|
|
|
625
|
-
:
|
|
626
|
-
|
|
627
|
-
Number of words at which to truncate, or `None` to disable.
|
|
695
|
+
Args:
|
|
696
|
+
sort_items (bool): Whether to sort by `(app_label, name)`.
|
|
697
|
+
truncate_words (Optional[int]): Number of words at which to truncate, or `None` to disable.
|
|
628
698
|
"""
|
|
629
699
|
|
|
630
700
|
def __init__(self, sort_items=True, truncate_words=None, *args, **kwargs):
|
|
@@ -683,9 +753,9 @@ class CustomFieldColumn(django_tables2.Column):
|
|
|
683
753
|
if self.customfield.type == choices.CustomFieldTypeChoices.TYPE_BOOLEAN:
|
|
684
754
|
template = helpers.render_boolean(value)
|
|
685
755
|
elif self.customfield.type == choices.CustomFieldTypeChoices.TYPE_MULTISELECT:
|
|
686
|
-
template = format_html_join(" ", '<span class="
|
|
756
|
+
template = format_html_join(" ", '<span class="badge bg-secondary">{}</span>', ((v,) for v in value))
|
|
687
757
|
elif self.customfield.type == choices.CustomFieldTypeChoices.TYPE_SELECT:
|
|
688
|
-
template = format_html('<span class="
|
|
758
|
+
template = format_html('<span class="badge bg-secondary">{}</span>', value)
|
|
689
759
|
elif self.customfield.type == choices.CustomFieldTypeChoices.TYPE_URL:
|
|
690
760
|
template = format_html('<a href="{}">{}</a>', value, value)
|
|
691
761
|
else:
|
nautobot/core/templates/403.html
CHANGED
nautobot/core/templates/404.html
CHANGED
nautobot/core/templates/40x.html
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
{% load helpers %}
|
|
3
3
|
|
|
4
4
|
{% block content %}
|
|
5
|
-
<div class="row" style="margin-top:
|
|
6
|
-
<div class="col-sm-
|
|
7
|
-
<div class="
|
|
8
|
-
<div class="
|
|
9
|
-
<strong>{% block icon %}{% endblock %}
|
|
5
|
+
<div class="row justify-content-center" style="margin-top: 9.375rem;">
|
|
6
|
+
<div class="col-sm-12 col-md-9 col-lg-7 nb-lg-max-width">
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div class="card-header">
|
|
9
|
+
<strong class="hstack gap-4">{% block icon %}{% endblock %}{% block title %}{% endblock %}</strong>
|
|
10
10
|
</div>
|
|
11
|
-
<div class="
|
|
11
|
+
<div class="card-body">
|
|
12
12
|
<p>
|
|
13
13
|
{% block message %}{% endblock %}
|
|
14
14
|
</p>
|
|
15
15
|
{% support_message %}
|
|
16
16
|
</div>
|
|
17
|
-
<div class="
|
|
18
|
-
<a href="{% url 'home' %}" class="btn btn-
|
|
17
|
+
<div class="card-footer bg-body text-center">
|
|
18
|
+
<a href="{% url 'home' %}" class="btn btn-primary">Home Page</a>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
nautobot/core/templates/500.html
CHANGED
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
{% block title %}Server Error{% endblock %}
|
|
5
5
|
|
|
6
6
|
{% block content %}
|
|
7
|
-
<div class="row" style="margin-top:
|
|
8
|
-
<div class="col-sm-
|
|
9
|
-
<div class="
|
|
10
|
-
<div class="
|
|
11
|
-
<strong><
|
|
7
|
+
<div class="row justify-content-center" style="margin-top: 9.375rem;">
|
|
8
|
+
<div class="col-sm-12 col-md-9 col-lg-7 nb-lg-max-width">
|
|
9
|
+
<div class="card">
|
|
10
|
+
<div class="card-header">
|
|
11
|
+
<strong class="hstack gap-4"><span class="mdi mdi-alert"></span>Server Error</strong>
|
|
12
12
|
</div>
|
|
13
|
-
<div class="
|
|
13
|
+
<div class="card-body">
|
|
14
14
|
{% block message %}
|
|
15
15
|
<p>
|
|
16
16
|
There was a problem with your request. Please contact an administrator.
|
|
17
17
|
</p>
|
|
18
18
|
{% endblock %}
|
|
19
|
-
<hr />
|
|
19
|
+
<hr class="border-top" />
|
|
20
20
|
<p>
|
|
21
21
|
The complete exception is provided below:
|
|
22
22
|
</p>
|
|
@@ -28,10 +28,10 @@ Nautobot version: {{ nautobot_version }}
|
|
|
28
28
|
</pre>
|
|
29
29
|
{% support_message %}
|
|
30
30
|
</div>
|
|
31
|
-
<div class="
|
|
32
|
-
<a href="{% url 'home' %}" class="btn btn-
|
|
31
|
+
<div class="card-footer bg-body text-center">
|
|
32
|
+
<a href="{% url 'home' %}" class="btn btn-primary">Home Page</a>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
|
-
{% endblock %}
|
|
37
|
+
{% endblock %}
|
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
{% extends 'base.html' %}
|
|
2
2
|
{% load helpers %}
|
|
3
3
|
{% load registry %}
|
|
4
|
+
{% load ui_framework %}
|
|
5
|
+
|
|
6
|
+
{% block breadcrumbs_wrapper %}{% render_breadcrumbs %}{% endblock %}
|
|
4
7
|
|
|
5
8
|
{% block header %}
|
|
6
9
|
{{ block.super }}
|
|
7
10
|
{% if new_release %}
|
|
8
11
|
{# new_release is set only if the current user is a superuser or staff member #}
|
|
9
12
|
<div class="alert alert-info text-center" role="alert">
|
|
10
|
-
<
|
|
13
|
+
<span class="mdi mdi-information-outline"></span>
|
|
11
14
|
A new release is available: <a href="{{ new_release.url }}">Nautobot v{{ new_release.version }}</a> |
|
|
12
15
|
<a href="https://docs.nautobot.com/projects/core/en/v{{ new_release.version }}/installation/upgrading/">Upgrade instructions</a>
|
|
13
16
|
</div>
|
|
14
17
|
{% endif %}
|
|
15
18
|
{% endblock %}
|
|
16
19
|
|
|
17
|
-
|
|
18
20
|
{% block content %}
|
|
19
|
-
<h1>About Nautobot</h1>
|
|
20
21
|
<div class="row">
|
|
21
|
-
<div class="col-
|
|
22
|
-
<div class="
|
|
23
|
-
<div class="
|
|
22
|
+
<div class="col-lg-6">
|
|
23
|
+
<div class="card">
|
|
24
|
+
<div class="card-header">
|
|
24
25
|
<strong>About</strong>
|
|
25
26
|
</div>
|
|
26
|
-
<div class="
|
|
27
|
+
<div class="card-body">
|
|
27
28
|
<a href="https://networktocode.com/nautobot/">Nautobot</a> is a product of <a href="https://networktocode.com/">Network to Code</a>. Nautobot is a Network Source of Truth and Network Automation Platform. Nautobot has an extensive ecosystem of solutions that can be installed to provide and power Network Automation feature sets. Please check the <a href="{% url 'apps:apps_marketplace' %}">App Marketplace</a> to learn more.
|
|
28
29
|
</div>
|
|
29
30
|
</div>
|
|
30
31
|
</div>
|
|
31
|
-
<div class="col-
|
|
32
|
-
<div class="
|
|
33
|
-
<div class="
|
|
32
|
+
<div class="col-lg-6">
|
|
33
|
+
<div class="card">
|
|
34
|
+
<div class="card-header">
|
|
34
35
|
<strong>Support</strong>
|
|
35
36
|
</div>
|
|
36
|
-
<table class="table table-hover
|
|
37
|
+
<table class="table table-hover card-body attr-table">
|
|
37
38
|
<tr>
|
|
38
39
|
<td>Support Contract Status</td>
|
|
39
40
|
<td>{{ support_contract_active | render_boolean }}</td>
|
|
@@ -64,4 +65,4 @@
|
|
|
64
65
|
</div>
|
|
65
66
|
</div>
|
|
66
67
|
</div>
|
|
67
|
-
{% endblock %}
|
|
68
|
+
{% endblock %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% load i18n bootstrapped_goodies_tags %}
|
|
2
|
-
<div class="actions
|
|
2
|
+
<div class="actions mb-10 d-flex justify-content-center">
|
|
3
3
|
{% for field in action_form %}{% if field.label %}<span style="vertical-align:sub">{{ field.label }}</span> {% endif %}{% dab_field_rendering field %}{% endfor %}
|
|
4
4
|
<button type="submit" class="btn btn-sm btn-primary" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
|
|
5
5
|
</div>
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
{% if not is_popup %}
|
|
7
7
|
{% block breadcrumbs %}
|
|
8
8
|
<ol class="breadcrumb">
|
|
9
|
-
<li><a href="{% url 'admin:index' %}">{% trans 'Admin Home' %}</a></li>
|
|
9
|
+
<li class="breadcrumb-item"><a href="{% url 'admin:index' %}">{% trans 'Admin Home' %}</a></li>
|
|
10
10
|
{% for app in app_list %}
|
|
11
|
-
<li>{{ app.name }}</li>
|
|
11
|
+
<li {% if forloop.last %}class="breadcrumb-item active" aria-current="page"{% else %}class="breadcrumb-item"{% endif %}>{{ app.name }}</li>
|
|
12
12
|
{% endfor %}
|
|
13
13
|
</ol>
|
|
14
14
|
{% endblock %}
|
|
15
15
|
{% endif %}
|
|
16
16
|
|
|
17
|
-
{% block sidebar %}{% endblock %}
|
|
17
|
+
{% block sidebar %}{% endblock %}
|