diff --git a/backend/samfundet/migrations/0042_occupiedtimeslot.py b/backend/samfundet/migrations/0025_occupiedtimeslot.py similarity index 93% rename from backend/samfundet/migrations/0042_occupiedtimeslot.py rename to backend/samfundet/migrations/0025_occupiedtimeslot.py index d65e64621..0b6b6f865 100644 --- a/backend/samfundet/migrations/0042_occupiedtimeslot.py +++ b/backend/samfundet/migrations/0025_occupiedtimeslot.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0 on 2023-12-17 21:25 +# Generated by Django 5.0 on 2023-12-19 12:37 import django.db.models.deletion from django.conf import settings @@ -7,7 +7,7 @@ class Migration(migrations.Migration): dependencies = [ - ("samfundet", "0041_recruitmentposition_norwegian_applicants_only_and_more"), + ("samfundet", "0024_recruitmentposition_norwegian_applicants_only_and_more"), ] operations = [ diff --git a/backend/samfundet/serializers.py b/backend/samfundet/serializers.py index d1cb95eea..be9e52ec4 100644 --- a/backend/samfundet/serializers.py +++ b/backend/samfundet/serializers.py @@ -54,12 +54,15 @@ class Meta: class ImageSerializer(serializers.ModelSerializer): # Read only tags used in frontend. tags = TagSerializer(many=True, read_only=True) - url = serializers.SerializerMethodField(method_name='get_url', read_only=True) + url = serializers.SerializerMethodField(method_name='get_url', + read_only=True) # Write only fields for posting new images. file = serializers.FileField(write_only=True, required=True) # Comma separated tag string "tag_a,tag_b" is automatically parsed to list of tag models. - tag_string = serializers.CharField(write_only=True, allow_blank=True, required=False) + tag_string = serializers.CharField(write_only=True, + allow_blank=True, + required=False) class Meta: model = Image @@ -73,7 +76,9 @@ def create(self, validated_data: dict) -> Event: file = validated_data.pop('file') if 'tag_string' in validated_data: tag_names = validated_data.pop('tag_string').split(',') - tags = [Tag.objects.get_or_create(name=name)[0] for name in tag_names] + tags = [ + Tag.objects.get_or_create(name=name)[0] for name in tag_names + ] else: tags = [] image = Image.objects.create( @@ -99,7 +104,10 @@ class BilligPriceGroupSerializer(serializers.ModelSerializer): class Meta: model = BilligPriceGroup - fields = ['id', 'name', 'can_be_put_on_card', 'membership_needed', 'netsale', 'price'] + fields = [ + 'id', 'name', 'can_be_put_on_card', 'membership_needed', 'netsale', + 'price' + ] class BilligTicketGroupSerializer(serializers.ModelSerializer): @@ -146,7 +154,8 @@ class EventListSerializer(serializers.ListSerializer): Speedup fetching of billig events for lists serialization """ - def to_representation(self, events: list[Event] | QuerySet[Event]) -> list[str]: + def to_representation(self, + events: list[Event] | QuerySet[Event]) -> list[str]: # Prefetch related/billig for speed if hasattr(events, 'prefetch_related'): events = events.prefetch_related('custom_tickets') @@ -184,7 +193,8 @@ def create(self, validated_data: dict) -> Event: and sets it in the new event. Read/write only fields enable us to use the same serializer for both reading and writing. """ - validated_data['image'] = Image.objects.get(pk=validated_data['image_id']) + validated_data['image'] = Image.objects.get( + pk=validated_data['image_id']) event = Event(**validated_data) event.save() return event @@ -225,8 +235,7 @@ class LoginSerializer(serializers.Serializer): # This will be used when the DRF browsable API is enabled. style={'input_type': 'password'}, trim_whitespace=False, - write_only=True - ) + write_only=True) def validate(self, attrs: dict) -> dict: # Inherited function. @@ -236,7 +245,9 @@ def validate(self, attrs: dict) -> dict: if username and password: # Try to authenticate the user using Django auth framework. - user = authenticate(request=self.context.get('request'), username=username, password=password) + user = authenticate(request=self.context.get('request'), + username=username, + password=password) if not user: # If we don't have a regular user, raise a ValidationError. msg = 'Access denied: wrong username or password.' @@ -252,7 +263,7 @@ def validate(self, attrs: dict) -> dict: class RegisterSerializer(serializers.Serializer): """ - This serializer defines two fields for authentication: + This serializer defines following fields for registration * username * email * phone_number @@ -274,8 +285,7 @@ class RegisterSerializer(serializers.Serializer): # This will be used when the DRF browsable API is enabled. style={'input_type': 'password'}, trim_whitespace=False, - write_only=True - ) + write_only=True) def validate(self, attrs: dict) -> dict: # Inherited function. @@ -289,10 +299,15 @@ def validate(self, attrs: dict) -> dict: if username and password: # Try to authenticate the user using Django auth framework. - user = User.objects.create_user( - first_name=firstname, last_name=lastname, username=username, email=email, phone_number=phone_number, password=password - ) - user = authenticate(request=self.context.get('request'), username=username, password=password) + user = User.objects.create_user(first_name=firstname, + last_name=lastname, + username=username, + email=email, + phone_number=phone_number, + password=password) + user = authenticate(request=self.context.get('request'), + username=username, + password=password) else: msg = 'Both "username" and "password" are required.' raise serializers.ValidationError(msg, code='authorization') @@ -326,9 +341,12 @@ class Meta: class UserSerializer(serializers.ModelSerializer): groups = GroupSerializer(many=True, read_only=True) profile = ProfileSerializer(many=False, read_only=True) - permissions = serializers.SerializerMethodField(method_name='get_permissions', read_only=True) - object_permissions = serializers.SerializerMethodField(method_name='get_object_permissions', read_only=True) - user_preference = serializers.SerializerMethodField(method_name='get_user_preference', read_only=True) + permissions = serializers.SerializerMethodField( + method_name='get_permissions', read_only=True) + object_permissions = serializers.SerializerMethodField( + method_name='get_object_permissions', read_only=True) + user_preference = serializers.SerializerMethodField( + method_name='get_user_preference', read_only=True) class Meta: model = User @@ -341,26 +359,32 @@ def get_permissions(self, user: User) -> list[str]: def _permission_to_str(permission: Permission) -> str: return f'{permission.content_type.app_label}.{permission.codename}' - def _obj_permission_to_obj(self, obj_perm: UserObjectPermission | GroupObjectPermission) -> dict[str, str]: + def _obj_permission_to_obj( + self, obj_perm: UserObjectPermission | GroupObjectPermission + ) -> dict[str, str]: perm_obj = { 'obj_pk': obj_perm.object_pk, - 'permission': self._permission_to_str(permission=obj_perm.permission), + 'permission': + self._permission_to_str(permission=obj_perm.permission), } return perm_obj def get_object_permissions(self, user: User) -> list[dict[str, str]]: # Collect user-level and group-level object permissions. user_object_perms_qs = UserObjectPermission.objects.filter(user=user) - group_object_perms_qs = GroupObjectPermission.objects.filter(group__in=user.groups.all()) + group_object_perms_qs = GroupObjectPermission.objects.filter( + group__in=user.groups.all()) perm_objs = [] - for obj_perm in itertools.chain(user_object_perms_qs, group_object_perms_qs): + for obj_perm in itertools.chain(user_object_perms_qs, + group_object_perms_qs): perm_objs.append(self._obj_permission_to_obj(obj_perm=obj_perm)) return perm_objs def get_user_preference(self, user: User) -> dict: - user_preference, _created = UserPreference.objects.get_or_create(user=user) + user_preference, _created = UserPreference.objects.get_or_create( + user=user) return UserPreferenceSerializer(user_preference, many=False).data @@ -433,7 +457,8 @@ class Meta: class SaksdokumentSerializer(serializers.ModelSerializer): # Read only url file path used in frontend - url = serializers.SerializerMethodField(method_name='get_url', read_only=True) + url = serializers.SerializerMethodField(method_name='get_url', + read_only=True) # Write only field for posting new document file = serializers.FileField(write_only=True, required=False) @@ -527,7 +552,8 @@ class Meta: def get_recruitment_admission_ids(self, obj: User) -> list[int]: """Return list of recruitment admission IDs for the user.""" - return RecruitmentAdmission.objects.filter(user=obj).values_list('id', flat=True) + return RecruitmentAdmission.objects.filter(user=obj).values_list( + 'id', flat=True) class RecruitmentPositionSerializer(serializers.ModelSerializer): @@ -576,7 +602,9 @@ class ApplicantInfoSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ['id', 'first_name', 'last_name', 'email', 'occupied_timeslots'] + fields = [ + 'id', 'first_name', 'last_name', 'email', 'occupied_timeslots' + ] class InterviewRoomSerializer(serializers.ModelSerializer): @@ -601,12 +629,15 @@ class Meta: model = RecruitmentAdmission fields = '__all__' - def update(self, instance: RecruitmentAdmission, validated_data: dict) -> RecruitmentAdmission: + def update(self, instance: RecruitmentAdmission, + validated_data: dict) -> RecruitmentAdmission: interview_data = validated_data.pop('interview', {}) interview_instance = instance.interview - interview_instance.interview_location = interview_data.get('interview_location', interview_instance.interview_location) - interview_instance.interview_time = interview_data.get('interview_time', interview_instance.interview_time) + interview_instance.interview_location = interview_data.get( + 'interview_location', interview_instance.interview_location) + interview_instance.interview_time = interview_data.get( + 'interview_time', interview_instance.interview_time) interview_instance.save() # Update other fields of RecruitmentAdmission instance diff --git a/frontend/src/Pages/LoginPage/LoginPage.tsx b/frontend/src/Pages/LoginPage/LoginPage.tsx index 541ee4133..6a2df7d8a 100644 --- a/frontend/src/Pages/LoginPage/LoginPage.tsx +++ b/frontend/src/Pages/LoginPage/LoginPage.tsx @@ -55,7 +55,7 @@ export function LoginPage() {

{t(KEY.loginpage_internal_login)}

- + {loginFailed &&

{t(KEY.loginpage_login_failed)}

}
diff --git a/frontend/src/Pages/SignUpPage/SignUpPage.tsx b/frontend/src/Pages/SignUpPage/SignUpPage.tsx index 914c8d59b..96de0c043 100644 --- a/frontend/src/Pages/SignUpPage/SignUpPage.tsx +++ b/frontend/src/Pages/SignUpPage/SignUpPage.tsx @@ -72,7 +72,7 @@ export function SignUpPage() { required={true} field="username" type="text" - label={t(KEY.loginpage_email_placeholder) ?? ''} + label={t(KEY.loginpage_username) ?? ''} /> diff --git a/frontend/src/i18n/constants.ts b/frontend/src/i18n/constants.ts index 86c09301a..c6915de99 100644 --- a/frontend/src/i18n/constants.ts +++ b/frontend/src/i18n/constants.ts @@ -130,7 +130,7 @@ export const KEY = { // LoginPage: loginpage_register: 'loginpage_register', loginpage_internal_login: 'loginpage_internal_login', - loginpage_email_placeholder: 'loginpage_email_placeholder', + loginpage_username: 'loginpage_username', loginpage_forgotten_password: 'loginpage_forgotten_password', loginpage_login_failed: 'loginpage_login_failed', diff --git a/frontend/src/i18n/translations.ts b/frontend/src/i18n/translations.ts index 02d196d81..53d2350e0 100644 --- a/frontend/src/i18n/translations.ts +++ b/frontend/src/i18n/translations.ts @@ -120,7 +120,7 @@ export const nb: Record = { [KEY.loginpage_register]: 'Lag bruker', [KEY.loginpage_login_failed]: 'Innlogging feilet', [KEY.loginpage_internal_login]: 'Logg inn som intern', - [KEY.loginpage_email_placeholder]: 'Brukernavn', + [KEY.loginpage_username]: 'Brukernavn', [KEY.loginpage_forgotten_password]: 'Glemt passordet ditt?', // GroupsPage: @@ -356,7 +356,7 @@ export const en: Record = { // LoginPage: [KEY.loginpage_register]: 'Create user', [KEY.loginpage_internal_login]: 'Log in as internal', - [KEY.loginpage_email_placeholder]: 'Username', + [KEY.loginpage_username]: 'Username', [KEY.loginpage_forgotten_password]: 'Forgot password?', [KEY.loginpage_login_failed]: 'Login failed',