Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add link from the NN Re-assigned install to the node that got its number #798

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/meshapi/admin/models/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from simple_history.admin import SimpleHistoryAdmin

from meshapi.models import Install
from meshapi.widgets import ExternalHyperlinkWidget
from meshapi.widgets import ExternalHyperlinkWidget, InstallStatusWidget

from ..ranked_search import RankedSearchMixin

Expand Down Expand Up @@ -40,8 +40,13 @@ class Meta:
lambda ticket_number: f"{OSTICKET_URL}/scp/tickets.php?number={ticket_number}",
title="View in OSTicket",
),
"status": InstallStatusWidget(),
}

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.fields["status"].widget.form_instance = self


@admin.register(Install)
class InstallAdmin(RankedSearchMixin, ImportExportMixin, ExportActionMixin, SimpleHistoryAdmin):
Expand Down
15 changes: 15 additions & 0 deletions src/meshapi/templates/widgets/install_status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% load i18n static %}
<div class="related-widget-wrapper">
{% include "django/forms/widgets/select.html" %}
{% if reassigned_node_id %}
{% block links %}
{% spaceless %}
<a class="related-widget-wrapper-link view-related"
href="/admin/meshapi/node/{{ reassigned_node_id }}"
title="{% blocktranslate %}Show the node that got this install's number{% endblocktranslate %}">
<img src="{% static 'admin/img/icon-viewlink.svg' %}" alt="{% translate 'Navigate' %}">
</a>
{% endspaceless %}
{% endblock %}
{% endif %}
</div>
19 changes: 19 additions & 0 deletions src/meshapi/tests/test_admin_change_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,25 @@ def test_change_building_address(self):
self.assertEqual(building.primary_node, self.node1)
self.assertEqual(list(building.nodes.all()), [self.node1])

def test_install_hyperlinks_to_nn_assigned_node(self):
old_install = Install(**sample_install)
old_install.install_number = 741
old_install.member = self.member
old_install.building = self.building_1
old_install.status = Install.InstallStatus.NN_REASSIGNED
old_install.save()

new_node = Node(**sample_node)
new_node.network_number = old_install.install_number
new_node.save()

change_url = f"/admin/meshapi/install/{old_install.id}/change/"
response = self._call(change_url, 200)
form_soup = bs4.BeautifulSoup(response.content.decode()).find(id="install_form")
link_tag = form_soup.find("select", {"id": "id_status"}).parent.find("a")
self.assertEqual(link_tag.attrs["href"], f"/admin/meshapi/node/{new_node.id}")
self.assertEqual(link_tag.attrs["title"], "Show the node that got this install's number")


class TestAdminAddView(TestCase):
def setUp(self):
Expand Down
22 changes: 22 additions & 0 deletions src/meshapi/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from django_jsonform.widgets import JSONFormWidget
from flags.state import flag_enabled

from meshapi.models import Install, Node


class PanoramaViewer(JSONFormWidget):
pano_template_name = "widgets/panorama_viewer.html"
Expand Down Expand Up @@ -93,6 +95,22 @@ class UISPHyperlinkWidget(widgets.TextInput):
template_name = "widgets/uisp_link.html"


class InstallStatusWidget(widgets.Select):
template_name = "widgets/install_status.html"
form_instance: "InstallAdminForm"

def get_context(self, name: str, value: str, attrs: Optional[dict] = None) -> dict:
context = super().get_context(name, value, attrs)
if self.form_instance:
install = self.form_instance.instance
if install and install.status == Install.InstallStatus.NN_REASSIGNED:
recycled_as_node = Node.objects.filter(network_number=install.install_number).first()
if recycled_as_node:
context["reassigned_node_id"] = str(recycled_as_node.id)

return context


class AutoPopulateLocationWidget(forms.Widget):
template_name = "widgets/auto_populate_location.html"

Expand All @@ -111,3 +129,7 @@ def get_context(self, name: str, value: str, attrs: Optional[dict] = None) -> di
context["auto_populate_source"] = self.source
context["auto_populate_url"] = self.source
return context


# Down here to resolve circular imports
from meshapi.admin.models.install import InstallAdminForm # noqa: E402
WillNilges marked this conversation as resolved.
Show resolved Hide resolved
Loading