nautobot 3.0.0a2__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 +0 -2
- nautobot/apps/filters.py +7 -9
- nautobot/apps/models.py +2 -2
- nautobot/apps/ui.py +9 -1
- nautobot/circuits/filters.py +3 -2
- nautobot/circuits/navigation.py +3 -2
- nautobot/circuits/templates/circuits/circuit.html +1 -1
- nautobot/circuits/templates/circuits/circuit_create.html +3 -3
- nautobot/circuits/templates/circuits/circuittermination.html +1 -1
- nautobot/circuits/templates/circuits/circuittermination_create.html +9 -24
- nautobot/circuits/templates/circuits/circuittype.html +1 -1
- nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +6 -6
- nautobot/circuits/templates/circuits/inc/speed_widget.html +12 -12
- nautobot/circuits/templates/circuits/providernetwork.html +1 -1
- nautobot/circuits/tests/integration/test_circuit.py +10 -13
- nautobot/cloud/filters.py +1 -1
- nautobot/cloud/navigation.py +3 -2
- nautobot/core/api/schema.py +1 -1
- nautobot/core/api/serializers.py +6 -1
- nautobot/core/api/urls.py +1 -0
- nautobot/core/api/views.py +8 -0
- nautobot/core/apps/__init__.py +11 -10
- nautobot/core/celery/__init__.py +3 -5
- nautobot/core/checks.py +46 -0
- nautobot/core/cli/bootstrap_v3_to_v5.py +70 -1
- nautobot/core/cli/migrate_deprecated_templates.py +200 -0
- nautobot/core/constants.py +3 -0
- nautobot/core/context_processors.py +9 -1
- nautobot/core/forms/forms.py +1 -1
- nautobot/core/jobs/__init__.py +6 -3
- nautobot/core/jobs/groups.py +31 -1
- nautobot/core/management/commands/generate_test_data.py +28 -9
- nautobot/core/models/generics.py +9 -1
- nautobot/core/models/tree_queries.py +10 -5
- nautobot/core/settings.py +18 -12
- nautobot/core/settings.yaml +13 -7
- nautobot/core/signals.py +12 -1
- nautobot/core/tables.py +13 -6
- nautobot/core/templates/40x.html +1 -1
- nautobot/core/templates/500.html +2 -2
- nautobot/core/templates/admin/config/config.html +12 -12
- nautobot/core/templates/admin/index.html +3 -3
- nautobot/core/templates/buttons/export.html +1 -1
- nautobot/core/templates/components/button/dropdown.html +5 -3
- nautobot/core/templates/components/panel/body_wrapper_generic_table.html +1 -1
- nautobot/core/templates/components/panel/panel.html +3 -3
- nautobot/core/templates/components/tab/content_wrapper.html +2 -3
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +1 -1
- nautobot/core/templates/echarts/echarts.html +1 -1
- nautobot/core/templates/generic/object_bulk_add_component.html +2 -1
- nautobot/core/templates/generic/object_bulk_create.html +4 -3
- nautobot/core/templates/generic/object_bulk_destroy.html +3 -3
- nautobot/core/templates/generic/object_bulk_remove.html +2 -2
- nautobot/core/templates/generic/object_bulk_update.html +5 -4
- nautobot/core/templates/generic/object_create.html +5 -4
- nautobot/core/templates/generic/object_import.html +2 -1
- nautobot/core/templates/generic/object_list.html +12 -4
- nautobot/core/templates/generic/object_notes.html +5 -3
- nautobot/core/templates/generic/object_retrieve.html +2 -3
- nautobot/core/templates/graphene/graphiql.html +7 -7
- nautobot/core/templates/home.html +1 -1
- nautobot/core/templates/import_success.html +2 -1
- nautobot/core/templates/inc/computed_fields/panel_data.html +1 -1
- nautobot/core/templates/inc/created_updated.html +7 -3
- nautobot/core/templates/inc/custom_fields/panel_data.html +1 -1
- nautobot/core/templates/inc/form_static_field.html +6 -0
- nautobot/core/templates/inc/header.html +1 -1
- nautobot/core/templates/inc/image_attachments.html +2 -1
- nautobot/core/templates/inc/nav_menu.html +2 -1
- nautobot/core/templates/inc/search_panel.html +4 -4
- nautobot/core/templates/login.html +4 -2
- nautobot/core/templates/nautobot_config.py.j2 +6 -5
- nautobot/core/templates/redoc_ui.html +7 -0
- nautobot/core/templates/search.html +1 -1
- nautobot/core/templates/swagger_ui.html +17 -3
- nautobot/core/templates/system_jobs/import_objects.html +1 -2
- nautobot/core/templates/utilities/confirmation_form.html +2 -2
- nautobot/core/templates/utilities/obj_table.html +10 -2
- nautobot/core/templates/utilities/render_field.html +7 -7
- nautobot/core/templates/utilities/render_jinja2.html +2 -2
- nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +4 -4
- nautobot/core/templates/utilities/theme_preview.html +16 -3
- nautobot/core/templates/widgets/selectwithdisabled_option.html +3 -1
- nautobot/core/templatetags/helpers.py +52 -6
- nautobot/core/testing/api.py +68 -9
- nautobot/core/testing/filters.py +0 -23
- nautobot/core/testing/integration.py +23 -10
- nautobot/core/testing/mixins.py +2 -0
- nautobot/core/testing/views.py +4 -0
- nautobot/core/tests/integration/test_app_home.py +34 -30
- nautobot/core/tests/integration/test_app_navbar.py +3 -0
- nautobot/core/tests/nautobot_config_without_example_apps.py +4 -0
- nautobot/core/tests/runner.py +9 -1
- nautobot/core/tests/test_api.py +5 -3
- nautobot/core/tests/test_breadcrumbs.py +6 -7
- nautobot/core/tests/test_checks.py +28 -0
- nautobot/core/tests/test_cli.py +40 -0
- nautobot/core/tests/test_config.py +2 -1
- nautobot/core/tests/test_forms.py +55 -13
- nautobot/core/tests/test_jobs.py +75 -1
- nautobot/core/tests/test_nautobot_server.py +2 -0
- nautobot/core/tests/test_navigations.py +76 -1
- nautobot/core/tests/test_patch_social_django.py +42 -0
- nautobot/core/tests/test_tables.py +3 -1
- nautobot/core/tests/test_templatetags_helpers.py +53 -13
- nautobot/core/tests/test_templatetags_ui_framework.py +4 -4
- nautobot/core/tests/test_tree_queries.py +14 -1
- nautobot/core/tests/test_ui.py +1 -1
- nautobot/core/tests/test_utils.py +31 -4
- nautobot/core/tests/test_views.py +159 -31
- nautobot/core/ui/breadcrumbs.py +2 -12
- nautobot/core/ui/choices.py +142 -10
- nautobot/core/ui/constants.py +76 -12
- nautobot/core/ui/object_detail.py +92 -12
- nautobot/core/urls.py +12 -1
- nautobot/core/utils/cache.py +2 -1
- nautobot/core/utils/filtering.py +17 -17
- nautobot/core/utils/lookup.py +3 -8
- nautobot/core/utils/module_loading.py +21 -0
- nautobot/core/utils/patch_social_django.py +128 -0
- nautobot/core/views/__init__.py +38 -1
- nautobot/core/views/generic.py +3 -3
- nautobot/core/views/mixins.py +15 -3
- nautobot/core/views/renderers.py +2 -0
- nautobot/core/views/viewsets.py +2 -1
- nautobot/data_validation/apps.py +1 -5
- nautobot/data_validation/custom_validators.py +4 -4
- nautobot/data_validation/filters.py +1 -1
- nautobot/data_validation/forms.py +40 -0
- nautobot/data_validation/migrations/0001_initial.py +0 -7
- nautobot/data_validation/migrations/0002_data_migration_from_app.py +0 -12
- nautobot/data_validation/models.py +16 -7
- nautobot/data_validation/navigation.py +8 -1
- nautobot/data_validation/tables.py +12 -5
- nautobot/data_validation/templates/data_validation/datacompliance_tab.html +1 -0
- nautobot/data_validation/templates/data_validation/device_constraints.html +61 -0
- nautobot/data_validation/tests/__init__.py +2 -2
- nautobot/data_validation/tests/migrations/test_migrations.py +83 -3
- nautobot/data_validation/tests/test_data_compliance_rules.py +12 -7
- nautobot/data_validation/tests/test_filters.py +8 -6
- nautobot/data_validation/tests/test_models.py +15 -0
- nautobot/data_validation/tests/test_views.py +190 -32
- nautobot/data_validation/urls.py +2 -5
- nautobot/data_validation/views.py +73 -40
- nautobot/dcim/api/serializers.py +0 -13
- 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} +2 -35
- nautobot/dcim/forms.py +1 -1
- 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/device_components.py +81 -68
- nautobot/dcim/models/devices.py +13 -16
- nautobot/dcim/navigation.py +7 -6
- nautobot/dcim/tables/devices.py +3 -0
- nautobot/dcim/tables/template_code.py +14 -14
- nautobot/dcim/templates/dcim/cable.html +2 -61
- nautobot/dcim/templates/dcim/cable_connect.html +28 -112
- nautobot/dcim/templates/dcim/cable_edit.html +2 -5
- nautobot/dcim/templates/dcim/cable_retrieve.html +61 -0
- nautobot/dcim/templates/dcim/cable_trace.html +1 -3
- nautobot/dcim/templates/dcim/cable_update.html +5 -0
- nautobot/dcim/templates/dcim/consoleport.html +6 -5
- nautobot/dcim/templates/dcim/consoleserverport.html +6 -5
- nautobot/dcim/templates/dcim/device/config.html +2 -2
- nautobot/dcim/templates/dcim/device/consoleports.html +1 -1
- nautobot/dcim/templates/dcim/device/consoleserverports.html +1 -1
- nautobot/dcim/templates/dcim/device/devicebays.html +1 -1
- nautobot/dcim/templates/dcim/device/frontports.html +1 -1
- nautobot/dcim/templates/dcim/device/interfaces.html +1 -1
- nautobot/dcim/templates/dcim/device/inventory.html +1 -1
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +1 -1
- nautobot/dcim/templates/dcim/device/modulebays.html +1 -1
- nautobot/dcim/templates/dcim/device/poweroutlets.html +1 -1
- nautobot/dcim/templates/dcim/device/powerports.html +1 -1
- nautobot/dcim/templates/dcim/device/rearports.html +1 -1
- nautobot/dcim/templates/dcim/device/status.html +8 -8
- nautobot/dcim/templates/dcim/device/wireless.html +1 -1
- nautobot/dcim/templates/dcim/device.html +1 -1
- nautobot/dcim/templates/dcim/device_component_add.html +2 -2
- nautobot/dcim/templates/dcim/device_create.html +5 -3
- nautobot/dcim/templates/dcim/device_interface_delete.html +1 -1
- nautobot/dcim/templates/dcim/device_list.html +73 -10
- nautobot/dcim/templates/dcim/devicebay_populate.html +2 -2
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/devicetype_component_add.html +2 -2
- nautobot/dcim/templates/dcim/footer_convert_to_contact_or_team_record.html +14 -0
- nautobot/dcim/templates/dcim/frontport.html +9 -8
- nautobot/dcim/templates/dcim/inc/edit_form_softwareversion_js.html +2 -2
- nautobot/dcim/templates/dcim/interface.html +26 -6
- nautobot/dcim/templates/dcim/interface_bulk_delete.html +1 -1
- nautobot/dcim/templates/dcim/inventoryitem_add.html +3 -1
- nautobot/dcim/templates/dcim/inventoryitem_bulk_delete.html +1 -1
- nautobot/dcim/templates/dcim/inventoryitem_edit.html +3 -1
- nautobot/dcim/templates/dcim/location_retrieve.html +1 -242
- nautobot/dcim/templates/dcim/module/base.html +49 -9
- nautobot/dcim/templates/dcim/module_list.html +57 -8
- nautobot/dcim/templates/dcim/modulefamily_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +49 -9
- nautobot/dcim/templates/dcim/platform_create.html +1 -1
- nautobot/dcim/templates/dcim/powerfeed.html +1 -1
- nautobot/dcim/templates/dcim/powerpanel.html +1 -1
- nautobot/dcim/templates/dcim/powerport.html +5 -4
- nautobot/dcim/templates/dcim/rack_elevation_list.html +16 -4
- nautobot/dcim/templates/dcim/rack_retrieve.html +33 -15
- nautobot/dcim/templates/dcim/rearport.html +7 -6
- nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_add_member.html +16 -14
- nautobot/dcim/templates/dcim/virtualchassis_update.html +14 -6
- nautobot/dcim/tests/integration/test_controller.py +1 -0
- nautobot/dcim/tests/test_api.py +8 -0
- nautobot/dcim/tests/test_custom_validators.py +229 -0
- nautobot/dcim/tests/test_filters.py +12 -6
- nautobot/dcim/tests/test_models.py +63 -4
- nautobot/dcim/tests/test_views.py +63 -22
- nautobot/dcim/urls.py +64 -21
- nautobot/dcim/utils.py +3 -3
- nautobot/dcim/views.py +547 -273
- nautobot/extras/api/views.py +9 -1
- nautobot/extras/choices.py +2 -13
- nautobot/extras/{filters/mixins.py → filter_mixins.py} +1 -1
- nautobot/extras/{filters/customfields.py → filter_mixins_customfields.py} +42 -6
- nautobot/extras/{filters/__init__.py → filters.py} +14 -46
- nautobot/extras/forms/forms.py +5 -13
- nautobot/extras/forms/mixins.py +0 -41
- nautobot/extras/management/__init__.py +9 -0
- nautobot/extras/migrations/0127_approval_workflow_models.py +6 -6
- 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 +1 -2
- nautobot/extras/models/approvals.py +22 -13
- nautobot/extras/models/contacts.py +2 -0
- nautobot/extras/models/groups.py +44 -5
- nautobot/extras/models/jobs.py +59 -1
- nautobot/extras/models/mixins.py +28 -0
- nautobot/extras/models/models.py +13 -0
- nautobot/extras/models/secrets.py +1 -0
- nautobot/extras/models/statuses.py +0 -15
- nautobot/extras/navigation.py +13 -9
- nautobot/extras/plugins/__init__.py +33 -55
- nautobot/extras/plugins/tables.py +3 -3
- nautobot/extras/plugins/urls.py +2 -21
- nautobot/extras/plugins/utils.py +1 -33
- nautobot/extras/plugins/views.py +0 -4
- nautobot/extras/signals.py +20 -19
- nautobot/extras/tables.py +52 -68
- nautobot/extras/templates/extras/approval_dashboard.html +7 -5
- nautobot/extras/templates/extras/approvalworkflowdefinition_update.html +4 -2
- nautobot/extras/templates/extras/approvalworkflowstage_retrieve.html +20 -12
- nautobot/extras/templates/extras/computedfield.html +1 -1
- nautobot/extras/templates/extras/configcontext.html +1 -1
- nautobot/extras/templates/extras/configcontextschema_validation.html +2 -2
- nautobot/extras/templates/extras/customfield.html +1 -1
- nautobot/extras/templates/extras/dynamicgroup_retrieve.html +11 -5
- nautobot/extras/templates/extras/dynamicgroup_update.html +1 -1
- nautobot/extras/templates/extras/gitrepository_result.html +0 -2
- nautobot/extras/templates/extras/graphqlquery_retrieve.html +1 -96
- nautobot/extras/templates/extras/inc/approval_buttons_column.html +20 -6
- nautobot/extras/templates/extras/inc/bulk_edit_overridable_field.html +8 -7
- nautobot/extras/templates/extras/inc/configcontext_format.html +10 -3
- nautobot/extras/templates/extras/inc/graphqlquery_execute.html +71 -0
- nautobot/extras/templates/extras/inc/job_tiles.html +15 -3
- nautobot/extras/templates/extras/inc/json_format.html +10 -3
- nautobot/extras/templates/extras/inc/overridable_field.html +13 -12
- nautobot/extras/templates/extras/job.html +29 -12
- nautobot/extras/templates/extras/job_bulk_edit.html +18 -0
- nautobot/extras/templates/extras/job_edit.html +52 -46
- nautobot/extras/templates/extras/job_list.html +29 -25
- nautobot/extras/templates/extras/marketplace.html +5 -9
- nautobot/extras/templates/extras/object_configcontext.html +1 -1
- nautobot/extras/templates/extras/object_dynamicgroups.html +2 -2
- nautobot/extras/templates/extras/objectchange_retrieve.html +19 -37
- nautobot/extras/templates/extras/plugin_detail.html +26 -21
- nautobot/extras/templates/extras/plugins_list.html +16 -26
- nautobot/extras/templates/extras/role_retrieve.html +64 -0
- nautobot/extras/templates/extras/scheduledjob.html +4 -2
- nautobot/extras/templates/extras/secretsgroup.html +1 -1
- nautobot/extras/templates/extras/tag.html +1 -1
- 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_configcontextschema.py +27 -26
- nautobot/extras/tests/integration/test_customfields.py +8 -7
- nautobot/extras/tests/integration/test_dynamicgroups.py +5 -1
- nautobot/extras/tests/integration/test_plugin_banner.py +3 -0
- nautobot/extras/tests/integration/test_plugins.py +18 -6
- nautobot/extras/tests/test_api.py +27 -18
- nautobot/extras/tests/test_approvals.py +38 -38
- nautobot/extras/tests/test_changelog.py +35 -3
- nautobot/extras/tests/test_customfields.py +22 -13
- nautobot/extras/tests/test_customfields_filters.py +479 -0
- nautobot/extras/tests/test_dynamicgroups.py +39 -1
- nautobot/extras/tests/test_filters.py +21 -19
- nautobot/extras/tests/test_forms.py +18 -21
- nautobot/extras/tests/test_jobs.py +25 -4
- nautobot/extras/tests/test_migrations.py +1 -0
- nautobot/extras/tests/test_models.py +13 -31
- nautobot/extras/tests/test_plugins.py +36 -10
- nautobot/extras/tests/test_views.py +31 -30
- nautobot/extras/views.py +81 -19
- nautobot/ipam/factory.py +7 -0
- nautobot/ipam/filter_mixins.py +38 -0
- nautobot/ipam/filters.py +27 -38
- 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 -2
- nautobot/ipam/signals.py +71 -0
- nautobot/ipam/tables.py +13 -6
- nautobot/ipam/templates/ipam/inc/toggle_available.html +10 -10
- nautobot/ipam/templates/ipam/inc/vlangroup_header.html +1 -0
- nautobot/ipam/templates/ipam/ipaddress.html +14 -0
- nautobot/ipam/templates/ipam/ipaddress_merge.html +3 -3
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +1 -0
- nautobot/ipam/templates/ipam/namespace_update.html +15 -0
- nautobot/ipam/templates/ipam/prefix_delete.html +1 -1
- nautobot/ipam/templates/ipam/prefix_list.html +14 -13
- nautobot/ipam/templates/ipam/service.html +1 -1
- nautobot/ipam/templates/ipam/vlan.html +1 -1
- nautobot/ipam/templates/ipam/vlan_interfaces.html +1 -1
- nautobot/ipam/templates/ipam/vlan_vminterfaces.html +1 -1
- nautobot/ipam/tests/migration/test_migrations.py +89 -0
- nautobot/ipam/tests/test_api.py +13 -6
- nautobot/ipam/tests/test_filters.py +10 -0
- nautobot/ipam/tests/test_forms.py +1 -1
- nautobot/ipam/tests/test_models.py +43 -1
- nautobot/ipam/tests/test_tables.py +1 -2
- nautobot/ipam/tests/test_utils.py +1 -1
- nautobot/ipam/tests/test_views.py +13 -14
- nautobot/ipam/ui.py +0 -17
- nautobot/ipam/utils/migrations.py +16 -2
- nautobot/ipam/utils/testing.py +9 -3
- nautobot/ipam/views.py +46 -6
- nautobot/project-static/dist/css/nautobot.css +1 -1
- nautobot/project-static/dist/css/nautobot.css.map +1 -1
- nautobot/project-static/dist/js/nautobot.js +1 -1
- nautobot/project-static/dist/js/nautobot.js.map +1 -1
- nautobot/project-static/js/cabletrace.js +1 -1
- nautobot/project-static/js/interface_filtering.js +20 -16
- nautobot/project-static/nautobot-icons/battery-3.svg +3 -0
- nautobot/project-static/nautobot-icons/cloud.svg +1 -1
- nautobot/project-static/nautobot-icons/control-panel.svg +1 -1
- nautobot/project-static/nautobot-icons/device-lifecycle.svg +1 -1
- nautobot/project-static/nautobot-icons/elements.svg +1 -1
- nautobot/project-static/nautobot-icons/extensibility.svg +3 -0
- nautobot/project-static/nautobot-icons/hammer.svg +1 -1
- nautobot/project-static/nautobot-icons/organization.svg +3 -0
- nautobot/project-static/nautobot-icons/secrets.svg +1 -1
- nautobot/project-static/nautobot-icons/security.svg +3 -0
- nautobot/project-static/nautobot-icons/server.svg +1 -1
- nautobot/project-static/nautobot-icons/star-filled.svg +1 -1
- nautobot/project-static/nautobot-icons/star.svg +1 -1
- 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/tests/test_filters.py +0 -2
- nautobot/tenancy/views.py +2 -1
- nautobot/ui/src/js/collapse.js +3 -3
- nautobot/ui/src/js/nautobot.js +16 -0
- nautobot/ui/src/scss/colors.scss +1 -1
- nautobot/ui/src/scss/nautobot.scss +61 -28
- nautobot/users/templates/users/profile.html +45 -12
- nautobot/users/templates/users/sessionkey_delete.html +1 -1
- nautobot/users/tests/test_api.py +4 -0
- nautobot/users/views.py +4 -2
- nautobot/virtualization/models.py +1 -68
- nautobot/virtualization/navigation.py +3 -2
- nautobot/virtualization/templates/virtualization/virtual_machine_vminterface_delete.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_list.html +2 -2
- nautobot/virtualization/templates/virtualization/virtualmachine_update.html +3 -1
- nautobot/virtualization/tests/test_api.py +3 -0
- nautobot/virtualization/tests/test_models.py +44 -4
- 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/navigation.py +3 -2
- nautobot/wireless/tests/integration/test_radio_profile.py +1 -5
- nautobot/wireless/tests/test_api.py +1 -1
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/METADATA +14 -14
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/RECORD +417 -366
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/entry_points.txt +1 -0
- nautobot/data_validation/template_content.py +0 -42
- nautobot/dcim/filters/mixins.py +0 -354
- nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +0 -4
- /nautobot/tenancy/{filters/mixins.py → filter_mixins.py} +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/LICENSE.txt +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/NOTICE +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0a3.dist-info}/WHEEL +0 -0
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/signals.py
CHANGED
|
@@ -67,10 +67,21 @@ def invalidate_max_depth_cache(sender, **kwargs):
|
|
|
67
67
|
|
|
68
68
|
Note that this signal is connected in `TreeModel.__init_subclass__()` so as to only apply to those models.
|
|
69
69
|
"""
|
|
70
|
-
from nautobot.core.models.tree_queries import TreeManager
|
|
70
|
+
from nautobot.core.models.tree_queries import TreeManager, TreeNode
|
|
71
71
|
|
|
72
72
|
if not isinstance(sender.objects, TreeManager):
|
|
73
73
|
return
|
|
74
74
|
|
|
75
|
+
# If the instance is a TreeNode, and it has siblings, skip invalidating the cache.
|
|
76
|
+
instance = kwargs.get("instance", None)
|
|
77
|
+
if isinstance(instance, TreeNode):
|
|
78
|
+
try:
|
|
79
|
+
parent = getattr(instance, "parent", None)
|
|
80
|
+
except instance.DoesNotExist:
|
|
81
|
+
parent = None
|
|
82
|
+
if parent and getattr(parent, "children", None) and parent.children.count() > 1:
|
|
83
|
+
# TreeNode has siblings, depth can't change
|
|
84
|
+
return
|
|
85
|
+
|
|
75
86
|
with contextlib.suppress(redis.exceptions.ConnectionError):
|
|
76
87
|
cache.delete(sender.objects.max_depth_cache_key)
|
nautobot/core/tables.py
CHANGED
|
@@ -370,12 +370,17 @@ class ToggleColumn(django_tables2.CheckBoxColumn):
|
|
|
370
370
|
default = kwargs.pop("default", "")
|
|
371
371
|
visible = kwargs.pop("visible", False)
|
|
372
372
|
if "attrs" not in kwargs:
|
|
373
|
-
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
|
+
}
|
|
374
377
|
super().__init__(*args, default=default, visible=visible, **kwargs)
|
|
375
378
|
|
|
376
379
|
@property
|
|
377
380
|
def header(self):
|
|
378
|
-
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
|
+
)
|
|
379
384
|
|
|
380
385
|
|
|
381
386
|
class BooleanColumn(django_tables2.Column):
|
|
@@ -405,7 +410,8 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
405
410
|
"th": {"class": "nb-actionable nb-w-0"},
|
|
406
411
|
}
|
|
407
412
|
# Note that braces are escaped to allow for string formatting prior to template rendering
|
|
408
|
-
template_code = """
|
|
413
|
+
template_code = """\
|
|
414
|
+
{{% if record.present_in_database %}}
|
|
409
415
|
<div class="dropdown">
|
|
410
416
|
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
411
417
|
<span class="mdi mdi-dots-vertical" aria-hidden="true"></span>
|
|
@@ -439,6 +445,7 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
439
445
|
{{% endif %}}
|
|
440
446
|
</ul>
|
|
441
447
|
</div>
|
|
448
|
+
{{% endif %}}
|
|
442
449
|
"""
|
|
443
450
|
|
|
444
451
|
def __init__(
|
|
@@ -490,7 +497,7 @@ class ApprovalButtonsColumn(django_tables2.TemplateColumn):
|
|
|
490
497
|
"""
|
|
491
498
|
|
|
492
499
|
buttons = ("detail", "changelog", "approve", "deny")
|
|
493
|
-
attrs = {"td": {"class": "d-print-none text-
|
|
500
|
+
attrs = {"td": {"class": "d-print-none text-end text-nowrap"}}
|
|
494
501
|
template_name = "extras/inc/approval_buttons_column.html"
|
|
495
502
|
|
|
496
503
|
def __init__(
|
|
@@ -652,11 +659,11 @@ class LinkedCountColumn(django_tables2.Column):
|
|
|
652
659
|
{k: (getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE) for k, v in self.url_params.items()}
|
|
653
660
|
)
|
|
654
661
|
if value > 1:
|
|
655
|
-
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
662
|
+
return format_html('<a href="{}" class="badge bg-primary">{}</a>', url, value)
|
|
656
663
|
if related_record is not None:
|
|
657
664
|
return helpers.hyperlinked_object(related_record, self.display_field)
|
|
658
665
|
if value == 1:
|
|
659
|
-
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
666
|
+
return format_html('<a href="{}" class="badge bg-primary">{}</a>', url, value)
|
|
660
667
|
return helpers.placeholder(value)
|
|
661
668
|
|
|
662
669
|
|
nautobot/core/templates/40x.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
{% block content %}
|
|
5
5
|
<div class="row justify-content-center" style="margin-top: 9.375rem;">
|
|
6
|
-
<div class="col-
|
|
6
|
+
<div class="col-sm-12 col-md-9 col-lg-7 nb-lg-max-width">
|
|
7
7
|
<div class="card">
|
|
8
8
|
<div class="card-header">
|
|
9
9
|
<strong class="hstack gap-4">{% block icon %}{% endblock %}{% block title %}{% endblock %}</strong>
|
nautobot/core/templates/500.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
{% block content %}
|
|
7
7
|
<div class="row justify-content-center" style="margin-top: 9.375rem;">
|
|
8
|
-
<div class="col-
|
|
8
|
+
<div class="col-sm-12 col-md-9 col-lg-7 nb-lg-max-width">
|
|
9
9
|
<div class="card">
|
|
10
10
|
<div class="card-header">
|
|
11
11
|
<strong class="hstack gap-4"><span class="mdi mdi-alert"></span>Server Error</strong>
|
|
@@ -16,7 +16,7 @@
|
|
|
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>
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
{% block content %}
|
|
14
14
|
<form action="" method="post" enctype="multipart/form-data" id="changelist-form" class="form form-horizontal">
|
|
15
15
|
{% csrf_token %}
|
|
16
|
-
<div class="row">
|
|
17
|
-
<div class="col-lg-
|
|
16
|
+
<div class="row justify-content-center">
|
|
17
|
+
<div class="col-lg-8">
|
|
18
18
|
{% if form.non_field_errors %}
|
|
19
19
|
<div class="card border-danger">
|
|
20
20
|
<div class="card-header bg-danger-subtle border-danger text-body"><strong>Errors</strong></div>
|
|
@@ -59,14 +59,14 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
{{ item.form_field.as_hidden }}
|
|
61
61
|
{% else %}
|
|
62
|
-
<div class="mb-10 d-flex justify-content-
|
|
63
|
-
<label class="col-
|
|
62
|
+
<div class="mb-10 d-md-flex align-content-start justify-content-between{% if item.form_field.errors %} has-error{% endif %}">
|
|
63
|
+
<label class="col-12 col-md-3 col-form-label" for="{{ item.form_field.id_for_label }}">
|
|
64
64
|
{{ name | split:"_" | join:" " }}
|
|
65
|
-
<span class="form-text">
|
|
65
|
+
<span class="form-text ps-2">
|
|
66
66
|
(default: <code>{{ item.default }}</code>)
|
|
67
67
|
</span>
|
|
68
68
|
</label>
|
|
69
|
-
<div class="col-
|
|
69
|
+
<div class="col-12 col-md-9">
|
|
70
70
|
{{ item.form_field.errors }}
|
|
71
71
|
{% if item.is_file %}{% trans "Current file" %}: <a href="{% get_media_prefix as MEDIA_URL %}{{ MEDIA_URL }}{{ item.value }}" target="_blank">{{ item.value }}</a>{% endif %}
|
|
72
72
|
{{ item.form_field }}
|
|
@@ -89,14 +89,14 @@
|
|
|
89
89
|
</div>
|
|
90
90
|
{{ item.form_field.as_hidden }}
|
|
91
91
|
{% else %}
|
|
92
|
-
<div class="mb-10 d-flex justify-content-
|
|
93
|
-
<label class="col-
|
|
92
|
+
<div class="mb-10 d-md-flex align-content-start justify-content-between{% if item.form_field.errors %} has-error{% endif %}">
|
|
93
|
+
<label class="col-12 col-md-3 d-flex d-md-block col-form-label" for="{{ item.form_field.id_for_label }}">
|
|
94
94
|
{{ item.name | split:"_" | join:" " }}
|
|
95
|
-
<span class="form-text">
|
|
95
|
+
<span class="form-text ps-2">
|
|
96
96
|
(default: <code>{{ item.default }}</code>)
|
|
97
97
|
</span>
|
|
98
98
|
</label>
|
|
99
|
-
<div class="col-
|
|
99
|
+
<div class="col-12 col-md-9">
|
|
100
100
|
{{ item.form_field.errors }}
|
|
101
101
|
{% if item.is_file %}{% trans "Current file" %}: <a href="{% get_media_prefix as MEDIA_URL %}{{ MEDIA_URL }}{{ item.value }}" target="_blank">{{ item.value }}</a>{% endif %}
|
|
102
102
|
{{ item.form_field }}
|
|
@@ -112,8 +112,8 @@
|
|
|
112
112
|
</div>
|
|
113
113
|
</div>
|
|
114
114
|
</div>
|
|
115
|
-
<div class="row">
|
|
116
|
-
<div class="col-lg-
|
|
115
|
+
<div class="row justify-content-center">
|
|
116
|
+
<div class="col-lg-8 text-end">
|
|
117
117
|
<input type="submit" name="_save" class="btn btn-primary" value="{% trans 'Save' %}"/>
|
|
118
118
|
</div>
|
|
119
119
|
</div>
|
|
@@ -14,19 +14,19 @@
|
|
|
14
14
|
<ul class="dropdown-menu" role="menu">
|
|
15
15
|
{% for app in app_list %}
|
|
16
16
|
<li>
|
|
17
|
-
<a href="#"><strong>{% render_app_name app %}</strong></a>
|
|
17
|
+
<a class="dropdown-item" href="#"><strong>{% render_app_name app %}</strong></a>
|
|
18
18
|
</li>
|
|
19
19
|
{% for model in app.models %}
|
|
20
20
|
<li>
|
|
21
21
|
{% if model.admin_url %}
|
|
22
|
-
<a href="{{ model.admin_url }}">{{ model.name }}</a>
|
|
22
|
+
<a class="dropdown-item" href="{{ model.admin_url }}">{{ model.name }}</a>
|
|
23
23
|
{% else %}
|
|
24
24
|
{{ model.name }}
|
|
25
25
|
{% endif %}
|
|
26
26
|
</li>
|
|
27
27
|
{% endfor %}
|
|
28
28
|
{% if not forloop.last %}
|
|
29
|
-
<li
|
|
29
|
+
<li><hr class="dropdown-divider"></li>
|
|
30
30
|
{% endif %}
|
|
31
31
|
{% endfor %}
|
|
32
32
|
</ul>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div class="
|
|
1
|
+
<div class="dropdown d-inline-flex">
|
|
2
2
|
<button type="button" class="btn btn-{{ color }} dropdown-toggle" data-bs-toggle="dropdown"
|
|
3
3
|
aria-haspopup="true" aria-expanded="false"
|
|
4
4
|
{% for key, value in attributes.items %}{{ key }}="{{ value }}" {% endfor %}
|
|
@@ -9,12 +9,14 @@
|
|
|
9
9
|
</button>
|
|
10
10
|
<ul class="dropdown-menu">
|
|
11
11
|
{% for child in children %}
|
|
12
|
-
<li
|
|
12
|
+
<li>
|
|
13
|
+
<a href="{{ child.link }}" class="dropdown-item text-{{ child.color }}"
|
|
13
14
|
{% for key, value in child.attributes.items %}{{ key }}="{{ value }}" {% endfor %}
|
|
14
15
|
>
|
|
15
16
|
{% if child.icon %}<span class="mdi {{ child.icon }}" aria-hidden="true"></span>{% endif %}
|
|
16
17
|
{{ child.label }}
|
|
17
|
-
</a
|
|
18
|
+
</a>
|
|
19
|
+
</li>
|
|
18
20
|
{% endfor %}
|
|
19
21
|
</ul>
|
|
20
22
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<div class="card">
|
|
1
|
+
<div class="card{% if css_class %} border-{{ css_class }}{% endif %}">
|
|
2
2
|
{% if label.strip or header_extra_content.strip %}
|
|
3
|
-
<div class="card-header">
|
|
3
|
+
<div class="card-header{% if css_class %} bg-{{ css_class }}-subtle border-{{ css_class }}{% endif %}">
|
|
4
4
|
{% if label %}
|
|
5
5
|
<strong>{{ label }}</strong>
|
|
6
6
|
{% endif %}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
{% endif %}
|
|
13
13
|
{{ body }}
|
|
14
14
|
{% if footer_content.strip %}
|
|
15
|
-
<div class="card-footer">
|
|
15
|
+
<div class="card-footer{% if css_class %} bg-{{ css_class }}-subtle border-{{ css_class }}{% endif %}">
|
|
16
16
|
{{ footer_content }}
|
|
17
17
|
</div>
|
|
18
18
|
{% endif %}
|
|
@@ -9,15 +9,14 @@
|
|
|
9
9
|
<div class="align-items-center d-flex flex-wrap mb-16">
|
|
10
10
|
{% include 'inc/created_updated.html' %}
|
|
11
11
|
<div class="flex-grow-0 flex-shrink-0 d-print-none">
|
|
12
|
+
{% custom_links object %}
|
|
13
|
+
{% job_buttons object %}
|
|
12
14
|
{% block buttons %}
|
|
13
15
|
{% plugin_buttons object %}
|
|
14
16
|
{% render_detail_view_extra_buttons %}
|
|
15
17
|
{% block extra_buttons %}{% endblock extra_buttons %}
|
|
16
18
|
{% consolidate_detail_view_action_buttons %}
|
|
17
19
|
{% endblock buttons %}
|
|
18
|
-
{% custom_links object %}
|
|
19
|
-
{% job_buttons object %}
|
|
20
|
-
{% block panel_buttons %}{% endblock panel_buttons %}
|
|
21
20
|
</div>
|
|
22
21
|
</div>
|
|
23
22
|
{% else %}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% comment %}disabled_message is not part of the default render context but a tab can define it if needed.{% endcomment %}
|
|
2
2
|
{% if disabled_message %}
|
|
3
3
|
<li class="nav-item" role="presentation" title="{{ disabled_message }}">
|
|
4
|
-
<a class="nav-link disabled"
|
|
4
|
+
<a aria-disabled="true" class="nav-link disabled">{{ label }}</a>
|
|
5
5
|
</li>
|
|
6
6
|
{% else %}
|
|
7
7
|
<li class="nav-item" role="presentation">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div id="{{ chart_container_id }}" style="width: {{ chart_width }}; height: {{ chart_height }};"></div>
|
|
1
|
+
<div class="collapse show" id="{{ chart_container_id }}" style="width: {{ chart_width }}; height: {{ chart_height }};"></div>
|
|
2
2
|
<!-- Safe JSON export from Django -->
|
|
3
3
|
{% with "echarts-config-"|add:chart_container_id as chart_config_id %}
|
|
4
4
|
{{ chart_config|json_script:chart_config_id }}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{% extends 'base.html' %}
|
|
2
2
|
{% load form_helpers %}
|
|
3
3
|
|
|
4
|
+
{% block title %}Add {{ model_name|title }}{% endblock %}
|
|
5
|
+
|
|
4
6
|
{% block content %}
|
|
5
7
|
<form action="." method="post" class="h-100 vstack">
|
|
6
8
|
{% csrf_token %}
|
|
@@ -11,7 +13,6 @@
|
|
|
11
13
|
{{ field }}
|
|
12
14
|
{% endfor %}
|
|
13
15
|
<div class="row align-content-start flex-fill">
|
|
14
|
-
<h1 class="mb-16">{% block title %}Add {{ model_name|title }}{% endblock %}</h1>
|
|
15
16
|
<p class="mb-16">{{ table.rows|length }} {{ parent_model_name }} selected</p>
|
|
16
17
|
<div class="col-lg-7">
|
|
17
18
|
<div class="card">
|
|
@@ -25,11 +25,12 @@ Leaving it here for now in case apps are making use of it.
|
|
|
25
25
|
</style>
|
|
26
26
|
{% endblock %}
|
|
27
27
|
|
|
28
|
+
{% block title %}{{ obj_type|bettertitle }} Bulk Import{% endblock %}
|
|
29
|
+
|
|
28
30
|
{% block content %}
|
|
29
31
|
{% block tabs %}{% endblock %}
|
|
30
|
-
<div class="row">
|
|
31
|
-
<div class="col-
|
|
32
|
-
<h1 class="mb-16">{% block title %}{{ obj_type|bettertitle }} Bulk Import{% endblock %}</h1>
|
|
32
|
+
<div class="row justify-content-center">
|
|
33
|
+
<div class="col-lg-8 col-md-10">
|
|
33
34
|
{% if form.non_field_errors %}
|
|
34
35
|
<div class="card border-danger">
|
|
35
36
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
{% for field in form.hidden_fields %}
|
|
14
14
|
{{ field }}
|
|
15
15
|
{% endfor %}
|
|
16
|
-
<div class="row align-content-start flex-fill">
|
|
17
|
-
<div class="col-
|
|
16
|
+
<div class="row align-content-start justify-content-center flex-fill">
|
|
17
|
+
<div class="col-lg-8 col-md-10 d-flex justify-content-center">
|
|
18
18
|
<div class="card border-danger" id="confirm-bulk-deletion">
|
|
19
19
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
20
20
|
<strong>Confirm Bulk Deletion</strong>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
28
|
{% if table %}
|
|
29
|
-
<div class="col-
|
|
29
|
+
<div class="col-lg-8 col-md-10">
|
|
30
30
|
<div class="card">
|
|
31
31
|
<div class="table-responsive">
|
|
32
32
|
{% render_table table 'inc/table.html' %}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
{% for field in form.hidden_fields %}
|
|
10
10
|
{{ field }}
|
|
11
11
|
{% endfor %}
|
|
12
|
-
<div class="row align-content-start flex-fill">
|
|
13
|
-
<div class="col-
|
|
12
|
+
<div class="row align-content-start justify-content-center flex-fill">
|
|
13
|
+
<div class="col-lg-8 col-md-10 d-flex justify-content-center">
|
|
14
14
|
<div class="card border-danger">
|
|
15
15
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
16
16
|
<strong>Confirm Bulk Removal</strong>
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
{% load form_helpers %}
|
|
4
4
|
{% load render_table from django_tables2 %}
|
|
5
5
|
|
|
6
|
+
{% block title %}Editing {{ objs_count }} {{ obj_type_plural|bettertitle }}{% endblock %}
|
|
7
|
+
|
|
6
8
|
{% block content %}
|
|
7
9
|
<form action="" method="post" class="h-100 vstack">
|
|
8
10
|
{% csrf_token %}
|
|
@@ -12,8 +14,7 @@
|
|
|
12
14
|
{% for field in form.hidden_fields %}
|
|
13
15
|
{{ field }}
|
|
14
16
|
{% endfor %}
|
|
15
|
-
<div class="row align-content-start flex-fill">
|
|
16
|
-
<h1 class="mb-16">{% block title %}Editing {{ objs_count }} {{ obj_type_plural|bettertitle }}{% endblock %}</h1>
|
|
17
|
+
<div class="row justify-content-center align-content-start flex-fill">
|
|
17
18
|
{% if form.errors %}
|
|
18
19
|
<div class="card border-danger">
|
|
19
20
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
</div>
|
|
31
32
|
{% endif %}
|
|
32
33
|
{% if table %}
|
|
33
|
-
<div class="col-
|
|
34
|
+
<div class="col-lg-8">
|
|
34
35
|
<div class="card">
|
|
35
36
|
<div class="table-responsive">
|
|
36
37
|
{% render_table table 'inc/table.html' %}
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
</div>
|
|
39
40
|
</div>
|
|
40
41
|
{% endif %}
|
|
41
|
-
<div class="{% if table %}col-
|
|
42
|
+
<div class="{% if table %}col-lg-4{% else %}col-lg-8 col-md-12{% endif %}">
|
|
42
43
|
<div class="card">
|
|
43
44
|
<div class="card-header"><strong>{% block form_title %}Attributes{% endblock %}</strong></div>
|
|
44
45
|
<div class="card-body">
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
{% load form_helpers %}
|
|
3
3
|
{% load helpers %}
|
|
4
4
|
|
|
5
|
+
{% block title %}{% if editing %}Editing {{ obj_type }} {{ obj }}{% else %}Add a new {{ obj_type }}{% endif %}{% endblock %}
|
|
6
|
+
|
|
5
7
|
{% block content %}
|
|
6
8
|
<form action="" method="post" enctype="multipart/form-data" class="h-100 vstack">
|
|
7
9
|
{% csrf_token %}
|
|
8
10
|
{% for field in form.hidden_fields %}
|
|
9
11
|
{{ field }}
|
|
10
12
|
{% endfor %}
|
|
11
|
-
<div class="row align-content-start flex-fill">
|
|
12
|
-
<div class="col-lg-8
|
|
13
|
+
<div class="row justify-content-center align-content-start flex-fill">
|
|
14
|
+
<div class="col-lg-8 col-md-10 mb-10">
|
|
13
15
|
<h3>
|
|
14
16
|
{% if obj %}
|
|
15
17
|
{% with obj|get_docs_url as docs_url %}
|
|
@@ -20,10 +22,9 @@
|
|
|
20
22
|
{% endif %}
|
|
21
23
|
{% endwith %}
|
|
22
24
|
{% endif %}
|
|
23
|
-
{% block title %}{% if editing %}Editing {{ obj_type }} {{ obj }}{% else %}Add a new {{ obj_type }}{% endif %}{% endblock %}
|
|
24
25
|
</h3>
|
|
25
26
|
</div>
|
|
26
|
-
<div class="col-lg-8
|
|
27
|
+
<div class="col-lg-8 col-md-10">
|
|
27
28
|
{% block tabs %}{% endblock %}
|
|
28
29
|
{% block form_errors %}
|
|
29
30
|
{% if form.non_field_errors or model_form.non_field_errors %}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
{% load helpers %}
|
|
3
3
|
{% load form_helpers %}
|
|
4
4
|
|
|
5
|
+
{% block title %}{{ obj_type|bettertitle }} Import{% endblock %}
|
|
6
|
+
|
|
5
7
|
{% block content %}
|
|
6
8
|
{% block tabs %}{% endblock %}
|
|
7
9
|
<form action="" method="post" class="object-import-form h-100 vstack">
|
|
8
10
|
{% csrf_token %}
|
|
9
11
|
<div class="row align-content-start flex-fill">
|
|
10
12
|
<div class="col-md-8 offset-md-2">
|
|
11
|
-
<h1>{% block title %}{{ obj_type|bettertitle }} Import{% endblock %}</h1>
|
|
12
13
|
{% if form.non_field_errors %}
|
|
13
14
|
<div class="card border-danger">
|
|
14
15
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
@@ -156,17 +156,25 @@
|
|
|
156
156
|
data-bs-target="#dynamic_group_assignment_modal"
|
|
157
157
|
data-objects="all"
|
|
158
158
|
class="btn btn-primary btn-sm"
|
|
159
|
-
disabled
|
|
159
|
+
disabled>
|
|
160
160
|
<span class="mdi mdi-group me-4" aria-hidden="true"></span>Update Group Assignment for All
|
|
161
161
|
</button>
|
|
162
162
|
{% endif %}
|
|
163
163
|
{% if bulk_edit_url and permissions.change %}
|
|
164
|
-
<button type="submit"
|
|
164
|
+
<button type="submit"
|
|
165
|
+
name="_edit"
|
|
166
|
+
formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}"
|
|
167
|
+
class="btn btn-warning btn-sm"
|
|
168
|
+
disabled>
|
|
165
169
|
<span class="mdi mdi-pencil me-4" aria-hidden="true"></span>Edit All
|
|
166
170
|
</button>
|
|
167
171
|
{% endif %}
|
|
168
172
|
{% if bulk_delete_url and permissions.delete %}
|
|
169
|
-
<button type="submit"
|
|
173
|
+
<button type="submit"
|
|
174
|
+
name="_delete"
|
|
175
|
+
formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}"
|
|
176
|
+
class="btn btn-danger btn-sm"
|
|
177
|
+
disabled>
|
|
170
178
|
<span class="mdi mdi-trash-can-outline me-4" aria-hidden="true"></span>Delete All
|
|
171
179
|
</button>
|
|
172
180
|
{% endif %}
|
|
@@ -297,7 +305,7 @@
|
|
|
297
305
|
</a>
|
|
298
306
|
{% if current_saved_view %}
|
|
299
307
|
{% if current_saved_view.owner == user %}
|
|
300
|
-
<a class="btn btn-danger" href="{% url 'extras:savedview_delete' pk=current_saved_view.pk %}">
|
|
308
|
+
<a class="btn btn-danger" href="{% url 'extras:savedview_delete' pk=current_saved_view.pk %}?return_url={{ request.path }}">
|
|
301
309
|
<span class="mdi mdi-trash-can-outline me-4" aria-hidden="true"></span>Delete Current
|
|
302
310
|
</a>
|
|
303
311
|
{% else %}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
{% block content %}
|
|
6
6
|
{% if perms.extras.add_note %}
|
|
7
7
|
<form action="{% url 'extras:note_add' %}?return_url={{ request.path }}?tab=notes" method="post" enctype="multipart/form-data">
|
|
8
|
-
<div class="row">
|
|
9
|
-
<div class="col-md-
|
|
8
|
+
<div class="row justify-content-center">
|
|
9
|
+
<div class="col-md-10 col-lg-8">
|
|
10
10
|
<h3 class="mb-16">Add a new note</h3>
|
|
11
11
|
<div class="card">
|
|
12
12
|
<div class="card-header">
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
|
-
|
|
21
|
+
</div>
|
|
22
|
+
<div class="row justify-content-center">
|
|
23
|
+
<div class="col-md-10 col-lg-8 gap-8 hstack justify-content-end mb-16">
|
|
22
24
|
<button id="createNote" type="submit" class="btn btn-primary">
|
|
23
25
|
<span aria-hidden="true" class="mdi mdi-check me-4"></span><!--
|
|
24
26
|
-->Create
|
|
@@ -132,15 +132,14 @@
|
|
|
132
132
|
<div class="align-items-center d-flex flex-wrap mb-16">
|
|
133
133
|
{% include 'inc/created_updated.html' %}
|
|
134
134
|
<div class="flex-grow-0 flex-shrink-0 d-print-none">
|
|
135
|
+
{% custom_links object %}
|
|
136
|
+
{% job_buttons object %}
|
|
135
137
|
{% block buttons %}
|
|
136
138
|
{% plugin_buttons object %}
|
|
137
139
|
{% render_detail_view_extra_buttons %}
|
|
138
140
|
{% block extra_buttons %}{% endblock extra_buttons %}
|
|
139
141
|
{% consolidate_detail_view_action_buttons %}
|
|
140
142
|
{% endblock buttons %}
|
|
141
|
-
{% custom_links object %}
|
|
142
|
-
{% job_buttons object %}
|
|
143
|
-
{% block panel_buttons %}{% endblock panel_buttons %}
|
|
144
143
|
</div>
|
|
145
144
|
</div>
|
|
146
145
|
<div class="row">
|
|
@@ -49,13 +49,13 @@ add "&raw" to the end of the URL within a browser.
|
|
|
49
49
|
[data-bs-theme="dark"] .graphiql-dialog-overlay,
|
|
50
50
|
[data-bs-theme="dark"] .graphiql-tooltip,
|
|
51
51
|
[data-bs-theme="dark"] [data-radix-popper-content-wrapper] {
|
|
52
|
-
--color-primary:
|
|
53
|
-
--color-secondary:
|
|
54
|
-
--color-tertiary: 0, 0%,
|
|
55
|
-
--color-success:
|
|
56
|
-
--color-warning:
|
|
57
|
-
--color-error: 0,
|
|
58
|
-
--color-base:
|
|
52
|
+
--color-primary: 209, 100%, 60% !important; /* $blue-0-dark: #339dff; */
|
|
53
|
+
--color-secondary: 0, 0%, 71% !important; /* $gray-3-dark: #b5b5b5; */
|
|
54
|
+
--color-tertiary: 0, 0%, 100% !important; /* $black-0-dark: #ffffff; */
|
|
55
|
+
--color-success: 27, 63%, 49% !important; /* $green-0-dark: #2ecc40; */
|
|
56
|
+
--color-warning: 30, 100%, 60% !important; /* $orange-0-dark: #ff9933; */
|
|
57
|
+
--color-error: 0, 100%, 65% !important; /* $red-0-dark: #ff4c4c; */
|
|
58
|
+
--color-base: 0, 0%, 12% !important; /* $gray-0-dark: #1e1e1e; */
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
#main-content {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
{% load helpers %}
|
|
3
3
|
{% load registry %}
|
|
4
4
|
|
|
5
|
-
{# TODO: Figure out better solution: this is a quick hack to remove "chevrons" from homepage because in this commit I'm adding the
|
|
5
|
+
{# TODO: Figure out better solution: this is a quick hack to remove "chevrons" from homepage because in this commit I'm adding the chevrons in base_django.html #}
|
|
6
6
|
{% block page_title %}{% endblock %}
|
|
7
7
|
|
|
8
8
|
{% block header %}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{% extends 'base.html' %}
|
|
2
2
|
|
|
3
|
+
{% block title %}Import Completed{% endblock %}
|
|
4
|
+
|
|
3
5
|
{% block content %}
|
|
4
|
-
<h1>{% block title %}Import Completed{% endblock %}</h1>
|
|
5
6
|
{% include 'responsive_table.html' %}
|
|
6
7
|
<a href="{{ request.path }}" class="btn btn-primary">
|
|
7
8
|
<span class="mdi mdi-database-import-outline" aria-hidden="true"></span>
|