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

Allow workspace adapter to specify the template for the workspace list page #531

Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Move most account settings into the Account adapter
* Allow the user to set a custom success message to be displayed after they verify an AnVIL account
* Move the setting to specify the template for account link verification emails into the AccountAdapter
* Allow users to specify the template for the WorkspaceListByType view in the WorkspaceAdapter

## 0.25.0 (2024-08-07)

Expand Down
2 changes: 1 addition & 1 deletion anvil_consortium_manager/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.26.0.dev1"
__version__ = "0.26.0.dev2"
1 change: 1 addition & 0 deletions anvil_consortium_manager/adapters/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ class DefaultWorkspaceAdapter(BaseWorkspaceAdapter):
list_table_class_staff_view = tables.WorkspaceStaffTable
list_table_class_view = tables.WorkspaceUserTable
workspace_detail_template_name = "anvil_consortium_manager/workspace_detail.html"
workspace_list_template_name = "anvil_consortium_manager/workspace_list.html"
3 changes: 3 additions & 0 deletions anvil_consortium_manager/adapters/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
class BaseWorkspaceAdapter(ABC):
"""Base class to inherit when customizing the workspace adapter."""

workspace_list_template_name = "anvil_consortium_manager/workspace_list.html"
""" path to workspace list template"""

@abstractproperty
def name(self):
"""String specifying the namee of this type of workspace."""
Expand Down
17 changes: 17 additions & 0 deletions anvil_consortium_manager/tests/test_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ class TestAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.TestWorkspaceData
workspace_data_form_class = forms.TestWorkspaceDataForm
workspace_detail_template_name = "custom/workspace_detail.html"
workspace_list_template_name = "custom/workspace_list.html"

return TestAdapter

Expand Down Expand Up @@ -532,6 +533,22 @@ def test_get_workspace_detail_template_name_none(self):
with self.assertRaises(ImproperlyConfigured):
TestAdapter().get_workspace_detail_template_name()

def test_get_workspace_list_template_name_default(self):
"""get_workspace_list_template_name returns the correct template using the default adapter."""
self.assertEqual(
DefaultWorkspaceAdapter().workspace_list_template_name,
"anvil_consortium_manager/workspace_list.html",
)

def test_get_workspace_list_template_name_custom(self):
"""get_workspace_list_template_name returns the corret template when using a custom adapter"""
TestAdapter = self.get_test_adapter()
setattr(TestAdapter, "workspace_list_template_name", "foo")
self.assertEqual(
TestAdapter().workspace_list_template_name,
"foo",
)


class WorkspaceAdapterRegistryTest(TestCase):
"""Tests for the WorkspaceAdapterRegstry model."""
Expand Down
3 changes: 3 additions & 0 deletions anvil_consortium_manager/tests/test_app/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class TestWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.TestWorkspaceData
workspace_data_form_class = forms.TestWorkspaceDataForm
workspace_detail_template_name = "test_workspace_detail.html"
workspace_list_template_name = "test_workspace_list.html"

def get_autocomplete_queryset(self, queryset, q, forwarded={}):
billing_project = forwarded.get("billing_project", None)
Expand Down Expand Up @@ -74,6 +75,7 @@ class TestForeignKeyWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.TestForeignKeyWorkspaceData
workspace_data_form_class = forms.TestForeignKeyWorkspaceDataForm
workspace_detail_template_name = "workspace_detail.html"
workspace_list_template_name = "workspace_list.html"


class TestWorkspaceMethodsAdapter(BaseWorkspaceAdapter):
Expand All @@ -88,6 +90,7 @@ class TestWorkspaceMethodsAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.TestWorkspaceMethodsData
workspace_data_form_class = forms.TestWorkspaceMethodsForm
workspace_detail_template_name = "workspace_detail.html"
workspace_list_template_name = "workspace_list.html"


class TestBeforeWorkspaceCreateAdapter(TestWorkspaceMethodsAdapter):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "anvil_consortium_manager/base.html" %}
{% load static %}

{% load render_table from django_tables2 %}
{% load crispy_forms_tags %}

{% block title %}{{workspace_type_display_name}}s{% endblock %}

{% block content %}

<div class="row">
<div class="col-sm-12">

<h2>{{workspace_type_display_name}}s</h2>

<div class="container pt-3">
{% crispy filter.form %}
</div>

{% render_table table %}

</div>
</div>

</div>

{% endblock content %}
14 changes: 14 additions & 0 deletions anvil_consortium_manager/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11781,6 +11781,20 @@ def test_view_with_filter_returns_mutiple_objects(self):
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

def test_view_with_default_adapter_use_default_workspace_list_template(self):
default_type = DefaultWorkspaceAdapter().get_type()
self.client.force_login(self.view_user)
response = self.client.get(self.get_url(default_type))
self.assertTemplateUsed(response, "anvil_consortium_manager/workspace_list.html")

def test_view_with_custom_adapter_use_custom_workspace_list_template(self):
workspace_adapter_registry.unregister(DefaultWorkspaceAdapter)
workspace_adapter_registry.register(TestWorkspaceAdapter)
self.workspace_type = TestWorkspaceAdapter().get_type()
self.client.force_login(self.view_user)
response = self.client.get(self.get_url(self.workspace_type))
self.assertTemplateUsed(response, "test_workspace_list.html")


class WorkspaceDeleteTest(AnVILAPIMockTestMixin, TestCase):
api_success_code = 202
Expand Down
5 changes: 4 additions & 1 deletion anvil_consortium_manager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,6 @@ class WorkspaceListByType(
"billing_project__name",
"name",
)
template_name = "anvil_consortium_manager/workspace_list.html"
filterset_class = filters.WorkspaceListFilter

def get_queryset(self):
Expand All @@ -1540,6 +1539,10 @@ def get_table_class(self):
else:
return self.adapter.get_list_table_class_view()

def get_template_names(self):
"""Return the workspace list template name specified in the adapter."""
return [self.adapter.workspace_list_template_name]


class WorkspaceDelete(auth.AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, DeleteView):
model = models.Workspace
Expand Down
4 changes: 4 additions & 0 deletions docs/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ Next, set up the adapter by subclassing :class:`~anvil_consortium_manager.adapte
* ``list_table_class_view``: the table to use to display the list of workspaces for non-Staff Viewers.
* ``workspace_detail_template_name``: the template to use to render the detail of the workspace

The following attribute for WorkspaceListByType view has a default, but can be overridden:
* ``workspace_list_template_name``: a path to the template to use to render the list of the workspace

You may also override default settings and methods:

- ``get_autocomplete_queryset``: a method to filter a workspace queryset for use in the :class:`~anvil_consortium_manager.views.WorkspaceAutocompleteByType` view. This queryset passed to this method is the workspace data model specified by the adapter, not the `Workspace` model.
Expand Down Expand Up @@ -152,6 +155,7 @@ Here is example of the custom adapter for ``my_app`` with the model, form and ta
workspace_data_model = models.CustomWorkspaceData
workspace_data_form_class = forms.CustomWorkspaceDataForm
workspace_detail_template_name = "my_app/custom_workspace_detail.html"
workspace_list_template_name = "my_app/custom_workspace_list.html"

Finally, to tell the app to use this adapter, set ``ANVIL_WORKSPACE_ADAPTERS`` in your settings file, e.g.: ``ANVIL_WORKSPACE_ADAPTERS = ["my_app.adapters.CustomWorkspaceAdapter"]``.

Expand Down
1 change: 1 addition & 0 deletions example_site/app/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CustomWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.CustomWorkspaceData
workspace_data_form_class = forms.CustomWorkspaceDataForm
workspace_detail_template_name = "app/custom_workspace_detail.html"
workspace_list_template_name = "app/custom_workspace_list.html"

def before_anvil_create(self, workspace):
"""Add authorization domain to workspace."""
Expand Down