diff --git a/config/settings/base.py b/config/settings/base.py index a26d4d3..811b9aa 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -132,7 +132,7 @@ ] AUTH_USER_MODEL = "users.User" -LOGIN_REDIRECT_URL = "wagtailadmin_home" +LOGIN_REDIRECT_URL = "wagtailadmin_login_redirect" LOGIN_URL = "wagtailadmin_login" # PASSWORDS diff --git a/config/urls.py b/config/urls.py index cd086a1..652c909 100644 --- a/config/urls.py +++ b/config/urls.py @@ -25,6 +25,7 @@ SignedURLView, media_index, ) +from mycarehub.users.views import CustomLoginView, login_redirect urlpatterns = [ path("sysadmin/", HomeView.as_view(), name="home"), @@ -124,6 +125,8 @@ path("admin/images/", CustomImageIndexView.as_view(), name="wagtailimages-index"), path("admin/media/", media_index, name="wagtailmedia-index"), path("admin/documents/", CustomDocumentIndexView.as_view(), name="wagtaildocs-index"), + path("admin/login/", CustomLoginView.as_view(), name="wagtailadmin_login"), + path("admin/redirect/", login_redirect, name="wagtailadmin_redirect"), path("admin/", include(wagtailadmin_urls)), path("documents/", include(wagtaildocs_urls)), re_path( diff --git a/mycarehub/conftest.py b/mycarehub/conftest.py index 293fda6..6311b2a 100644 --- a/mycarehub/conftest.py +++ b/mycarehub/conftest.py @@ -194,7 +194,7 @@ def content_item_with_tag_and_category(content_item_index, program, facility): def initial_sms_content_item(content_item_index, sms_category, sms_tag, request_with_user): """Initial SMS content item fixture.""" initial_sms_content_item = SMSContentItem( - content="This is some sample content for testing purposes", + body="This is some sample content for testing purposes", category=sms_category, tag=sms_tag, ) @@ -211,7 +211,7 @@ def initial_sms_content_item(content_item_index, sms_category, sms_tag, request_ def sms_content_item(content_item_index, sms_category, sms_tag, request_with_user): """Subsequent SMS content item fixture.""" sms_content_item = SMSContentItem( - content="Hello is some sample content for testing purposes", + body="Hello is some sample content for testing purposes", category=sms_category, tag=sms_tag, ) diff --git a/mycarehub/content/migrations/0018_rename_content_smscontentitem_body.py b/mycarehub/content/migrations/0018_rename_content_smscontentitem_body.py new file mode 100644 index 0000000..b0b15b2 --- /dev/null +++ b/mycarehub/content/migrations/0018_rename_content_smscontentitem_body.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.20 on 2023-10-25 07:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("content", "0017_alter_contentitem_facilities"), + ] + + operations = [ + migrations.RenameField( + model_name="smscontentitem", + old_name="content", + new_name="body", + ), + ] diff --git a/mycarehub/content/models/sms.py b/mycarehub/content/models/sms.py index 0d57827..81feafd 100644 --- a/mycarehub/content/models/sms.py +++ b/mycarehub/content/models/sms.py @@ -157,7 +157,7 @@ class SMSContentItem(Page): ) sequence_number = models.IntegerField(null=True, blank=True) sequence = models.CharField(max_length=10, null=True, blank=True) - content = models.TextField( + body = models.TextField( max_length=160, help_text="Write out the body of the content to be sent to subscribers" ) @@ -175,13 +175,13 @@ class SMSContentItem(Page): ], heading="About", ), - FieldPanel("content"), + FieldPanel("body"), ] # these fields determine the content that is indexed for search purposes search_fields = Page.search_fields + [ index.SearchField("category"), - index.SearchField("content"), + index.SearchField("body"), ] # this configuration allows these custom fields to be available over the API @@ -193,7 +193,7 @@ class SMSContentItem(Page): APIField("tag"), APIField("sequence"), APIField("sequence_number"), - APIField("content"), + APIField("body"), ] # limit the parent page types @@ -241,7 +241,7 @@ def save(self, *args, **kwargs): We replace the title to make it easier for users to keep track of their sms's. """ - new_title = Truncator(self.content).chars(30) + new_title = Truncator(self.body).chars(30) self.slug = slugify(new_title) self.title = new_title super().save(*args, **kwargs) diff --git a/mycarehub/content/tests/test_models.py b/mycarehub/content/tests/test_models.py index 2f1f952..c8a60a9 100644 --- a/mycarehub/content/tests/test_models.py +++ b/mycarehub/content/tests/test_models.py @@ -209,14 +209,14 @@ def test_bypass_generate_sequence_after_save(): sms_content_item = SMSContentItem( path="test", depth=3, - content="This is some sample content for testing purposes", + body="This is some sample content for testing purposes", category=category, tag=tag, ) sms_content_item.save() - sms_content_item.content = "This is a new title to test the save method" + sms_content_item.body = "This is a new title to test the save method" sms_content_item.save() assert sms_content_item.title == "This is a new title to test t…" diff --git a/mycarehub/content/tests/test_wagtail_hooks.py b/mycarehub/content/tests/test_wagtail_hooks.py index 72ad861..12c3c53 100644 --- a/mycarehub/content/tests/test_wagtail_hooks.py +++ b/mycarehub/content/tests/test_wagtail_hooks.py @@ -95,7 +95,7 @@ def test_set_sequence_number_after_page_create( sms_tag, ): sms_content_item = SMSContentItem( - content="Hello is some sample content for testing purposes", + body="Hello is some sample content for testing purposes", category=sms_category, tag=sms_tag, ) diff --git a/mycarehub/templates/wagtailadmin/pages/listing/_list.html b/mycarehub/templates/wagtailadmin/pages/listing/_list.html new file mode 100644 index 0000000..dc9f683 --- /dev/null +++ b/mycarehub/templates/wagtailadmin/pages/listing/_list.html @@ -0,0 +1,84 @@ +{% load i18n %} +{% load l10n %} +{% load wagtailadmin_tags %} + + {% if show_ordering_column or show_bulk_actions %} + + {% endif %} + + {% if show_parent %} + + {% endif %} + + + + + + {% block post_parent_page_headers %} + {% endblock %} + + + {% if pages %} + {% trans "Select page" as checkbox_aria_label %} + {% for page in pages %} + {% page_permissions page as page_perms %} + + {% if show_ordering_column %} + + {% elif show_bulk_actions %} + {% include "wagtailadmin/bulk_actions/listing_checkbox_cell.html" with obj_type="page" obj=page aria_labelledby_prefix="page_" aria_labelledby=page.pk|unlocalize aria_labelledby_suffix="_title" %} + {% endif %} + + + + {% if show_parent %} + + {% endif %} + + + + + {% block page_navigation %} + {% endblock %} + + {% endfor %} + {% else %} + {% block no_results %}{% endblock %} + {% endif %} + +
+ {% if orderable and ordering == "ord" %} +
+ {% trans 'Drag' %} + Item {{ forloop.counter }} of {{ pages|length }} +
+ {% endif %} +
+ {% block page_title %} + {% endblock %} + + {% if page.category %} + {{ page.category }} + {% endif %} + + {% for category in page.categories.all %} + {{ category.name }} + {% if not forloop.last %}, {% endif %} + {% endfor %} + {{ page.body|safe|truncatechars:70 }} + {% block page_parent_page_title %} + {% with page.get_parent as parent %} + {% if parent %} + {{ parent.specific_deferred.get_admin_display_title }} + {% endif %} + {% endwith %} + {% endblock %} + + {% if page.latest_revision_created_at %} + {% human_readable_date page.latest_revision_created_at %} + {% endif %} + {{ page.page_type_display_name }} + {% include "wagtailadmin/shared/page_status_tag.html" with page=page %} + + {{ page.owner }} +
diff --git a/mycarehub/templates/wagtailadmin/pages/listing/_table_headers_explore.html b/mycarehub/templates/wagtailadmin/pages/listing/_table_headers_explore.html new file mode 100644 index 0000000..c1475c6 --- /dev/null +++ b/mycarehub/templates/wagtailadmin/pages/listing/_table_headers_explore.html @@ -0,0 +1,77 @@ +{% load i18n wagtailadmin_tags %} + +{% comment %} + +Table headers for the page listing, when in 'explore' mode. Expects the following variables: + +sortable: if true, headings are links to wagtailadmin_explore with sort parameters applied. +sortable_by_type: must be true to allow sorting on the 'type' column +show_ordering_column: if true, an 'ordering' column is added. +orderable: if true, the 'ordering' column is populated (again with links to wagtailadmin_explore). + +If either sortable or orderable is true, the following variables are also required: + +parent_page: The page instance currently being browsed (used to generate the correct wagtailadmin_explore urls and title text) +ordering: the current sort parameter + +{% endcomment %} + + + {% if show_ordering_column %} + + {% if orderable %} + {% if ordering == "ord" %} + + {% icon name="order" %}{% trans 'Sort' %} + + {% else %} + + {% icon name="order" %}{% trans 'Sort' %} + + {% endif %} + {% endif %} + + {% elif show_bulk_actions %} + {% include 'wagtailadmin/bulk_actions/select_all_checkbox_cell.html' with parent=parent_page.id %} + {% endif %} + + {% trans 'Title' as title_label %} + {% page_table_header_label label=title_label sortable=sortable sort_field='title' parent_page_title=parent_page.title %} + + + {% trans 'Category' as category_label %} + {% page_table_header_label label=category_label parent_page_title=parent_page.title %} + + + {% trans 'Message' as message_label %} + {% page_table_header_label label=message_label parent_page_title=parent_page.title %} + + {% if show_parent %} + + {% trans 'Parent' as parent_label %} + {% page_table_header_label label=parent_label sortable=0 parent_page_title=parent_page.title %} + + {% endif %} + + {% trans 'Last Updated' as updated_label %} + {% page_table_header_label label=updated_label sortable=sortable sort_field='latest_revision_created_at' parent_page_title=parent_page.title %} + + + {% trans 'Type' as type_label %} + + {% if sortable and sortable_by_type %} + {% page_table_header_label label=type_label sortable=1 sort_field='content_type' parent_page_title=parent_page.title %} + {% else %} + {% page_table_header_label label=type_label sortable=0 parent_page_title=parent_page.title %} + {% endif %} + + + {% trans 'Status' as status_label %} + {% page_table_header_label label=status_label sortable=sortable sort_field='live' parent_page_title=parent_page.title %} + + + {% trans 'Added By' as added_by_label %} + {% page_table_header_label label=added_by_label parent_page_title=parent_page.title %} + + + diff --git a/mycarehub/templates/wagtailadmin/pages/page_listing_header.html b/mycarehub/templates/wagtailadmin/pages/page_listing_header.html index b5ea724..1644e58 100644 --- a/mycarehub/templates/wagtailadmin/pages/page_listing_header.html +++ b/mycarehub/templates/wagtailadmin/pages/page_listing_header.html @@ -8,8 +8,8 @@ {% block header_content %} {{ block.super }} -
-
+
+
@@ -22,9 +22,9 @@ {% endif %}
-
+
- {% icon name="plus" wrapped=1 %} {% trans 'Add Content' %} + {% icon name="plus" wrapped=1 %} {% trans 'Add New Content' %}
diff --git a/mycarehub/users/tests/test_views.py b/mycarehub/users/tests/test_views.py index 06f295e..0c352f2 100644 --- a/mycarehub/users/tests/test_views.py +++ b/mycarehub/users/tests/test_views.py @@ -6,10 +6,17 @@ from django.http import HttpRequest from django.test import RequestFactory +from mycarehub.content.models.models import ContentItemIndexPage from mycarehub.users.forms import UserChangeForm from mycarehub.users.models import User from mycarehub.users.tests.factories import UserFactory -from mycarehub.users.views import UserRedirectView, UserUpdateView, user_detail_view +from mycarehub.users.views import ( + CustomLoginView, + UserRedirectView, + UserUpdateView, + login_redirect, + user_detail_view, +) pytestmark = pytest.mark.django_db @@ -82,3 +89,24 @@ def test_not_authenticated(self, user: User, rf: RequestFactory): response = user_detail_view(request, username=user.username) assert response.status_code == 302 + + +class TestCustomLoginView: + def test_get_succes_url( + self, content_item_index: ContentItemIndexPage, user: User, rf: RequestFactory + ): + view = CustomLoginView() + request = rf.post("/fake-url") + request.user = user + + view.request = request + + assert view.get_success_url() == f"/admin/pages/{content_item_index.id}/" + + +def test_login_redirect(content_item_index: ContentItemIndexPage, user: User, rf: RequestFactory): + view = login_redirect + request = rf.post("/fake-url") + request.user = user + + assert view(request) == f"/admin/pages/{content_item_index.id}/" diff --git a/mycarehub/users/views.py b/mycarehub/users/views.py index 959fa2d..74a3aac 100644 --- a/mycarehub/users/views.py +++ b/mycarehub/users/views.py @@ -4,8 +4,10 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, RedirectView, UpdateView +from wagtail.admin.views.account import LoginView from mycarehub.common.views import ApprovedMixin +from mycarehub.content.models.models import ContentItemIndexPage User = get_user_model() @@ -43,3 +45,26 @@ def get_redirect_url(self): user_redirect_view = UserRedirectView.as_view() + + +class CustomLoginView(LoginView): + """ + Modifes `get_success_url` to redirect users to the program index page. + """ + + def get_success_url(self): + user = self.request.user + + # we show the first index page created for the current user's program + index_page = ( + ContentItemIndexPage.objects.filter(program=user.program).order_by("id").first() + ) + return reverse("wagtailadmin_explore", kwargs={"parent_page_id": index_page.id}) + + +def login_redirect(request): + user = request.user + + # we show the first index page created for the current user's program + index_page = ContentItemIndexPage.objects.filter(program=user.program).order_by("id").first() + return reverse("wagtailadmin_explore", kwargs={"parent_page_id": index_page.id})