Add a news review workflow and a staff notification area
News gains a PENDING_REVIEW status between draft and published. A non-editor author (can_add_news but not can_publish_news -- a coach_manager, not an ADMIN/EDITOR) gets a "Send for review" button instead of Publish; an editor/admin always sees Publish directly, no review step. Submitting notifies every ADMIN/EDITOR in-app only (see notify_members' new send_email=False) -- a review queue that emailed on every submission would get noisy fast. The notification area itself: a topbar bell (badge + dropdown, same <details>/<summary> convention as the sidebar's user-menu, generalised to a shared .dismissable-details close handler) visible on every page, plus a fuller "Notifications" card on the dashboard, both fed by a new notification_bell context processor. "Mark all read" clears the signed-in staff member's own unread notifications for this club. This is the reusable notification system's first consumer beyond news publishing itself -- validates that notify_members()/Notification generalise the way they were meant to. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -20,6 +20,7 @@ class News(ClubScopedModel):
|
||||
|
||||
class Status(models.TextChoices):
|
||||
DRAFT = "draft", _("draft")
|
||||
PENDING_REVIEW = "pending_review", _("pending review")
|
||||
PUBLISHED = "published", _("published")
|
||||
|
||||
title = models.CharField(_("title"), max_length=255)
|
||||
@@ -41,7 +42,7 @@ class News(ClubScopedModel):
|
||||
teams = models.ManyToManyField(Team, related_name="news_items", blank=True, verbose_name=_("teams"), help_text=_("Leave empty for club-wide news."))
|
||||
|
||||
visibility = models.CharField(_("visibility"), max_length=10, choices=Visibility.choices, default=Visibility.INTERNAL)
|
||||
status = models.CharField(_("status"), max_length=10, choices=Status.choices, default=Status.DRAFT)
|
||||
status = models.CharField(_("status"), max_length=20, choices=Status.choices, default=Status.DRAFT)
|
||||
published_at = models.DateTimeField(_("publish date"), null=True, blank=True, help_text=_("When this goes live. In the future to schedule it ahead of time."))
|
||||
|
||||
created_by = models.ForeignKey(Member, on_delete=models.SET_NULL, null=True, blank=True, related_name="news_items", verbose_name=_("created by"))
|
||||
@@ -57,6 +58,15 @@ class News(ClubScopedModel):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def submit_for_review(self):
|
||||
"""A non-editor author (see club.services.access.can_add_news vs
|
||||
can_publish_news) hands a draft off to an editor/admin instead of
|
||||
publishing it themselves -- see news.services.notify_editors_of_pending_review,
|
||||
which this doesn't call itself: the notification is the view's job,
|
||||
same as publish()/unpublish() never send anything either."""
|
||||
self.status = self.Status.PENDING_REVIEW
|
||||
self.save(update_fields=["status"])
|
||||
|
||||
def publish(self, at=None):
|
||||
self.status, self.published_at = self.Status.PUBLISHED, at or timezone.now()
|
||||
self.save(update_fields=["status", "published_at"])
|
||||
|
||||
Reference in New Issue
Block a user