internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: nautobot/nautobot

Issue:
GraphiQL interface save query function giving error
<!--
    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.

    This form is only for reporting reproducible bugs. If you need assistance
    with Nautobot installation, or if you have a general question, please start a
    discussion instead: https://github.com/nautobot/nautobot/discussions

    Please describe the environment in which you are running Nautobot. Be sure
    that you are running an unmodified instance of the latest stable release
    before submitting a bug report, and that any plugins have been disabled.
-->
### Environment
* Nautobot version (Docker tag too if applicable): 1.6.2
* Python version: 3.9.16
* Database platform, version: postgres 
* Middleware(s): n/a

<!--
    Describe in detail the exact steps that someone else can take to reproduce
    this bug using the current stable release of Nautobot. Begin with the
    creation of any necessary database objects and call out every operation
    being performed explicitly. If reporting a bug in the REST API, be sure to
    reconstruct the raw HTTP request(s) being made: Don't rely on a client
    library such as pynautobot.
-->
### Steps to Reproduce
1. Have an existing saved Graphql query (initially from an earlier version of Nautobot)
2. Using the Graphiql interface
3. Update the query with a new value or delete a value
4. Attempt to save the query and observe the error

*note* the saved query editor in the primary Nautobot GUI works

<!-- What did you expect to happen? -->
### Expected Behavior
Query to save

<!-- What happened instead? -->
### Observed Behavior
An error:

<img width="815" alt="Screenshot 2023-10-04 at 21 26 48" src="https://github.com/nautobot/nautobot/assets/10200477/2f1f2b2e-f94e-412e-9be4-d2e5c6b8a9c1">



Discussion:
A workaround is to use the Saved Graphql queries under Extensibility top level menu item, but this is a nicer interface.
Can confirm still reproducible in 2.1.0.

Resolving patch:
diff --git a/nautobot/extras/api/serializers.py b/nautobot/extras/api/serializers.py
--- a/nautobot/extras/api/serializers.py
+++ b/nautobot/extras/api/serializers.py
@@ -342,7 +342,7 @@ class Meta:
 
 
 class GraphQLQuerySerializer(ValidatedModelSerializer, NotesSerializerMixin):
-    variables = serializers.DictField(required=False, allow_null=True, default={})
+    variables = serializers.DictField(read_only=True)
 
     class Meta:
         model = GraphQLQuery


Test patch:
Repository: nautobot/nautobot

Issue:
Job Hook Receivers and Job Button Receivers are not easily visible in Jobs list in the UI
### As ...

Ozzie - Operator

### I want ...

I'd like to be able to see all the Jobs in the Job list UI, including 'hidden' jobs such as a job hook receiver job. Currently you have to jump through a number of hoops in order to see the job details for job hook receiver and job button receiver jobs, as they're being hidden by the code base.

Relevant chunk of code: https://github.com/nautobot/nautobot/blob/develop/nautobot/extras/views.py#L1057-L1065

### So that ...

It's hard to determine all the jobs that exist when certain types of jobs are hidden.


### I know this is done when...

I can see job hook receiver jobs in the Jobs list UI.

### Optional - Feature groups this request pertains to.

- [X] Automation
- [ ] Circuits
- [ ] DCIM
- [ ] IPAM
- [ ] Misc (including Data Sources)
- [ ] Organization
- [X] Plugins (and other Extensibility)
- [ ] Security (Secrets, etc)
- [ ] Image Management
- [X] UI/UX
- [ ] Documentation
- [ ] Other (not directly a platform feature)

### Database Changes

Database does not need any changes.

### External Dependencies

N/A


Discussion:

Resolving patch:
diff --git a/nautobot/extras/views.py b/nautobot/extras/views.py
--- a/nautobot/extras/views.py
+++ b/nautobot/extras/views.py
@@ -1054,15 +1054,11 @@ class JobListView(generic.ObjectListView):
 
     def alter_queryset(self, request):
         queryset = super().alter_queryset(request)
-        # Default to hiding "hidden", non-installed jobs and job hook receivers
+        # Default to hiding "hidden" and non-installed jobs
         if "hidden" not in request.GET:
             queryset = queryset.filter(hidden=False)
         if "installed" not in request.GET:
             queryset = queryset.filter(installed=True)
-        if "is_job_hook_receiver" not in request.GET:
-            queryset = queryset.filter(is_job_hook_receiver=False)
-        if "is_job_button_receiver" not in request.GET:
-            queryset = queryset.filter(is_job_button_receiver=False)
         queryset = queryset.prefetch_related("results")
         return queryset
 


Test patch:
Repository: nautobot/nautobot

Issue:
ExternalIntegration missing Q filter for API
<!--
    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.

    This form is only for reporting reproducible bugs. If you need assistance
    with Nautobot installation, or if you have a general question, please start a
    discussion instead: https://github.com/nautobot/nautobot/discussions

    Please describe the environment in which you are running Nautobot. Be sure
    that you are running an unmodified instance of the latest stable release
    before submitting a bug report, and that any plugins have been disabled.
-->
### Environment
* Nautobot version (Docker tag too if applicable): 2.1.0
* Python version: 3.11
* Database platform, version: NA
* Middleware(s):

<!--
    Describe in detail the exact steps that someone else can take to reproduce
    this bug using the current stable release of Nautobot. Begin with the
    creation of any necessary database objects and call out every operation
    being performed explicitly. If reporting a bug in the REST API, be sure to
    reconstruct the raw HTTP request(s) being made: Don't rely on a client
    library such as pynautobot.
-->
### Steps to Reproduce
1. Create job using ObjectVar pointing ExternalIntegration
2. Attempt to select an existing ExternalINtegration on the job form
3.

<!-- What did you expect to happen? -->
### Expected Behavior
API call returns 200 with paginated instances

<!-- What happened instead? -->
### Observed Behavior
API call returns 400 with an error similar to `q filter unknown`


Discussion:

Resolving patch:
diff --git a/nautobot/extras/filters/__init__.py b/nautobot/extras/filters/__init__.py
--- a/nautobot/extras/filters/__init__.py
+++ b/nautobot/extras/filters/__init__.py
@@ -493,6 +493,12 @@ class Meta:
 
 
 class ExternalIntegrationFilterSet(NautobotFilterSet):
+    q = SearchFilter(
+        filter_predicates={
+            "name": "icontains",
+            "remote_url": "icontains",
+        },
+    )
     has_secrets_group = RelatedMembershipBooleanFilter(
         field_name="secrets_group",
         label="Has secrets group",


Test patch:
Repository: nautobot/nautobot

Issue:
Add device type table to hardwarefamily detail view
Leave the row in the table with the link to the filtered results but also add a table of the device types to the detail view



Discussion:

Resolving patch:
diff --git a/nautobot/dcim/views.py b/nautobot/dcim/views.py
--- a/nautobot/dcim/views.py
+++ b/nautobot/dcim/views.py
@@ -2947,6 +2947,27 @@ class HardwareFamilyUIViewSet(NautobotUIViewSet):
     table_class = tables.HardwareFamilyTable
     lookup_field = "pk"
 
+    def get_extra_context(self, request, instance):
+        # Related device types table
+        context = super().get_extra_context(request, instance)
+        if self.action == "retrieve":
+            device_types = (
+                DeviceType.objects.restrict(request.user, "view")
+                .filter(hardware_family=instance)
+                .select_related("manufacturer")
+                .annotate(device_count=count_related(Device, "device_type"))
+            )
+            device_type_table = tables.DeviceTypeTable(device_types, orderable=False)
+
+            paginate = {
+                "paginator_class": EnhancedPaginator,
+                "per_page": get_paginate_count(request),
+            }
+            RequestConfig(request, paginate).configure(device_type_table)
+
+            context["device_type_table"] = device_type_table
+        return context
+
 
 #
 # Software images


Test patch:
Repository: nautobot/nautobot

Issue:
Contacts/Teams UI updates
Feedback from Sprint Review:

- Remove "Add Contact" button from the standard buttons in the detail views, use a button in the Contacts tab instead
- Change “Assign an existing contact/team” UI buttons text from “Create” to some other text (“Assign”?)
- On the contacts table, break out Contact/Team column into a separate column and rename the columns to "Type" and "Name"
- Change the table header from "Contact/Teams" to just "Contacts"


Discussion:

Resolving patch:
diff --git a/nautobot/extras/tables.py b/nautobot/extras/tables.py
--- a/nautobot/extras/tables.py
+++ b/nautobot/extras/tables.py
@@ -52,9 +52,16 @@
 )
 from .registry import registry
 
+CONTACT_OR_TEAM_ICON = """
+{% if record.contact %}
+<i class="mdi mdi-account" title="Contact"></i>
+{% else %}
+<i class="mdi mdi-account-group" title="Team"></i>
+{% endif %}
+"""
+
 CONTACT_OR_TEAM = """
 {% load helpers %}
-<i class="mdi {% if record.contact %}mdi-account{% else %}mdi-account-group{% endif %}"></i>
 {{ record.contact_or_team|hyperlinked_object:"name"}}
 """
 
@@ -1142,7 +1149,10 @@ class Meta(BaseTable.Meta):
 
 class AssociatedContactsTable(StatusTableMixin, RoleTableMixin, BaseTable):
     pk = ToggleColumn()
-    contact_or_team = tables.TemplateColumn(CONTACT_OR_TEAM, verbose_name="Contact/Team")
+    contact_type = tables.TemplateColumn(
+        CONTACT_OR_TEAM_ICON, verbose_name="Type", attrs={"td": {"style": "width:20px;"}}
+    )
+    name = tables.TemplateColumn(CONTACT_OR_TEAM, verbose_name="Name")
     contact_or_team_phone = tables.TemplateColumn(PHONE, accessor="contact_or_team.phone", verbose_name="Phone")
     contact_or_team_email = tables.TemplateColumn(EMAIL, accessor="contact_or_team.email", verbose_name="E-Mail")
     actions = actions = ButtonsColumn(model=ContactAssociation, buttons=("edit", "delete"))
@@ -1151,7 +1161,8 @@ class Meta(BaseTable.Meta):
         model = ContactAssociation
         fields = (
             "pk",
-            "contact_or_team",
+            "contact_type",
+            "name",
             "status",
             "role",
             "contact_or_team_phone",
@@ -1160,7 +1171,8 @@ class Meta(BaseTable.Meta):
         )
         default_columns = [
             "pk",
-            "contact_or_team",
+            "contact_type",
+            "name",
             "status",
             "role",
             "contact_or_team_phone",


Test patch:
Repository: nautobot/nautobot

Issue:
Invalid Device Filter on Add Interface to Interface Redundancy Group
<!--
    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.

    This form is only for reporting reproducible bugs. If you need assistance
    with Nautobot installation, or if you have a general question, please start a
    discussion instead: https://github.com/nautobot/nautobot/discussions

    Please describe the environment in which you are running Nautobot. Be sure
    that you are running an unmodified instance of the latest stable release
    before submitting a bug report, and that any plugins have been disabled.
-->
### Environment
* Nautobot version (Docker tag too if applicable): 2.1.2
* Python version: 3.11
* Database platform, version: psql
* Middleware(s): na

<!--
    Describe in detail the exact steps that someone else can take to reproduce
    this bug using the current stable release of Nautobot. Begin with the
    creation of any necessary database objects and call out every operation
    being performed explicitly. If reporting a bug in the REST API, be sure to
    reconstruct the raw HTTP request(s) being made: Don't rely on a client
    library such as pynautobot.
-->
### Steps to Reproduce
1. Create Interface Redundancy Group
2. Attempt to add interface to group
3. select location
4. click device menu

<!-- What did you expect to happen? -->
### Expected Behavior
Location UUID is passed to API call for devices using `location` param


<!-- What happened instead? -->
### Observed Behavior
Location UUID is passed to API call for devices using `location_id` param



Discussion:

Resolving patch:
diff --git a/nautobot/dcim/forms.py b/nautobot/dcim/forms.py
--- a/nautobot/dcim/forms.py
+++ b/nautobot/dcim/forms.py
@@ -3606,20 +3606,19 @@ class InterfaceRedundancyGroupAssociationForm(BootstrapMixin, NoteModelFormMixin
     location = DynamicModelChoiceField(
         queryset=Location.objects.all(),
         required=False,
-        query_params={"region_id": "$region"},
     )
     rack = DynamicModelChoiceField(
         queryset=Rack.objects.all(),
         required=False,
         null_option="None",
-        query_params={"location_id": "$location"},
+        query_params={"location": "$location"},
     )
     device = DynamicModelChoiceField(
         queryset=Device.objects.all(),
         required=False,
         query_params={
-            "location_id": "$location",
-            "rack_id": "$rack",
+            "location": "$location",
+            "rack": "$rack",
         },
     )
     interface = DynamicModelChoiceField(


Test patch:
Repository: nautobot/nautobot

Issue:
Job list view refinements
As a network automation engineer, I want a few refinements to the jobs list view, so that the view is more usable when I need to identify jobs I want to run.


- Reduce the size of the grouping headers
- When a job is disabled, grey the row background to more clearly indicate the status
- Change the name hyperlink to route to the job's run page instead of the detail view of the job.
  - Add the "play" button to the beginning of the name text
  - Replace the existing play button on the right with an mdi-information button that links to the job's detail view
  - Something like this:
![Screenshot 2024-01-18 at 10 48 25 AM](https://github.com/nautobot/nautobot/assets/1297132/997e979d-9115-4f4f-8d2e-3d0913f5064b)

Checkboxes are covered in #5126


Discussion:

Resolving patch:
diff --git a/nautobot/extras/tables.py b/nautobot/extras/tables.py
--- a/nautobot/extras/tables.py
+++ b/nautobot/extras/tables.py
@@ -97,7 +97,7 @@
 """
 
 JOB_BUTTONS = """
-<a href="{% url 'extras:job_run' pk=record.pk %}" class="btn btn-primary btn-xs" title="Run/Schedule" {% if not perms.extras.run_job or not record.runnable %}disabled="disabled"{% endif %}><i class="mdi mdi-play" aria-hidden="true"></i></a>
+<a href="{% url 'extras:job' pk=record.pk %}" class="btn btn-primary btn-xs" title="Details"><i class="mdi mdi-information" aria-hidden="true"></i></a>
 """
 
 OBJECTCHANGE_OBJECT = """
@@ -600,7 +600,10 @@ class JobTable(BaseTable):
     # TODO(Glenn): pk = ToggleColumn()
     source = tables.Column()
     # grouping is used to, well, group the Jobs, so it isn't a column of its own.
-    name = tables.Column(linkify=True)
+    name = tables.Column(
+        attrs={"a": {"class": "job_run", "title": "Run/Schedule"}},
+        linkify=("extras:job_run", {"pk": tables.A("pk")}),
+    )
     installed = BooleanColumn()
     enabled = BooleanColumn()
     has_sensitive_variables = BooleanColumn()
@@ -634,6 +637,9 @@ class JobTable(BaseTable):
     def render_description(self, value):
         return render_markdown(value)
 
+    def render_name(self, value):
+        return format_html('<span class="btn btn-primary btn-xs"><i class="mdi mdi-play"></i></span>{}', value)
+
     class Meta(BaseTable.Meta):
         model = JobModel
         orderable = False


Test patch:
Repository: nautobot/nautobot

Issue:
Jobs tile view
As a network automation engineer I want a tile based view of jobs as an alternative to the table list view, so that I have a more elegant way to interact with my automations.

I will know this is complete when a user has the ability to toggle between two view options in the jobs list view:
![Screenshot 2024-01-18 at 11 11 29 AM](https://github.com/nautobot/nautobot/assets/1297132/4acef8f7-88c6-40c4-818d-e08cf6493d05)


Create a card element for jobs like this:
![Screenshot 2024-01-18 at 11 10 00 AM](https://github.com/nautobot/nautobot/assets/1297132/8f7a5a53-d25a-49a0-a714-11ed6561d7df)


Create a view which shows these cards, grouped by the existing grouping headers.
![Screenshot 2024-01-18 at 11 12 52 AM](https://github.com/nautobot/nautobot/assets/1297132/521ef719-9b34-4448-82ed-0c091e75a3da)




Out of scope, but in the future, we will do things like allow users to move and reorder the cards in the view to suit their preferences, and save favorited job cards to the top of the page.


Discussion:

Resolving patch:
diff --git a/nautobot/extras/tables.py b/nautobot/extras/tables.py
--- a/nautobot/extras/tables.py
+++ b/nautobot/extras/tables.py
@@ -104,7 +104,7 @@
 """
 
 JOB_BUTTONS = """
-<a href="{% url 'extras:job' pk=record.pk %}" class="btn btn-primary btn-xs" title="Details"><i class="mdi mdi-information" aria-hidden="true"></i></a>
+<a href="{% url 'extras:job' pk=record.pk %}" class="btn btn-default btn-xs" title="Details"><i class="mdi mdi-information-outline" aria-hidden="true"></i></a>
 """
 
 OBJECTCHANGE_OBJECT = """
diff --git a/nautobot/extras/views.py b/nautobot/extras/views.py
--- a/nautobot/extras/views.py
+++ b/nautobot/extras/views.py
@@ -1243,6 +1243,7 @@ class JobListView(generic.ObjectListView):
     filterset = filters.JobFilterSet
     filterset_form = forms.JobFilterForm
     action_buttons = ()
+    non_filter_params = ("display",)
     template_name = "extras/job_list.html"
 
     def alter_queryset(self, request):
@@ -1255,8 +1256,19 @@ def alter_queryset(self, request):
         return queryset
 
     def extra_context(self):
+        # Determine user's preferred display
+        if self.request.GET.get("display") in ["list", "tiles"]:
+            display = self.request.GET.get("display")
+            if self.request.user.is_authenticated:
+                self.request.user.set_config("extras.job.display", display, commit=True)
+        elif self.request.user.is_authenticated:
+            display = self.request.user.get_config("extras.job.display", "list")
+        else:
+            display = "list"
+
         return {
-            "table_inc_template": "extras/inc/job_table.html",
+            "table_inc_template": "extras/inc/job_tiles.html" if display == "tiles" else "extras/inc/job_table.html",
+            "display": display,
         }
 
 


Test patch:
Repository: nautobot/nautobot

Issue:
Implement template tags to render phone and email fields in Django Template,
Some models in Nautobot (Contact, Team, and Location) have non-mandatory phone numbers and emails associated with them. It would be nice not to explicitly render them in one template tag instead of in an if/else block that has multiple lines.

_Originally posted by @glennmatthews in https://github.com/nautobot/nautobot/pull/5069#discussion_r1449221680_
            


Discussion:

Resolving patch:
diff --git a/nautobot/core/templatetags/helpers.py b/nautobot/core/templatetags/helpers.py
--- a/nautobot/core/templatetags/helpers.py
+++ b/nautobot/core/templatetags/helpers.py
@@ -81,6 +81,24 @@ def hyperlinked_object(value, field="display"):
     return format_html("{}", display)
 
 
+@library.filter()
+@register.filter()
+def hyperlinked_email(value):
+    """Render an email address as a `mailto:` hyperlink."""
+    if value is None:
+        return placeholder(value)
+    return format_html('<a href="mailto:{}">{}</a>', value, value)
+
+
+@library.filter()
+@register.filter()
+def hyperlinked_phone_number(value):
+    """Render a phone number as a `tel:` hyperlink."""
+    if value is None:
+        return placeholder(value)
+    return format_html('<a href="tel:{}">{}</a>', value, value)
+
+
 @library.filter()
 @register.filter()
 def placeholder(value):
diff --git a/nautobot/extras/tables.py b/nautobot/extras/tables.py
--- a/nautobot/extras/tables.py
+++ b/nautobot/extras/tables.py
@@ -66,19 +66,13 @@
 """
 
 PHONE = """
-{% if value %}
-    <a href="tel:{{ value }}">{{ value }}</a>
-{% else %}
-    <span class="text-muted">&mdash;</span>
-{% endif %}
+{% load helpers %}
+{{ value|hyperlinked_phone_number }}
 """
 
 EMAIL = """
-{% if value %}
-    <a href="mailto:{{ value }}">{{ value }}</a>
-{% else %}
-    <span class="text-muted">&mdash;</span>
-{% endif %}
+{% load helpers %}
+{{ value|hyperlinked_email }}
 """
 
 TAGGED_ITEM = """


Test patch:
diff --git a/nautobot/core/tests/test_templatetags_helpers.py b/nautobot/core/tests/test_templatetags_helpers.py
--- a/nautobot/core/tests/test_templatetags_helpers.py
+++ b/nautobot/core/tests/test_templatetags_helpers.py
@@ -42,6 +42,16 @@ def test_hyperlinked_object(self):
             f'<a href="/dcim/locations/{location.pk}/" title="An important location">{location!s}</a>',
         )
 
+    def test_hyperlinked_email(self):
+        self.assertEqual(
+            helpers.hyperlinked_email("admin@example.com"), '<a href="mailto:admin@example.com">admin@example.com</a>'
+        )
+        self.assertEqual(helpers.hyperlinked_email(None), '<span class="text-muted">&mdash;</span>')
+
+    def test_hyperlinked_phone_number(self):
+        self.assertEqual(helpers.hyperlinked_phone_number("555-1234"), '<a href="tel:555-1234">555-1234</a>')
+        self.assertEqual(helpers.hyperlinked_phone_number(None), '<span class="text-muted">&mdash;</span>')
+
     def test_placeholder(self):
         self.assertEqual(helpers.placeholder(None), '<span class="text-muted">&mdash;</span>')
         self.assertEqual(helpers.placeholder([]), '<span class="text-muted">&mdash;</span>')
Repository: nautobot/nautobot

Issue:
Update VirtualMachineForm to use `select_reated` when Finding IPs for `primary_ip`
Context: https://github.com/nautobot/nautobot/pull/3399/files#diff-f5bfbf2ee3cfa0511ed857e2999b0d1ddd921289c1b2115df6e286ed1558fca9R306


Discussion:

Resolving patch:
diff --git a/nautobot/virtualization/forms.py b/nautobot/virtualization/forms.py
--- a/nautobot/virtualization/forms.py
+++ b/nautobot/virtualization/forms.py
@@ -258,7 +258,7 @@ def __init__(self, *args, **kwargs):
                 # Collect interface IPs
                 interface_ip_assignments = IPAddressToInterface.objects.filter(
                     vm_interface__in=interface_ids
-                ).prefetch_related("ip_address")
+                ).select_related("ip_address")
                 if interface_ip_assignments.exists():
                     ip_list = [
                         (


Test patch: