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

Ajoute une page de preview pour la classification par objectifs #6386

Merged
merged 2 commits into from
Sep 28, 2022
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
2 changes: 1 addition & 1 deletion templates/tutorialv2/goals/mass-edit-goals.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<div class="mobile-menu-bloc mobile-all-links" data-title="Filtrer">
<h3>Filtrer</h3>
<ul>
<li><a href="{% url "content:mass-edit-goals" %}" class="{% if all %}selected{% endif %}">Tous ({{ num_all }})</a></li>
<li><a href="{% url "content:mass-edit-goals" %}" class="{% if all %}selected{% endif %}">Toutes ({{ num_all }})</a></li>
Arnaud-D marked this conversation as resolved.
Show resolved Hide resolved
<li><a href="{% url "content:mass-edit-goals" %}?non-classes" class="{% if only_not_classified %}selected{% endif %}">Sans objectif ({{ num_not_classified }})</a></li>
{% for goal in goals %}
<li>
Expand Down
67 changes: 67 additions & 0 deletions templates/tutorialv2/goals/view-goals.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{% extends "base.html" %}
{% load profile %}
{% load thumbnail %}
{% load date %}
{% load i18n %}
{% load captureas %}
{% load times %}


{% block title %}
{% trans "Aperçu de la classification par objectifs" %}
{% endblock %}


{% block breadcrumb %}
<li>{% trans "Aperçu de la classification par objectifs" %}</li>
{% endblock %}

{% block headline %}
{{ headline }}
{% endblock %}

{% block sidebar %}
<div class="sidebar">
<div class="mobile-menu-bloc mobile-all-links" data-title="Filtrer">
<h3>Filtrer</h3>
<ul>
<li><a href="{% url "content:view-goals" %}?non-classes" class="{% if only_not_classified %}selected{% endif %}">Sans objectif ({{ num_not_classified }})</a></li>
{% for goal in goals %}
<li>
<a href="{% url "content:view-goals" %}?objectif_{{ goal.id }}" class="{% if current_filter_pk == goal.pk %}selected{% endif %}">{{ goal.name }} ({{ goal.num_contents }})</a>
</li>
{% endfor %}
<li><a href="{% url "content:view-goals" %}" class="{% if all %}selected{% endif %}">Toutes ({{ num_all }})</a></li>
</ul>
</div>
</div>
{% endblock %}

{% block content %}

<p>
{% blocktrans %}
Cette page est un aperçu de la classification par objectifs. Elle vise à donner un avant-goût de
cette nouvelle manière de classifier les publications sur Zeste de Savoir, qui vient en complément
des catégories et des tags. L'objectif de cette classification est de faciliter l'identification
des objectifs des publications : découvrir un sujet, donner une opinion, apprendre à maîtriser un
outil ou une technologie, etc.
{% endblocktrans %}
</p>

{% if not contents %}
<p>{% trans "Il n'y a pas de publication à lister." %}</p>
{% else %}
{% include "misc/paginator.html" with position="top" %}
<div class="content-item-list">
{% for content in contents %}
{% include "tutorialv2/includes/content_item.part.html" with public_content=content.public_version show_description=True show_reactions=True ignore_categories=ignore_categories %}
{% endfor %}
{% for i in 1|times %}
<div class="fill"></div>
{% endfor %}
</div>
{% include "misc/paginator.html" with position="bottom" %}
{% endif %}

{% endblock %}
11 changes: 11 additions & 0 deletions templates/tutorialv2/view/categories.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% extends "tutorialv2/view/base_categories.html" %}
{% load i18n %}
{% load captureas %}


{% block content_category %}
Expand All @@ -21,6 +22,16 @@ <h2 itemprop="name">{% trans 'À la une' %}</h2>
</section>
{% endcomment %}

<section>
{% captureas url_view_goals %}{% url "content:view-goals" %}{% endcaptureas %}
{% blocktrans %}
<p>
<strong>Avis aux curieux</strong> ! La nouvelle <a href="{{ url_view_goals }}">classification par objectifs</a> fait son avant-première.
Arnaud-D marked this conversation as resolved.
Show resolved Hide resolved
Elle vient en complément de la classification par catégories et par tags.
</p>
{% endblocktrans %}
</section>

<section>
<h2 class="inline" itemprop="name">{% trans 'Domaines de savoir' %}</h2>
<div class="content-linkbox-list">
Expand Down
3 changes: 2 additions & 1 deletion zds/settings/abstract_base/zds.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@
"helps_per_page": 20,
"commits_per_page": 20,
"suggestions_per_page": 2,
"goals_content_per_page": 25,
"mass_edit_goals_content_per_page": 25,
"view_contents_by_goal_content_per_page": 42,
"feed_length": 5,
"user_page_number": 5,
"default_image": BASE_DIR / "fixtures" / "noir_black.png",
Expand Down
19 changes: 19 additions & 0 deletions zds/tutorialv2/tests/tests_views/tests_viewcontentsbygoal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.test import TestCase
from django.urls import reverse

from zds.tutorialv2.tests.factories import GoalFactory, PublishedContentFactory


class ViewContentsByGoalTests(TestCase):
def setUp(self):
self.goals = [GoalFactory(), GoalFactory()]
self.contents = [PublishedContentFactory(), PublishedContentFactory()]

def test_page_content(self):
"""Test roughly that what is expected is in the page."""
response = self.client.get(reverse("content:view-goals"))
self.assertEqual(response.status_code, 200)
for goal in self.goals:
self.assertContains(response, goal.name)
for content in self.contents:
self.assertContains(response, content.title)
3 changes: 2 additions & 1 deletion zds/tutorialv2/urls/urls_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from zds.tutorialv2.views.contents import DisplayContent, CreateContent, EditContent, EditContentLicense, DeleteContent
from zds.tutorialv2.views.events import EventsList
from zds.tutorialv2.views.goals import EditGoals, MassEditGoals
from zds.tutorialv2.views.goals import EditGoals, MassEditGoals, ViewContentsByGoal
from zds.tutorialv2.views.validations_contents import ActivateJSFiddleInContent
from zds.tutorialv2.views.containers_extracts import (
CreateContainer,
Expand Down Expand Up @@ -188,4 +188,5 @@
# Goal-based classification
path("modifier-objectifs/", MassEditGoals.as_view(), name="mass-edit-goals"),
path("modifier-objectifs/<int:pk>/", EditGoals.as_view(), name="edit-goals"),
path("objectifs/", ViewContentsByGoal.as_view(), name="view-goals"),
]
79 changes: 57 additions & 22 deletions zds/tutorialv2/views/goals.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
BooleanField,
HiddenInput,
)
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.generic import TemplateView
from django.views.generic.edit import BaseFormView

from zds.tutorialv2 import signals
Expand Down Expand Up @@ -106,27 +108,8 @@ def clean_content_id(self):
return content_id


class MassEditGoals(LoginRequiredMixin, PermissionRequiredMixin, BaseFormView, ZdSPagingListView):
"""View to edit the goals of many contents."""

template_name = "tutorialv2/goals/mass-edit-goals.html"
permission_required = "tutorialv2.change_publishablecontent"
class ContentsByGoalMixin:
context_object_name = "contents"
form_class = MassEditGoalsForm
ordering = ["-creation_date"]
paginate_by = settings.ZDS_APP["content"]["goals_content_per_page"]

def get_context_data(self, **kwargs):
context = {
"goals": Goal.objects.all().annotate(num_contents=Count("contents")),
"current_filter_pk": self.current_filter_pk,
"only_not_classified": self.only_not_classified,
"all": self.current_filter_pk is None and not self.only_not_classified,
"num_all": self.num_all,
"num_not_classified": self.num_not_classified,
}
context.update(kwargs)
return super().get_context_data(**context)

def get_queryset(self):
self.current_filter_pk = None
Expand All @@ -147,6 +130,40 @@ def get_queryset(self):
return self.base_queryset.filter(goals__in=[goal])
return self.base_queryset

def get_context_data(self, **kwargs):
context = {
"goals": Goal.objects.all().annotate(num_contents=Count("contents")),
"current_filter_pk": self.current_filter_pk,
"only_not_classified": self.only_not_classified,
"all": self.current_filter_pk is None and not self.only_not_classified,
"num_all": self.num_all,
"num_not_classified": self.num_not_classified,
}
context.update(kwargs)
return super().get_context_data(**context)


class MassEditGoals(LoginRequiredMixin, PermissionRequiredMixin, BaseFormView, ContentsByGoalMixin, ZdSPagingListView):
"""View to edit the goals of many contents."""

template_name = "tutorialv2/goals/mass-edit-goals.html"
permission_required = "tutorialv2.change_publishablecontent"
form_class = MassEditGoalsForm
ordering = ["-creation_date"]
paginate_by = settings.ZDS_APP["content"]["mass_edit_goals_content_per_page"]

def get_context_data(self, **kwargs):
context = {
"goals": Goal.objects.all().annotate(num_contents=Count("contents")),
"current_filter_pk": self.current_filter_pk,
"only_not_classified": self.only_not_classified,
"all": self.current_filter_pk is None and not self.only_not_classified,
"num_all": self.num_all,
"num_not_classified": self.num_not_classified,
}
context.update(kwargs)
return super().get_context_data(**context)

def form_valid(self, form):
content = PublishableContent.objects.get(id=form.cleaned_data["content_id"])
goal = Goal.objects.get(id=form.cleaned_data["goal_id"])
Expand All @@ -158,5 +175,23 @@ def form_valid(self, form):
return JsonResponse({"state": activated})

def form_invalid(self, form):
print(form)
return JsonResponse({"errors": form.errors}, status=400)


class ViewContentsByGoal(ContentsByGoalMixin, ZdSPagingListView):
template_name = "tutorialv2/goals/view-goals.html"
ordering = ["-creation_date"]
paginate_by = settings.ZDS_APP["content"]["view_contents_by_goal_content_per_page"]

def get_context_data(self, **kwargs):
if self.only_not_classified:
headline = _("Publications sans objectif")
elif self.current_filter_pk is not None:
headline = _("Publications avec pour objectif « {} »").format(
Goal.objects.get(pk=self.current_filter_pk).name
)
else:
headline = _("Toutes les publications")
context = {"headline": headline}
context.update(kwargs)
return super().get_context_data(**context)