diff --git a/fiesta/apps/accounts/forms/profile.py b/fiesta/apps/accounts/forms/profile.py index efeceb53..5f1afda3 100644 --- a/fiesta/apps/accounts/forms/profile.py +++ b/fiesta/apps/accounts/forms/profile.py @@ -22,17 +22,21 @@ class UserProfileForm(BaseModelForm): _FIELD_NAMES_TO_CONFIGURATION = {f.field.name: conf_field for f, conf_field in FIELDS_TO_CONFIGURATION.items()} @classmethod - def for_user( - cls, - user: User, - ) -> type[UserProfileForm]: - """ - Creates the profile form class for specific user. - Fields and configuration are constructed from all SectionsConfiguration from - all sections from all memberships of that specific user. - """ + def get_form_fields(cls, user: User): + confs = cls.get_user_configuration(user) + # TODO: what to do, when no specific configuration is found? + + fields_to_include = tuple( + field_name + for field_name, conf_field in cls._FIELD_NAMES_TO_CONFIGURATION.items() + if any(conf_field.__get__(c) is not None for c in confs) + ) + return cls.Meta.fields + fields_to_include + + @classmethod + def get_user_configuration(cls, user: User): # all related configurations - confs = SectionsConfiguration.objects.filter( + return SectionsConfiguration.objects.filter( # from all user's memberships sections plugins__section__memberships__in=user.memberships.filter( # with waiting for confirmation or already active membership @@ -43,23 +47,29 @@ def for_user( ) ) - # TODO: what to do, when no specific configuration is found? + @classmethod + def for_user( + cls, + user: User, + ) -> type[UserProfileForm]: + """ + Creates the profile form class for specific user. + Fields and configuration are constructed from all SectionsConfiguration from + all sections from all memberships of that specific user. + """ + confs = cls.get_user_configuration(user) def callback(f: Field, **kwargs) -> FormField: + # TODO: what to do, when no specific configuration is found? + if conf_field := cls._FIELD_NAMES_TO_CONFIGURATION.get(f.name): return f.formfield(required=any(conf_field.__get__(c) for c in confs), **kwargs) return f.formfield(**kwargs) - fields_to_include = tuple( - field_name - for field_name, conf_field in cls._FIELD_NAMES_TO_CONFIGURATION.items() - if any(conf_field.__get__(c) is not None for c in confs) - ) - return modelform_factory( model=UserProfile, form=cls, - fields=cls.Meta.fields + fields_to_include, + fields=cls.get_form_fields(user), formfield_callback=callback, ) diff --git a/fiesta/apps/accounts/templates/accounts/dashboard_block.html b/fiesta/apps/accounts/templates/accounts/dashboard_block.html index 5abad00c..88b49349 100644 --- a/fiesta/apps/accounts/templates/accounts/dashboard_block.html +++ b/fiesta/apps/accounts/templates/accounts/dashboard_block.html @@ -4,7 +4,7 @@
{% blocktrans %}My Profile{% endblocktrans %}
- {% compute_profile_fullness user.profile as fullness %} + {% compute_profile_fullness user as fullness %} {% interpolate_to_list fullness "text-red-400" "text-orange-400" "text-blue-400" "text-lime-400" as color %}
{# TODO: compute completness #} diff --git a/fiesta/apps/accounts/templatetags/user_profile.py b/fiesta/apps/accounts/templatetags/user_profile.py index 9203e998..0b9a5913 100644 --- a/fiesta/apps/accounts/templatetags/user_profile.py +++ b/fiesta/apps/accounts/templatetags/user_profile.py @@ -2,6 +2,7 @@ from django import template +from apps.accounts.forms.profile import UserProfileForm from apps.accounts.models import User, UserProfile # from apps.plugins.middleware.plugin import HttpRequest @@ -19,10 +20,14 @@ def get_user_picture(user: User | None): return profile.picture -@register.simple_tag(takes_context=True) -def compute_profile_fullness(context: dict, profile: UserProfile) -> float: - # req: HttpRequest = context.get("request") +@register.simple_tag +def compute_profile_fullness(user: User) -> float: + fields = UserProfileForm.get_form_fields(user) # Get all field names of UserProfile + empty_fields = 0 - # TODO: compute based on accounts conf and profile state + for field in fields: + field_value = getattr(user.profile, field, None) + if field_value is None or field_value == "": # So far it's not possible to have a field with False value + empty_fields += 1 - return 0.77 + return (len(fields) - empty_fields) / len(fields) diff --git a/fiesta/apps/utils/templatetags/utils.py b/fiesta/apps/utils/templatetags/utils.py index 41028b8f..02269560 100644 --- a/fiesta/apps/utils/templatetags/utils.py +++ b/fiesta/apps/utils/templatetags/utils.py @@ -37,7 +37,7 @@ def map_attrgetter(iterable: Reversible, attr: str): @register.simple_tag def interpolate_to_list(value: float, *values: typing.Any): - return values[int(min(1, max(0, value)) * len(values))] + return values[int(min(1, max(0, value)) * len(values)) - 1] @register.filter