|
2 | 2 | import secrets
|
3 | 3 | import uuid
|
4 | 4 | from collections import defaultdict
|
| 5 | +from dataclasses import dataclass |
5 | 6 | from datetime import date, datetime, timedelta
|
6 | 7 | from enum import Enum, auto
|
7 |
| -from numbers import Number |
8 |
| -from typing import NamedTuple |
| 8 | +from numbers import Real |
9 | 9 |
|
10 | 10 | from django.conf import settings
|
11 | 11 | from django.contrib import messages
|
@@ -389,7 +389,7 @@ class State:
|
389 | 389 | REVIEWED = 70
|
390 | 390 | PUBLISHED = 80
|
391 | 391 |
|
392 |
| - state = FSMIntegerField(default=State.NEW, protected=True) |
| 392 | + state = FSMIntegerField(default=State.NEW, protected=True, verbose_name=_("state")) |
393 | 393 |
|
394 | 394 | course = models.ForeignKey(Course, models.PROTECT, verbose_name=_("course"), related_name="evaluations")
|
395 | 395 |
|
@@ -779,14 +779,14 @@ def unpublish(self):
|
779 | 779 | self._participant_count = None
|
780 | 780 |
|
781 | 781 | STATE_STR_CONVERSION = {
|
782 |
| - State.NEW: "new", |
783 |
| - State.PREPARED: "prepared", |
784 |
| - State.EDITOR_APPROVED: "editor_approved", |
785 |
| - State.APPROVED: "approved", |
786 |
| - State.IN_EVALUATION: "in_evaluation", |
787 |
| - State.EVALUATED: "evaluated", |
788 |
| - State.REVIEWED: "reviewed", |
789 |
| - State.PUBLISHED: "published", |
| 782 | + State.NEW: _("new"), |
| 783 | + State.PREPARED: _("prepared"), |
| 784 | + State.EDITOR_APPROVED: _("editor_approved"), |
| 785 | + State.APPROVED: _("approved"), |
| 786 | + State.IN_EVALUATION: _("in_evaluation"), |
| 787 | + State.EVALUATED: _("evaluated"), |
| 788 | + State.REVIEWED: _("reviewed"), |
| 789 | + State.PUBLISHED: _("published"), |
790 | 790 | }
|
791 | 791 |
|
792 | 792 | @classmethod
|
@@ -994,7 +994,7 @@ def unlogged_fields(self):
|
994 | 994 |
|
995 | 995 | @classmethod
|
996 | 996 | def transform_log_action(cls, field_action):
|
997 |
| - if field_action.label == "State": |
| 997 | + if field_action.label.lower() == Evaluation.state.field.verbose_name.lower(): |
998 | 998 | return FieldAction(
|
999 | 999 | field_action.label, field_action.type, [cls.state_to_str(state) for state in field_action.items]
|
1000 | 1000 | )
|
@@ -1236,25 +1236,23 @@ def can_have_textanswers(self):
|
1236 | 1236 | return self.is_text_question or self.is_rating_question and self.allows_additional_textanswers
|
1237 | 1237 |
|
1238 | 1238 |
|
1239 |
| -# Let's deduplicate the fields here once mypy is smart enough to keep up with us :) |
1240 |
| -class Choices(NamedTuple): |
| 1239 | +@dataclass |
| 1240 | +class Choices: |
1241 | 1241 | css_class: str
|
1242 |
| - values: tuple[Number] |
| 1242 | + values: tuple[Real] |
1243 | 1243 | colors: tuple[str]
|
1244 |
| - grades: tuple[Number] |
| 1244 | + grades: tuple[Real] |
1245 | 1245 | names: list[StrOrPromise]
|
1246 | 1246 | is_inverted: bool
|
1247 | 1247 |
|
| 1248 | + def as_name_color_value_tuples(self): |
| 1249 | + return zip(self.names, self.colors, self.values, strict=True) |
1248 | 1250 |
|
1249 |
| -class BipolarChoices(NamedTuple): |
1250 |
| - css_class: str |
1251 |
| - values: tuple[Number] |
1252 |
| - colors: tuple[str] |
1253 |
| - grades: tuple[Number] |
1254 |
| - names: list[StrOrPromise] |
| 1251 | + |
| 1252 | +@dataclass |
| 1253 | +class BipolarChoices(Choices): |
1255 | 1254 | plus_name: StrOrPromise
|
1256 | 1255 | minus_name: StrOrPromise
|
1257 |
| - is_inverted: bool |
1258 | 1256 |
|
1259 | 1257 |
|
1260 | 1258 | NO_ANSWER = 6
|
|
0 commit comments