From 116c395948c5034dc069cf233a2ad319e623757c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 12 Aug 2019 11:57:48 -0400 Subject: [PATCH] Fixes #3422: Prevent navigation menu from overlapping page content --- CHANGELOG.md | 1 + netbox/project-static/css/base.css | 8 ++-- netbox/scripts/examples.py | 66 ++++++++++++++++++++++++++++++ netbox/scripts/myscripts.py | 54 ++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 netbox/scripts/examples.py create mode 100644 netbox/scripts/myscripts.py diff --git a/CHANGELOG.md b/CHANGELOG.md index eaf8cd930..6e049b645 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ v2.6.3 (FUTURE) ## Bug Fixes * [#3405](https://github.com/netbox-community/netbox/issues/3405) - Fix population of power port/outlet details on device creation +* [#3422](https://github.com/netbox-community/netbox/issues/3422) - Prevent navigation menu from overlapping page content --- diff --git a/netbox/project-static/css/base.css b/netbox/project-static/css/base.css index fcee05e12..d625b9d68 100644 --- a/netbox/project-static/css/base.css +++ b/netbox/project-static/css/base.css @@ -42,8 +42,8 @@ footer p { } } -/* Hide the search bar in the navigation menu on displays less than 1200px wide */ -@media (max-width: 1199px) { +/* Hide the search bar in the navigation menu on displays less than 1250px wide */ +@media (max-width: 1249px) { #navbar_search { display: none; } @@ -62,8 +62,8 @@ footer p { } } -/* Collapse the nav menu on displays less than 960px wide */ -@media (max-width: 959px) { +/* Collapse the nav menu on displays less than 980px wide */ +@media (max-width: 979px) { .navbar-header { float: none; } diff --git a/netbox/scripts/examples.py b/netbox/scripts/examples.py new file mode 100644 index 000000000..b2adf8da4 --- /dev/null +++ b/netbox/scripts/examples.py @@ -0,0 +1,66 @@ +from django.utils.text import slugify + +from dcim.constants import * +from dcim.models import Device, DeviceRole, DeviceType, Site +from extras.scripts import * + + +class NewBranchScript(Script): + script_name = "New Branch" + script_description = "Provision a new branch site" + script_fields = ['site_name', 'switch_count', 'switch_model'] + + site_name = StringVar( + description="Name of the new site" + ) + switch_count = IntegerVar( + description="Number of access switches to create" + ) + switch_model = ObjectVar( + description="Access switch model", + queryset=DeviceType.objects.filter( + manufacturer__name='Cisco', + model__in=['Catalyst 3560X-48T', 'Catalyst 3750X-48T'] + ) + ) + x = BooleanVar( + description="Check me out" + ) + + def run(self, data): + + # Create the new site + site = Site( + name=data['site_name'], + slug=slugify(data['site_name']), + status=SITE_STATUS_PLANNED + ) + site.save() + self.log_success("Created new site: {}".format(site)) + + # Create access switches + switch_role = DeviceRole.objects.get(name='Access Switch') + for i in range(1, data['switch_count'] + 1): + switch = Device( + device_type=data['switch_model'], + name='{}-switch{}'.format(site.slug, i), + site=site, + status=DEVICE_STATUS_PLANNED, + device_role=switch_role + ) + switch.save() + self.log_success("Created new switch: {}".format(switch)) + + # Generate a CSV table of new devices + output = [ + 'name,make,model' + ] + for switch in Device.objects.filter(site=site): + attrs = [ + switch.name, + switch.device_type.manufacturer.name, + switch.device_type.model + ] + output.append(','.join(attrs)) + + return '\n'.join(output) diff --git a/netbox/scripts/myscripts.py b/netbox/scripts/myscripts.py new file mode 100644 index 000000000..f3542c368 --- /dev/null +++ b/netbox/scripts/myscripts.py @@ -0,0 +1,54 @@ +from dcim.models import Site +from extras.scripts import Script, BooleanVar, IntegerVar, ObjectVar, StringVar + + +class NoInputScript(Script): + description = "This script does not require any input" + + def run(self, data): + + self.log_debug("This a debug message.") + self.log_info("This an info message.") + self.log_success("This a success message.") + self.log_warning("This a warning message.") + self.log_failure("This a failure message.") + + +class DemoScript(Script): + name = "Script Demo" + description = "A quick demonstration of the available field types" + + my_string1 = StringVar( + description="Input a string between 3 and 10 characters", + min_length=3, + max_length=10 + ) + my_string2 = StringVar( + description="This field enforces a regex: three letters followed by three numbers", + regex=r'[a-z]{3}\d{3}' + ) + my_number = IntegerVar( + description="Pick a number between 1 and 255 (inclusive)", + min_value=1, + max_value=255 + ) + my_boolean = BooleanVar( + description="Use the checkbox to toggle true/false" + ) + my_object = ObjectVar( + description="Select a NetBox site", + queryset=Site.objects.all() + ) + + def run(self, data): + + self.log_info("Your string was {}".format(data['my_string1'])) + self.log_info("Your second string was {}".format(data['my_string2'])) + self.log_info("Your number was {}".format(data['my_number'])) + if data['my_boolean']: + self.log_info("You ticked the checkbox") + else: + self.log_info("You did not tick the checkbox") + self.log_info("You chose the sites {}".format(data['my_object'])) + + return "Here's some output"