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
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{% render_field form.name %}
|
|
10
10
|
{% render_field form.model_content_type %}
|
|
11
11
|
{% render_field form.model_constraints %}
|
|
12
|
-
{% render_field form.
|
|
12
|
+
{% render_field form.weight %}
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
15
|
<div class="card">
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
<thead>
|
|
23
23
|
<tr>
|
|
24
24
|
{% for field in stage.visible_fields %}
|
|
25
|
-
<th>
|
|
25
|
+
<th>
|
|
26
|
+
<span data-bs-toggle="tooltip" data-bs-placement="top" title="{{ field.help_text }}">{{ field.label|capfirst }}</span>
|
|
27
|
+
</th>
|
|
26
28
|
{% endfor %}
|
|
27
29
|
</tr>
|
|
28
30
|
</thead>
|
|
@@ -3,19 +3,27 @@
|
|
|
3
3
|
|
|
4
4
|
{% block buttons %}
|
|
5
5
|
<span title="{% if not object.is_active_stage %}This stage is not active{% elif request.user in object.users_that_already_approved %}You already approved this stage{% else %}Approve this stage{% endif %}">
|
|
6
|
-
|
|
7
|
-
href="{% url 'extras:approvalworkflowstage_approve' object.pk %}?return_url={{request.path}}"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
{% if object.is_active_stage and request.user not in object.users_that_already_approved %}
|
|
7
|
+
<a href="{% url 'extras:approvalworkflowstage_approve' object.pk %}?return_url={{request.path}}"
|
|
8
|
+
class="btn btn-success">
|
|
9
|
+
<span class="mdi mdi-check"></span> Approve
|
|
10
|
+
</a>
|
|
11
|
+
{% else %}
|
|
12
|
+
<a aria-disabled="true" class="btn btn-success disabled">
|
|
13
|
+
<span class="mdi mdi-check"></span> Approve
|
|
14
|
+
</a>
|
|
15
|
+
{% endif %}
|
|
12
16
|
</span>
|
|
13
17
|
<span title="{% if not object.is_active_stage %}This stage is not active{% elif request.user in object.users_that_already_approved %}You already approved this stage{% else %}Deny this stage{% endif %}">
|
|
14
|
-
|
|
15
|
-
href="{% url 'extras:approvalworkflowstage_deny' object.pk %}?return_url={{request.path}}"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
{% if object.is_active_stage and request.user not in object.users_that_already_approved %}
|
|
19
|
+
<a href="{% url 'extras:approvalworkflowstage_deny' object.pk %}?return_url={{request.path}}"
|
|
20
|
+
class="btn btn-danger">
|
|
21
|
+
<span class="mdi mdi-close"></span> Deny
|
|
22
|
+
</a>
|
|
23
|
+
{% else %}
|
|
24
|
+
<a aria-disabled="true" class="btn btn-danger disabled">
|
|
25
|
+
<span class="mdi mdi-close"></span> Deny
|
|
26
|
+
</a>
|
|
27
|
+
{% endif %}
|
|
20
28
|
</span>
|
|
21
29
|
{% endblock buttons %}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
{% extends '
|
|
1
|
+
{% extends 'generic/object_retrieve.html' %}
|
|
2
2
|
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
{% extends '
|
|
1
|
+
{% extends 'generic/object_retrieve.html' %}
|
|
2
2
|
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{% extends 'extras/
|
|
1
|
+
{% extends 'extras/configcontextschema_retrieve.html' %}
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
{% block title %}{{ object }} - Validation{% endblock %}
|
|
4
4
|
|
|
5
5
|
{% block content %}
|
|
6
6
|
<div class="row">
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
{% extends '
|
|
1
|
+
{% extends 'generic/object_retrieve.html' %}
|
|
2
2
|
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -11,15 +11,21 @@
|
|
|
11
11
|
|
|
12
12
|
{% block extra_tab_content %}
|
|
13
13
|
<div id="members" role="tabpanel" class="tab-pane {% if not active_tab and not request.GET.tab or request.GET.tab == "members" %}active{% else %}fade{% endif %}">
|
|
14
|
-
|
|
15
|
-
<div class="
|
|
16
|
-
|
|
14
|
+
<div class="row">
|
|
15
|
+
<div class="col-lg-12">
|
|
16
|
+
{% if members_list_url %}
|
|
17
17
|
<div class="alert alert-success" role="alert">
|
|
18
18
|
You can bulk-add and bulk-remove members of this group from the <a href="{{ members_list_url }}">{{ members_verbose_name_plural|bettertitle }} list view</a>.
|
|
19
19
|
</div>
|
|
20
|
-
|
|
20
|
+
{% else %}
|
|
21
|
+
<div class="alert alert-warning" role="alert">
|
|
22
|
+
Dynamic group membership is cached for performance reasons, therefore this listing may not always
|
|
23
|
+
be up-to-date.<br>You can refresh the membership of this group asynchronously by clicking the
|
|
24
|
+
"Refresh Members" button above.
|
|
25
|
+
</div>
|
|
26
|
+
{% endif %}
|
|
21
27
|
</div>
|
|
22
|
-
|
|
28
|
+
</div>
|
|
23
29
|
<div class="row">
|
|
24
30
|
<div class="col-lg-12">
|
|
25
31
|
{% include 'utilities/obj_table.html' with table=members_table table_template='panel_table.html' heading='Dynamic Group members' %}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<div class="tab-content">
|
|
44
44
|
<div class="tab-pane active" id="filter-form">
|
|
45
45
|
{% if filter_form %}
|
|
46
|
-
<span class="form-text">
|
|
46
|
+
<span class="form-text py-6">
|
|
47
47
|
Select the filtering criteria to determine membership of objects matching
|
|
48
48
|
the Content Type for this Dynamic Group. Fields that are not a dropdown are
|
|
49
49
|
expected to have string inputs and do not support multiple values.
|
|
@@ -1,97 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block content_left_page %}
|
|
5
|
-
<div class="card">
|
|
6
|
-
<div class="card-header">
|
|
7
|
-
<strong>Query</strong>
|
|
8
|
-
</div>
|
|
9
|
-
<table class="table table-hover card-body attr-table">
|
|
10
|
-
<tr>
|
|
11
|
-
<td>Name</td>
|
|
12
|
-
<td><span>{{ object.name }}</span></td>
|
|
13
|
-
</tr>
|
|
14
|
-
<tr>
|
|
15
|
-
<td>Query</td>
|
|
16
|
-
<td><pre id="query"><code class="language-graphql">{{ object.query }}</code></pre></td>
|
|
17
|
-
</tr>
|
|
18
|
-
<tr>
|
|
19
|
-
<td>Query Variables</td>
|
|
20
|
-
<td><pre>{{ object.variables|render_json }}</pre></td>
|
|
21
|
-
</tr>
|
|
22
|
-
</table>
|
|
23
|
-
</div>
|
|
24
|
-
{% endblock content_left_page %}
|
|
25
|
-
|
|
26
|
-
{% block content_right_page %}
|
|
27
|
-
<div class="card">
|
|
28
|
-
<div class="card-header">
|
|
29
|
-
<strong>Response</strong>
|
|
30
|
-
<button class="btn btn-primary btn-sm float-end" onclick="test_query()">Execute</button>
|
|
31
|
-
</div>
|
|
32
|
-
{% if object.variables %}
|
|
33
|
-
<table class="table table-hover card-body attr-table">
|
|
34
|
-
<tr>
|
|
35
|
-
<td>Variables:</td>
|
|
36
|
-
<td><textarea id="query_variables" class="form-control">{{ object.variables|render_json:False }}</textarea></td>
|
|
37
|
-
</tr>
|
|
38
|
-
</table>
|
|
39
|
-
{% endif %}
|
|
40
|
-
<div class="card-footer">
|
|
41
|
-
<pre id="query_output">
|
|
42
|
-
|
|
43
|
-
</pre>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
{% endblock content_right_page %}
|
|
47
|
-
|
|
48
|
-
{% block javascript %}
|
|
49
|
-
{{ block.super }}
|
|
50
|
-
<script>
|
|
51
|
-
function fillQueryOutput(data) {
|
|
52
|
-
const queryOutput = document.querySelector('#query_output');
|
|
53
|
-
|
|
54
|
-
[...queryOutput.childNodes].forEach(childNode => childNode.remove());
|
|
55
|
-
|
|
56
|
-
const code = document.createElement('code');
|
|
57
|
-
code.classList.add('language-json');
|
|
58
|
-
code.textContent = JSON.stringify(data, undefined, 2);
|
|
59
|
-
|
|
60
|
-
queryOutput.appendChild(code);
|
|
61
|
-
|
|
62
|
-
hljs.highlightElement(code);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function test_query() {
|
|
66
|
-
const variables = document.querySelector('#query_variables')?.value;
|
|
67
|
-
|
|
68
|
-
$.ajax({
|
|
69
|
-
url: "{% url 'graphql' %}",
|
|
70
|
-
method: "POST",
|
|
71
|
-
headers: {"X-CSRFTOKEN": "{{ csrf_token }}"},
|
|
72
|
-
dataType: "json",
|
|
73
|
-
data: {
|
|
74
|
-
"query": `{{ object.query | escapejs }}`,
|
|
75
|
-
"variables": variables,
|
|
76
|
-
},
|
|
77
|
-
success: function(data) {
|
|
78
|
-
fillQueryOutput(data);
|
|
79
|
-
},
|
|
80
|
-
error: function(error) {
|
|
81
|
-
console.log(error);
|
|
82
|
-
fillQueryOutput(error.responseJSON);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
textarea = document.querySelector("#query_variables");
|
|
88
|
-
textarea.addEventListener('input', autoResize, false);
|
|
89
|
-
textarea.style.height = 'auto';
|
|
90
|
-
textarea.style.height = textarea.scrollHeight + 'px';
|
|
91
|
-
|
|
92
|
-
function autoResize() {
|
|
93
|
-
this.style.height = 'auto';
|
|
94
|
-
this.style.height = this.scrollHeight + 'px';
|
|
95
|
-
}
|
|
96
|
-
</script>
|
|
97
|
-
{% endblock javascript %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -10,15 +10,29 @@
|
|
|
10
10
|
{% endif %}
|
|
11
11
|
{% if "approve" in buttons and have_permission and record.is_active_stage %}
|
|
12
12
|
<span title='{% if request.user in record.users_that_already_approved %}You already approved this stage{% else %}Approve this stage{% endif %}'>
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
|
|
13
|
+
{% if request.user not in record.users_that_already_approved %}
|
|
14
|
+
<a href="{% url approval_route pk=record.pk %}?return_url={{ request.path }}{{ return_url_extra }}"
|
|
15
|
+
class="btn btn-success btn-sm">
|
|
16
|
+
<span class="mdi mdi-check"></span>
|
|
17
|
+
</a>
|
|
18
|
+
{% else %}
|
|
19
|
+
<a aria-disabled="true" class="btn btn-success btn-sm disabled">
|
|
20
|
+
<span class="mdi mdi-check"></span>
|
|
21
|
+
</a>
|
|
22
|
+
{% endif %}
|
|
16
23
|
</span>
|
|
17
24
|
{% endif %}
|
|
18
25
|
{% if "deny" in buttons and have_permission and record.is_active_stage and request.user not in record.users_that_already_approved %}
|
|
19
26
|
<span title='{%if request.user in record.users_that_already_approved %}You already approved this stage{% else %}Deny this stage{% endif %}'>
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
27
|
+
{% if request.user not in record.users_that_already_approved %}
|
|
28
|
+
<a href="{% url deny_route pk=record.pk %}?return_url={{ request.path }}{{ return_url_extra }}"
|
|
29
|
+
class="btn btn-danger btn-sm">
|
|
30
|
+
<span class="mdi mdi-close"></span>
|
|
31
|
+
</a>
|
|
32
|
+
{% else %}
|
|
33
|
+
<a aria-disabled="true" class="btn btn-danger btn-sm disabled">
|
|
34
|
+
<span class="mdi mdi-close"></span>
|
|
35
|
+
</a>
|
|
36
|
+
{% endif %}
|
|
23
37
|
</span>
|
|
24
38
|
{% endif %}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{% load form_helpers %}
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<
|
|
3
|
+
|
|
4
|
+
<hr class="border-top">
|
|
5
|
+
<div class="mb-10 d-lg-flex justify-content-center{% if field.errors %} has-error{% endif %}">
|
|
5
6
|
<label class="col-lg-3 col-form-label{% if field.field.required %} nb-required{% endif %}" for="{{ field.id_for_label }}">
|
|
6
7
|
{{ field.label }}
|
|
7
8
|
</label>
|
|
@@ -19,17 +20,17 @@
|
|
|
19
20
|
{% endif %}
|
|
20
21
|
</div>
|
|
21
22
|
</div>
|
|
22
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
23
|
+
<div class="mb-10 d-lg-flex justify-content-center">
|
|
23
24
|
<span class="col-lg-3 col-form-label">
|
|
24
25
|
</span>
|
|
25
26
|
<div class="col-lg-9">
|
|
26
|
-
<div>
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
<div class="form-check flex-wrap">
|
|
28
|
+
{{ override_field }}
|
|
29
|
+
<label class="form-check-label" for="{{ override_field.id_for_label }}">
|
|
29
30
|
<i>Clear override</i>
|
|
30
31
|
</label>
|
|
31
32
|
{% if override_field.help_text %}
|
|
32
|
-
<span class="form-text">{{ override_field.help_text|safe }}</span>
|
|
33
|
+
<span class="form-text w-100">{{ override_field.help_text|safe }}</span>
|
|
33
34
|
{% endif %}
|
|
34
35
|
</div>
|
|
35
36
|
</div>
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
{% load helpers %}
|
|
1
2
|
<div class="float-end">
|
|
2
|
-
<div class="btn-group btn-group-
|
|
3
|
-
<a href="
|
|
4
|
-
|
|
3
|
+
<div class="btn-group btn-group-sm" role="group">
|
|
4
|
+
<a href="{% django_querystring data_format='json' %}"
|
|
5
|
+
class="btn btn-primary {% if data_format == 'json' %}bg-primary nb-text-body-bg{% endif %}">
|
|
6
|
+
<span class="mdi mdi-code-json" aria-hidden="true"></span> JSON
|
|
7
|
+
</a>
|
|
8
|
+
<a href="{% django_querystring data_format='yaml' %}"
|
|
9
|
+
class="btn btn-primary {% if data_format == 'yaml' %}bg-primary nb-text-body-bg{% endif %}">
|
|
10
|
+
<span class="mdi mdi-format-list-group" aria-hidden="true"></span> YAML
|
|
11
|
+
</a>
|
|
5
12
|
</div>
|
|
6
13
|
</div>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{% load helpers %}
|
|
2
|
+
|
|
3
|
+
<div class="card">
|
|
4
|
+
<div class="card-header">
|
|
5
|
+
<strong>Response</strong>
|
|
6
|
+
<button class="btn btn-primary btn-sm float-end" onclick="test_query()">Execute</button>
|
|
7
|
+
</div>
|
|
8
|
+
{% if object.variables %}
|
|
9
|
+
<table class="table table-hover card-body attr-table">
|
|
10
|
+
<tr>
|
|
11
|
+
<td>Variables:</td>
|
|
12
|
+
<td><textarea id="query_variables" class="form-control">{{ object.variables|render_json:False }}</textarea></td>
|
|
13
|
+
</tr>
|
|
14
|
+
</table>
|
|
15
|
+
{% endif %}
|
|
16
|
+
<div class="card-footer">
|
|
17
|
+
<pre id="query_output" class="p-5">
|
|
18
|
+
|
|
19
|
+
</pre>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
function fillQueryOutput(data) {
|
|
25
|
+
const queryOutput = document.querySelector('#query_output');
|
|
26
|
+
|
|
27
|
+
[...queryOutput.childNodes].forEach(childNode => childNode.remove());
|
|
28
|
+
|
|
29
|
+
const code = document.createElement('code');
|
|
30
|
+
code.classList.add('language-json');
|
|
31
|
+
code.textContent = JSON.stringify(data, undefined, 2);
|
|
32
|
+
|
|
33
|
+
queryOutput.appendChild(code);
|
|
34
|
+
|
|
35
|
+
hljs.highlightElement(code);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function test_query() {
|
|
39
|
+
const variables = document.querySelector('#query_variables')?.value;
|
|
40
|
+
|
|
41
|
+
$.ajax({
|
|
42
|
+
url: "{% url 'graphql' %}",
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: {"X-CSRFTOKEN": "{{ csrf_token }}"},
|
|
45
|
+
dataType: "json",
|
|
46
|
+
data: {
|
|
47
|
+
"query": `{{ object.query | escapejs }}`,
|
|
48
|
+
"variables": variables,
|
|
49
|
+
},
|
|
50
|
+
success: function(data) {
|
|
51
|
+
fillQueryOutput(data);
|
|
52
|
+
},
|
|
53
|
+
error: function(error) {
|
|
54
|
+
console.log(error);
|
|
55
|
+
fillQueryOutput(error.responseJSON);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
window.addEventListener("load", () => {
|
|
61
|
+
textarea = document.querySelector("#query_variables");
|
|
62
|
+
textarea.addEventListener('input', autoResize, false);
|
|
63
|
+
textarea.style.height = 'auto';
|
|
64
|
+
textarea.style.height = textarea.scrollHeight + 'px';
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
function autoResize() {
|
|
68
|
+
this.style.height = 'auto';
|
|
69
|
+
this.style.height = this.scrollHeight + 'px';
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
@@ -19,9 +19,21 @@
|
|
|
19
19
|
<header class="nb-tile-header">
|
|
20
20
|
<h3>{{ row.record.grouping|bettertitle }}</h3>
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
22
|
+
{% if perms.extras.run_job and row.record.runnable %}
|
|
23
|
+
<a href="{% url 'extras:job_run' pk=row.record.pk %}"
|
|
24
|
+
class="btn btn-primary btn-sm"
|
|
25
|
+
data-bs-toggle="tooltip"
|
|
26
|
+
data-bs-title="Run/Schedule">
|
|
27
|
+
<span class="mdi mdi-play" aria-hidden="true"><span class="visually-hidden">Run/Schedule</span></span>
|
|
28
|
+
</a>
|
|
29
|
+
{% else %}
|
|
30
|
+
<a aria-disabled="true"
|
|
31
|
+
class="btn btn-primary btn-sm disabled"
|
|
32
|
+
data-bs-toggle="tooltip"
|
|
33
|
+
data-bs-title="Run/Schedule">
|
|
34
|
+
<span class="mdi mdi-play" aria-hidden="true"><span class="visually-hidden">Run/Schedule</span></span>
|
|
35
|
+
</a>
|
|
36
|
+
{% endif %}
|
|
25
37
|
|
|
26
38
|
{% comment "TODO(norbert-mieczkowski-codilime): use the same buttons (actions) in tables and tiles when tables support dropdown menus" %}
|
|
27
39
|
{% for item in row.items %}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
{% load helpers %}
|
|
1
2
|
<div class="float-end">
|
|
2
|
-
<div class="btn-group btn-group-
|
|
3
|
-
<a href="
|
|
4
|
-
|
|
3
|
+
<div class="btn-group btn-group-sm" role="group">
|
|
4
|
+
<a href="{% django_querystring format='json' %}"
|
|
5
|
+
class="btn btn-primary{% if format == 'json' %} bg-primary nb-text-body-bg{% endif %}">
|
|
6
|
+
<span class="mdi mdi-code-json" aria-hidden="true"></span> JSON
|
|
7
|
+
</a>
|
|
8
|
+
<a href="{% django_querystring format='yaml' %}"
|
|
9
|
+
class="btn btn-primary{% if format == 'yaml' %} bg-primary nb-text-body-bg{% endif %}">
|
|
10
|
+
<span class="mdi mdi-format-list-group" aria-hidden="true"></span> YAML
|
|
11
|
+
</a>
|
|
5
12
|
</div>
|
|
6
13
|
</div>
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
{% load form_helpers %}
|
|
2
2
|
|
|
3
|
-
<div class="mb-10 d-flex justify-content-center{% if field.errors %} has-error{% endif %}">
|
|
3
|
+
<div class="mb-10 d-lg-flex justify-content-center{% if field.errors %} has-error{% endif %}">
|
|
4
4
|
<label class="col-lg-3 col-form-label{% if field.field.required %} nb-required{% endif %}" for="{{ field.id_for_label }}">
|
|
5
5
|
{{ field.label }}
|
|
6
6
|
</label>
|
|
7
|
-
<div class="col-lg-3">
|
|
8
|
-
<div class="form-check{% if override_field.errors %} has-error{% endif %}">
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
<div class="col-lg-3 pe-lg-10">
|
|
8
|
+
<div class="form-check my-6{% if override_field.errors %} has-error{% endif %}">
|
|
9
|
+
{{ override_field }}
|
|
10
|
+
<label class="form-check-label" for="{{ override_field.id_for_label }}">
|
|
11
11
|
<i>Override default value</i>
|
|
12
|
+
{% if override_field.help_text %}
|
|
13
|
+
<span class="form-text">{{ override_field.help_text|safe }}</span>
|
|
14
|
+
{% endif %}
|
|
12
15
|
</label>
|
|
13
|
-
{% if override_field.help_text %}
|
|
14
|
-
<span class="form-text">{{ override_field.help_text|safe }}</span>
|
|
15
|
-
{% endif %}
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="col-lg-6">
|
|
19
19
|
{% if field|widget_type == 'checkboxinput' %}
|
|
20
|
-
<div class="form-check{% if field.errors %} has-error{% endif %}">
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
<div class="form-check my-6{% if field.errors %} has-error{% endif %}">
|
|
21
|
+
{{ field }}
|
|
22
|
+
<label class="form-check-label" for="{{ field.id_for_label }}">
|
|
23
|
+
{{ field.label }}
|
|
24
|
+
{% if field.help_text %}<span class="form-text">{{ field.help_text|safe }}</span>{% endif %}
|
|
23
25
|
</label>
|
|
24
|
-
{% if field.help_text %}<span class="form-text">{{ field.help_text|safe }}</span>{% endif %}
|
|
25
26
|
</div>
|
|
26
27
|
{% else %}
|
|
27
28
|
{{ field }}
|
|
@@ -14,17 +14,10 @@
|
|
|
14
14
|
<li class="breadcrumb-item">Submission and Scheduling</li>
|
|
15
15
|
</ol>
|
|
16
16
|
</div>
|
|
17
|
-
<div>
|
|
18
|
-
<h1 class="mb-16">{{ job_model }}</h1>
|
|
19
|
-
{% if job_model.read_only %}
|
|
20
|
-
<span class="badge bg-body-secondary border">Read-only</span>
|
|
21
|
-
{% endif %}
|
|
22
|
-
<p>{{ job_model.description | render_markdown }}</p>
|
|
23
|
-
</div>
|
|
24
17
|
<form action="" method="post" enctype="multipart/form-data" class="h-100 vstack">
|
|
25
18
|
{% csrf_token %}
|
|
26
|
-
<div class="row
|
|
27
|
-
<div class="col-xl-8
|
|
19
|
+
<div class="row justify-content-center flex-fill">
|
|
20
|
+
<div class="col-xl-8 col-lg-10">
|
|
28
21
|
{% if not perms.extras.run_job %}
|
|
29
22
|
<div class="alert alert-warning">
|
|
30
23
|
<span aria-hidden="true" class="mdi mdi-alert"></span>
|
|
@@ -40,6 +33,11 @@
|
|
|
40
33
|
<span aria-hidden="true" class="mdi mdi-alert"></span> This job is not enabled to be run.
|
|
41
34
|
</div>
|
|
42
35
|
{% endif %}
|
|
36
|
+
{% if job_model.read_only %}
|
|
37
|
+
<div class="alert alert-info">
|
|
38
|
+
<span aria-hidden="true" class="mdi mdi-info"></span>This job is read-only in its operation.
|
|
39
|
+
</div>
|
|
40
|
+
{% endif %}
|
|
43
41
|
{% if job_form.non_field_errors or schedule_form.non_field_errors %}
|
|
44
42
|
<div class="card border-danger">
|
|
45
43
|
<div class="card-header bg-danger-subtle border-danger text-body">
|
|
@@ -88,7 +86,7 @@
|
|
|
88
86
|
id="id__run"
|
|
89
87
|
name="_run"
|
|
90
88
|
type="submit"
|
|
91
|
-
{% if not perms.extras.run_job or not job_model.runnable %}disabled
|
|
89
|
+
{% if not perms.extras.run_job or not job_model.runnable %}disabled{% endif %}
|
|
92
90
|
>
|
|
93
91
|
<span aria-hidden="true" class="mdi mdi-play me-4"></span><!--
|
|
94
92
|
-->Run Job Now
|
|
@@ -147,13 +145,32 @@
|
|
|
147
145
|
|
|
148
146
|
// Toggle schedule name and schedule time field rows.
|
|
149
147
|
['#id__schedule_name', '#id__schedule_start_time'].forEach((selector) => {
|
|
150
|
-
const
|
|
148
|
+
const input = document.querySelector(selector);
|
|
149
|
+
const row = input?.parentElement.parentElement;
|
|
151
150
|
row.classList.toggle('d-none', immediately);
|
|
151
|
+
const label = row.querySelector('label');
|
|
152
|
+
|
|
153
|
+
label?.classList.toggle('nb-required', !immediately);
|
|
154
|
+
if (immediately) {
|
|
155
|
+
input.removeAttribute('required');
|
|
156
|
+
} else {
|
|
157
|
+
input.setAttribute('required', '');
|
|
158
|
+
}
|
|
152
159
|
});
|
|
153
160
|
|
|
154
161
|
// Toggle custom crontab field row.
|
|
155
|
-
|
|
162
|
+
input = document.querySelector('#id__recurrence_custom_time')
|
|
163
|
+
const row = input.parentElement.parentElement;
|
|
156
164
|
row.classList.toggle('d-none', !custom);
|
|
165
|
+
const label = row.querySelector('label');
|
|
166
|
+
|
|
167
|
+
label?.classList.toggle('nb-required', custom);
|
|
168
|
+
if (!custom) {
|
|
169
|
+
input.removeAttribute('required');
|
|
170
|
+
} else {
|
|
171
|
+
input.setAttribute('required', '');
|
|
172
|
+
}
|
|
173
|
+
|
|
157
174
|
};
|
|
158
175
|
|
|
159
176
|
{% if job_model.has_sensitive_variables %}
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
{% extends 'generic/object_bulk_update.html' %}
|
|
2
2
|
{% load form_helpers %}
|
|
3
3
|
|
|
4
|
+
{% block extra_styles %}
|
|
5
|
+
<style>
|
|
6
|
+
tr a.job_run {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
gap: 0.625rem; /* 10px */
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
tr a.job_run .btn {
|
|
12
|
+
align-self: flex-start;
|
|
13
|
+
margin-block: -0.09375rem; /* -1.5px */
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
tr :last-child {
|
|
17
|
+
margin-bottom: 0;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
20
|
+
{% endblock %}
|
|
21
|
+
|
|
4
22
|
{% block form_fields %}
|
|
5
23
|
{% render_field form.enabled %}
|
|
6
24
|
{% include "extras/inc/bulk_edit_overridable_field.html" with field=form.grouping override_field=form.clear_grouping_override %}
|