diff --git a/backend/backend_app/admin.py b/backend/backend_app/admin.py index 7aa0b00b56b9c09c8c1ca882cdec6f98794ee530..b8f510a8a5f3eeb0a5adb5bdcbbe5387d492cec7 100644 --- a/backend/backend_app/admin.py +++ b/backend/backend_app/admin.py @@ -12,14 +12,16 @@ from backend_app.models.country import Country from backend_app.models.countryDri import CountryDri from backend_app.models.countryScholarship import CountryScholarship from backend_app.models.countryTaggedItem import CountryTaggedItem +from backend_app.models.course import Course +from backend_app.models.courseFeedback import CourseFeedback from backend_app.models.currency import Currency from backend_app.models.department import Department from backend_app.models.for_testing.moderation import ForTestingModeration from backend_app.models.for_testing.versioning import ForTestingVersioning from backend_app.models.offer import Offer from backend_app.models.pendingModeration import PendingModeration -from backend_app.models.previousDeparture import PreviousDeparture -from backend_app.models.previousDepartureFeedback import PreviousDepartureFeedback +from backend_app.models.exchange import Exchange +from backend_app.models.exchangeFeedback import ExchangeFeedback from backend_app.models.recommendation import Recommendation from backend_app.models.recommendationList import RecommendationList from backend_app.models.specialty import Specialty @@ -42,12 +44,14 @@ ALL_MODELS = [ CountryDri, CountryScholarship, CountryTaggedItem, + Course, + CourseFeedback, Currency, Department, Offer, PendingModeration, - PreviousDeparture, - PreviousDepartureFeedback, + Exchange, + ExchangeFeedback, Recommendation, RecommendationList, Specialty, diff --git a/backend/backend_app/migrations/0002_auto_20190324_2123.py b/backend/backend_app/migrations/0002_auto_20190324_2123.py new file mode 100644 index 0000000000000000000000000000000000000000..ce86f591b109820d495426b0724f7017c4ff1d82 --- /dev/null +++ b/backend/backend_app/migrations/0002_auto_20190324_2123.py @@ -0,0 +1,347 @@ +# Generated by Django 2.1.7 on 2019-03-24 20:23 + +import backend_app.fields +import backend_app.models.abstract.essentialModule +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("backend_app", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Course", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("updated_on", models.DateTimeField(null=True)), + ("moderated_on", models.DateTimeField(null=True)), + ( + "obj_moderation_level", + models.SmallIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + backend_app.models.abstract.essentialModule.validate_obj_model_lv, + ], + ), + ), + ("has_pending_moderation", models.BooleanField(default=False)), + ("course_id", models.IntegerField()), + ("code", models.CharField(max_length=10)), + ( + "title", + models.CharField(blank=True, default="", max_length=200, null=True), + ), + ("link", models.CharField(blank=True, max_length=500, null=True)), + ("nb_credit", models.PositiveIntegerField()), + ( + "description", + models.TextField(blank=True, max_length=2000, null=True), + ), + ("profile", models.CharField(blank=True, max_length=10, null=True)), + ("tsh_profile", models.CharField(blank=True, max_length=21, null=True)), + ( + "student_login", + models.CharField(blank=True, max_length=8, null=True), + ), + ( + "moderated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "updated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={"abstract": False}, + ), + migrations.CreateModel( + name="CourseFeedback", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("updated_on", models.DateTimeField(null=True)), + ("moderated_on", models.DateTimeField(null=True)), + ( + "obj_moderation_level", + models.SmallIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + backend_app.models.abstract.essentialModule.validate_obj_model_lv, + ], + ), + ), + ("has_pending_moderation", models.BooleanField(default=False)), + ("comment", models.TextField(max_length=1500, null=True)), + ( + "adequation", + models.IntegerField( + validators=[ + django.core.validators.MaxValueValidator(5), + django.core.validators.MinValueValidator(-5), + ] + ), + ), + ( + "work_dose", + models.IntegerField( + validators=[ + django.core.validators.MaxValueValidator(5), + django.core.validators.MinValueValidator(-5), + ] + ), + ), + ( + "language_following_ease", + models.IntegerField( + validators=[ + django.core.validators.MaxValueValidator(5), + django.core.validators.MinValueValidator(-5), + ] + ), + ), + ("is_psf_credit", models.BooleanField()), + ], + options={"abstract": False}, + ), + migrations.CreateModel( + name="Exchange", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("updated_on", models.DateTimeField(null=True)), + ("moderated_on", models.DateTimeField(null=True)), + ( + "obj_moderation_level", + models.SmallIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + backend_app.models.abstract.essentialModule.validate_obj_model_lv, + ], + ), + ), + ("has_pending_moderation", models.BooleanField(default=False)), + ("utc_departure_id", models.IntegerField()), + ("year", models.PositiveIntegerField(default=2018)), + ( + "semester", + models.CharField( + choices=[("a", "autumn"), ("p", "spring")], + default="a", + max_length=2, + ), + ), + ("duration", models.PositiveIntegerField()), + ("dual_degree", models.BooleanField()), + ("master_obtained", models.BooleanField()), + ("student_major", models.CharField(max_length=40)), + ("student_minor", models.CharField(max_length=40)), + ("student_option", models.CharField(max_length=40)), + ("utc_allow_courses", models.BooleanField()), + ("utc_allow_login", models.BooleanField()), + ("is_anonymous", models.BooleanField()), + ("courses", backend_app.fields.JSONField(null=True)), + ( + "moderated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "updated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "utc_univ_id", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="backend_app.University", + ), + ), + ], + options={"abstract": False}, + ), + migrations.CreateModel( + name="ExchangeFeedback", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("updated_on", models.DateTimeField(null=True)), + ("moderated_on", models.DateTimeField(null=True)), + ( + "obj_moderation_level", + models.SmallIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + backend_app.models.abstract.essentialModule.validate_obj_model_lv, + ], + ), + ), + ("has_pending_moderation", models.BooleanField(default=False)), + ("general_comment", models.TextField(max_length=1500, null=True)), + ( + "academical_level_appreciation", + models.IntegerField( + validators=[ + django.core.validators.MaxValueValidator(5), + django.core.validators.MinValueValidator(-5), + ] + ), + ), + ( + "foreign_student_welcome", + models.PositiveIntegerField( + validators=[django.core.validators.MaxValueValidator(10)] + ), + ), + ( + "cultural_interest", + models.PositiveIntegerField( + validators=[django.core.validators.MaxValueValidator(10)] + ), + ), + ( + "departure", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + to="backend_app.Exchange", + ), + ), + ( + "moderated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "updated_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={"abstract": False}, + ), + migrations.RemoveField(model_name="previousdeparture", name="moderated_by"), + migrations.RemoveField(model_name="previousdeparture", name="specialty"), + migrations.RemoveField(model_name="previousdeparture", name="university"), + migrations.RemoveField(model_name="previousdeparture", name="updated_by"), + migrations.RemoveField(model_name="previousdeparture", name="user"), + migrations.RemoveField( + model_name="previousdeparturefeedback", name="departure" + ), + migrations.RemoveField( + model_name="previousdeparturefeedback", name="moderated_by" + ), + migrations.RemoveField(model_name="previousdeparturefeedback", name="owner"), + migrations.RemoveField( + model_name="previousdeparturefeedback", name="updated_by" + ), + migrations.DeleteModel(name="PreviousDeparture"), + migrations.DeleteModel(name="PreviousDepartureFeedback"), + migrations.AddField( + model_name="coursefeedback", + name="departure", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, to="backend_app.Exchange" + ), + ), + migrations.AddField( + model_name="coursefeedback", + name="moderated_by", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="coursefeedback", + name="updated_by", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="course", + name="utc_exchange_id", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, to="backend_app.Exchange" + ), + ), + ] diff --git a/backend/backend_app/migrations/0003_merge_20190406_1636.py b/backend/backend_app/migrations/0003_merge_20190406_1636.py new file mode 100644 index 0000000000000000000000000000000000000000..e7eb7fc6017643f5b431f69c972da1e2cf44836c --- /dev/null +++ b/backend/backend_app/migrations/0003_merge_20190406_1636.py @@ -0,0 +1,13 @@ +# Generated by Django 2.1.7 on 2019-04-06 14:36 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("backend_app", "0002_auto_20190324_2123"), + ("backend_app", "0002_auto_20190405_2131"), + ] + + operations = [] diff --git a/backend/backend_app/migrations/0004_auto_20190407_1010.py b/backend/backend_app/migrations/0004_auto_20190407_1010.py new file mode 100644 index 0000000000000000000000000000000000000000..e259dbfb7fb275b53e76e5618814b2665767f40e --- /dev/null +++ b/backend/backend_app/migrations/0004_auto_20190407_1010.py @@ -0,0 +1,108 @@ +# Generated by Django 2.1.7 on 2019-04-07 08:10 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [("backend_app", "0003_merge_20190406_1636")] + + operations = [ + migrations.RenameField( + model_name="coursefeedback", old_name="work_dose", new_name="working_dose" + ), + migrations.RemoveField(model_name="course", name="description"), + migrations.RemoveField(model_name="course", name="has_pending_moderation"), + migrations.RemoveField(model_name="course", name="moderated_by"), + migrations.RemoveField(model_name="course", name="moderated_on"), + migrations.RemoveField(model_name="course", name="obj_moderation_level"), + migrations.RemoveField(model_name="course", name="updated_by"), + migrations.RemoveField(model_name="course", name="updated_on"), + migrations.RemoveField(model_name="coursefeedback", name="departure"), + migrations.RemoveField(model_name="exchange", name="has_pending_moderation"), + migrations.RemoveField(model_name="exchange", name="is_anonymous"), + migrations.RemoveField(model_name="exchange", name="moderated_by"), + migrations.RemoveField(model_name="exchange", name="moderated_on"), + migrations.RemoveField(model_name="exchange", name="obj_moderation_level"), + migrations.RemoveField(model_name="exchange", name="updated_by"), + migrations.RemoveField(model_name="exchange", name="updated_on"), + migrations.RemoveField(model_name="exchangefeedback", name="departure"), + migrations.RemoveField(model_name="exchangefeedback", name="id"), + migrations.AddField( + model_name="course", + name="category", + field=models.CharField(blank=True, max_length=5, null=True), + ), + migrations.AddField( + model_name="coursefeedback", + name="course", + field=models.ForeignKey( + default=0, + on_delete=django.db.models.deletion.CASCADE, + to="backend_app.Course", + ), + ), + migrations.AddField( + model_name="coursefeedback", + name="university", + field=models.ForeignKey( + default=0, + on_delete=django.db.models.deletion.PROTECT, + to="backend_app.University", + ), + ), + migrations.AddField( + model_name="exchangefeedback", + name="exchange", + field=models.OneToOneField( + default=0, + on_delete=django.db.models.deletion.CASCADE, + primary_key=True, + related_name="feedbacks", + serialize=False, + to="backend_app.Exchange", + ), + ), + migrations.AddField( + model_name="exchangefeedback", + name="university", + field=models.ForeignKey( + default=0, + on_delete=django.db.models.deletion.PROTECT, + to="backend_app.University", + ), + ), + migrations.AlterField( + model_name="exchange", + name="semester", + field=models.CharField( + choices=[("a", "autumn"), ("p", "spring")], default="a", max_length=5 + ), + ), + migrations.AlterField( + model_name="exchange", + name="student_major", + field=models.CharField(max_length=20), + ), + migrations.AlterField( + model_name="exchange", + name="student_minor", + field=models.CharField(max_length=7), + ), + migrations.AlterField( + model_name="exchange", + name="student_option", + field=models.CharField(max_length=7), + ), + migrations.AlterField( + model_name="exchange", + name="user", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/backend/backend_app/models/course.py b/backend/backend_app/models/course.py new file mode 100644 index 0000000000000000000000000000000000000000..4cc86061629da89f4304a2fce0c1d1065ec339dd --- /dev/null +++ b/backend/backend_app/models/course.py @@ -0,0 +1,24 @@ +from django.db import models + +from backend_app.models.abstract.base import BaseModel, BaseModelSerializer + +from backend_app.models.exchange import Exchange + + +class Course(BaseModel): + utc_exchange_id = models.OneToOneField(Exchange, on_delete=models.CASCADE) + course_id = models.IntegerField() + code = models.CharField(max_length=10) + title = models.CharField(default="", null=True, blank=True, max_length=200) + link = models.CharField(null=True, blank=True, max_length=500) + nb_credit = models.PositiveIntegerField() + category = models.CharField(null=True, blank=True, max_length=5) + profile = models.CharField(null=True, blank=True, max_length=10) + tsh_profile = models.CharField(null=True, blank=True, max_length=21) + student_login = models.CharField(null=True, blank=True, max_length=8) + + +class CourseSerializer(BaseModelSerializer): + class Meta: + model = Course + fields = "__all__" diff --git a/backend/backend_app/models/courseFeedback.py b/backend/backend_app/models/courseFeedback.py new file mode 100644 index 0000000000000000000000000000000000000000..8306ab4e4a55800ebf874c246863aa44010e6f17 --- /dev/null +++ b/backend/backend_app/models/courseFeedback.py @@ -0,0 +1,40 @@ +from django.db import models +from django.core.validators import MaxValueValidator, MinValueValidator + +from backend_app.models.abstract.essentialModule import ( + EssentialModule, + EssentialModuleSerializer, + EssentialModuleViewSet, +) +from backend_app.models.course import Course, CourseSerializer +from backend_app.models.university import University + + +class CourseFeedback(EssentialModule): + university = models.ForeignKey(University, on_delete=models.PROTECT, default=0) + course = models.ForeignKey(Course, on_delete=models.CASCADE, default=0) + comment = models.TextField(null=True, max_length=1500) + adequation = models.IntegerField( + validators=[MaxValueValidator(5), MinValueValidator(-5)] + ) + working_dose = models.IntegerField( + validators=[MaxValueValidator(5), MinValueValidator(-5)] + ) + language_following_ease = models.IntegerField( + validators=[MaxValueValidator(5), MinValueValidator(-5)] + ) + is_psf_credit = models.BooleanField() + + +class CourseFeedbackSerializer(EssentialModuleSerializer): + course = CourseSerializer(many=True) + + class Meta: + model = CourseFeedback + fields = "__all__" + + +class CourseFeedbackViewSet(EssentialModuleViewSet): + queryset = CourseFeedback.objects.all().prefetch_related() # pylint: disable=E1101 + serializer_class = CourseFeedbackSerializer + end_point_route = "courseFeedbacks" diff --git a/backend/backend_app/models/exchange.py b/backend/backend_app/models/exchange.py new file mode 100644 index 0000000000000000000000000000000000000000..f29986664d10b0c600ec40edc4d8b1d73f39c9c6 --- /dev/null +++ b/backend/backend_app/models/exchange.py @@ -0,0 +1,44 @@ +from django.db import models +from backend_app.models.university import University +from base_app.models import User +from backend_app.fields import JSONField + +from backend_app.models.abstract.base import BaseModel, BaseModelSerializer +from backend_app.models.shared import SEMESTER_OPTIONS + + +class Exchange(BaseModel): + + # This model should be filled with data from the ENT + utc_univ_id = models.ForeignKey(University, on_delete=models.PROTECT) + utc_departure_id = models.IntegerField() + user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) + + year = models.PositiveIntegerField(default=2018) + semester = models.CharField(max_length=5, choices=SEMESTER_OPTIONS, default="a") + duration = models.PositiveIntegerField() + dual_degree = models.BooleanField() + master_obtained = models.BooleanField() + student_major = models.CharField(max_length=20) + student_minor = models.CharField(max_length=7) + student_option = models.CharField(max_length=7) + + utc_allow_courses = models.BooleanField() + utc_allow_login = models.BooleanField() + + courses = JSONField(null=True) # Store data from ENT + + +class ExchangeSerializer(BaseModelSerializer): + class Meta: + model = Exchange + fields = BaseModelSerializer.Meta.fields + ( + "year", + "semester", + "duration", + "dual_degree", + "master_obtained", + "student_major", + "studentminor", + "student_option", + ) diff --git a/backend/backend_app/models/exchangeFeedback.py b/backend/backend_app/models/exchangeFeedback.py new file mode 100644 index 0000000000000000000000000000000000000000..7e648be042c6722595f55d2d53776cbb74c95c2f --- /dev/null +++ b/backend/backend_app/models/exchangeFeedback.py @@ -0,0 +1,42 @@ +from django.db import models +from django.core.validators import MaxValueValidator, MinValueValidator + +from backend_app.models.abstract.essentialModule import ( + EssentialModule, + EssentialModuleSerializer, + EssentialModuleViewSet, +) +from backend_app.models.exchange import Exchange +from backend_app.models.university import University + + +class ExchangeFeedback(EssentialModule): + university = models.ForeignKey(University, on_delete=models.PROTECT, default=0) + exchange = models.OneToOneField( + Exchange, + on_delete=models.CASCADE, + related_name="feedbacks", + primary_key=True, + null=False, + default=0, + ) + general_comment = models.TextField(null=True, max_length=1500) + academical_level_appreciation = models.IntegerField( + validators=[MaxValueValidator(5), MinValueValidator(-5)] + ) + foreign_student_welcome = models.PositiveIntegerField( + validators=[MaxValueValidator(10)] + ) + cultural_interest = models.PositiveIntegerField(validators=[MaxValueValidator(10)]) + + +class ExchangeFeedbackSerializer(EssentialModuleSerializer): + class Meta: + model = ExchangeFeedback + fields = "__all__" + + +class ExchangeFeedbackViewSet(EssentialModuleViewSet): + queryset = ExchangeFeedback.objects.all() # pylint: disable=E1101 + serializer_class = ExchangeFeedbackSerializer + end_point_route = "exchangeFeedbacks" diff --git a/backend/backend_app/models/previousDeparture.py b/backend/backend_app/models/previousDeparture.py deleted file mode 100644 index ce851354196bcb4f18ccfaf2e7706c3dca645f6c..0000000000000000000000000000000000000000 --- a/backend/backend_app/models/previousDeparture.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.db import models -from backend_app.models.specialty import Specialty -from backend_app.models.university import University -from backend_app.permissions.app_permissions import ReadOnly -from base_app.models import User -from backend_app.fields import JSONField -from backend_app.models.abstract.essentialModule import ( - EssentialModule, - EssentialModuleSerializer, - EssentialModuleViewSet, -) -from backend_app.models.shared import SEMESTER_OPTIONS - - -class PreviousDeparture(EssentialModule): - # This model should be filled with data from the ENT - university = models.ForeignKey(University, on_delete=models.PROTECT) - specialty = models.ForeignKey(Specialty, on_delete=models.PROTECT) - user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) - # Useful to relink a departure with a user - Utc_departure_id = models.IntegerField() - year = models.PositiveIntegerField(default=2018) - semester = models.CharField(max_length=2, choices=SEMESTER_OPTIONS, default="a") - - is_anonymous = models.BooleanField() - courses = JSONField(null=True) # Store data from ENT - - -class PreviousDepartureSerializer(EssentialModuleSerializer): - class Meta: - model = PreviousDeparture - fields = "__all__" - - -class PreviousDepartureViewSet(EssentialModuleViewSet): - queryset = PreviousDeparture.objects.all() # pylint: disable=E1101 - serializer_class = PreviousDepartureSerializer - permission_classes = (ReadOnly,) - end_point_route = "universitiesPreviousDepartures" diff --git a/backend/backend_app/models/previousDepartureFeedback.py b/backend/backend_app/models/previousDepartureFeedback.py deleted file mode 100644 index 13f48f457fe22c9a810e5ac23f95ce0a15294b16..0000000000000000000000000000000000000000 --- a/backend/backend_app/models/previousDepartureFeedback.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.core.validators import MaxValueValidator -from django.db import models - -from backend_app.fields import JSONField -from backend_app.models.previousDeparture import PreviousDeparture -from backend_app.models.userRestrictedModule import ( - UserRestrictedModule, - UserRestrictedModuleSerializer, - UserRestrictedModuleViewSet, -) - - -class PreviousDepartureFeedback(UserRestrictedModule): - departure = models.OneToOneField(PreviousDeparture, on_delete=models.CASCADE) - - courses_and_courses_feedback = JSONField(default=dict) - adequation_comment = models.CharField(default="", blank=True, max_length=5000) - integration_comment = models.CharField(default="", blank=True, max_length=5000) - adequation_grate = models.PositiveIntegerField(validators=[MaxValueValidator(20)]) - integration_grade = models.PositiveIntegerField(validators=[MaxValueValidator(20)]) - - -class PreviousDepartureFeedbackSerializer(UserRestrictedModuleSerializer): - class Meta: - model = PreviousDepartureFeedback - fields = "__all__" - - -class PreviousDepartureFeedbackViewSet(UserRestrictedModuleViewSet): - queryset = PreviousDepartureFeedback.objects.all() # pylint: disable=E1101 - serializer_class = PreviousDepartureFeedbackSerializer - end_point_route = "universitiesPreviousDepartureFeedbacks" diff --git a/backend/backend_app/viewsets.py b/backend/backend_app/viewsets.py index 8b4acc33af16f02839b8663b2711afff3ea69c6c..2ff1010d39a61873f4b4dfd5f8d75def8154c871 100644 --- a/backend/backend_app/viewsets.py +++ b/backend/backend_app/viewsets.py @@ -11,6 +11,7 @@ from backend_app.models.country import CountryViewSet from backend_app.models.countryDri import CountryDriViewSet from backend_app.models.countryScholarship import CountryScholarshipViewSet from backend_app.models.countryTaggedItem import CountryTaggedItemViewSet +from backend_app.models.courseFeedback import CourseFeedbackViewSet from backend_app.models.currency import CurrencyViewSet from backend_app.models.department import DepartmentViewSet from backend_app.models.for_testing.moderation import ForTestingModerationViewSet @@ -20,10 +21,7 @@ from backend_app.models.pendingModeration import ( PendingModerationViewSet, PendingModerationObjViewSet, ) -from backend_app.models.previousDeparture import PreviousDepartureViewSet -from backend_app.models.previousDepartureFeedback import ( - PreviousDepartureFeedbackViewSet, -) +from backend_app.models.exchangeFeedback import ExchangeFeedbackViewSet from backend_app.models.recommendation import RecommendationViewSet from backend_app.models.recommendationList import RecommendationListViewSet from backend_app.models.specialty import SpecialtyViewSet @@ -51,13 +49,13 @@ ALL_API_VIEWSETS = [ CountryDriViewSet, CountryScholarshipViewSet, CountryTaggedItemViewSet, + CourseFeedbackViewSet, CurrencyViewSet, DepartmentViewSet, OfferViewSet, PendingModerationViewSet, PendingModerationObjViewSet, - PreviousDepartureViewSet, - PreviousDepartureFeedbackViewSet, + ExchangeFeedbackViewSet, RecommendationViewSet, RecommendationListViewSet, SpecialtyViewSet, diff --git a/frontend/src/components/university/UniversityTemplate.js b/frontend/src/components/university/UniversityTemplate.js index f54d9781714afdc9b11d726912a9b3e035cf973b..5a6d20606950fae4880cc520c1d5f1df2213a439 100644 --- a/frontend/src/components/university/UniversityTemplate.js +++ b/frontend/src/components/university/UniversityTemplate.js @@ -20,7 +20,7 @@ import CoverGallery from "./otherComponents/CoverGallery"; import GeneralInfoTab from "./tabs/GeneralInfoTab"; // import UniversityMoreTab from "./tabs/UniversityMoreTab"; // import CampusesCitiesTab from "./tabs/CampusesCitiesTab"; -// import PreviousDeparturesTab from "./tabs/PreviousDeparturesTab"; +import PreviousDeparturesTab from "./tabs/PreviousDeparturesTab"; import ScholarshipsTab from "./tabs/ScholarshipsTab"; // import MoreTab from "./tabs/MoreTab"; @@ -104,7 +104,7 @@ class UniversityTemplate extends Component { {/* { } */} - {/* {value === 2 && } */} + { } { } {/* {value === 4 && } */} {/* {value === 5 && } */} diff --git a/frontend/src/components/university/modules/CourseFeedback.js b/frontend/src/components/university/modules/CourseFeedback.js new file mode 100644 index 0000000000000000000000000000000000000000..3f2fb3a834f5c5491d5d70e03599bea5816a150c --- /dev/null +++ b/frontend/src/components/university/modules/CourseFeedback.js @@ -0,0 +1,84 @@ +import React from "react"; + +import Table from "@material-ui/core/Table"; +import TableBody from "@material-ui/core/TableBody"; +import TableCell from "@material-ui/core/TableCell"; +import TableHead from "@material-ui/core/TableHead"; +import TableRow from "@material-ui/core/TableRow"; + +import PropTypes from "prop-types"; +import compose from "recompose/compose"; +import withStyles from "@material-ui/core/styles/withStyles"; + + +const styles = theme => ({ + table: { + margin: theme.spacing.unit * 10, + flex: "auto", + } +}); + +const data = [ + { + id: 1, + courseName: "Cours de statistique", + nbCredit: "7", + language: "Anglais", + interest: "7", + work_dose: "10", + following_ability: "5" + }, + { + id: 2, + courseName: "Architecture d'application internet", + nbCredit: "6", + language: "Norvégien", + interest: "9", + work_dose: "5", + following_ability: "2" + } +]; + + +class CourseFeedback extends React.Component { + render() { + const { classes } = this.props; + + return ( + <> + + + + Cours + Crédits + Langue + Intérêt /10 + Dose de travail /10 + Facilité à suivre la langue /10 + + + + {data.map(courseData => ( + + {courseData.courseName} + {courseData.nbCredit} + {courseData.language} + {courseData.interest} + {courseData.work_dose} + {courseData.following_ability} + + ))} + +
+ + ); + } +} + +CourseFeedback.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default compose( + withStyles(styles), +)(CourseFeedback); \ No newline at end of file diff --git a/frontend/src/components/university/modules/PreviousDeparture.js b/frontend/src/components/university/modules/PreviousDeparture.js index 0bccf9fe2fabdb8848443fd0df317034503d01a0..ce80578bafed75e6ce22d35c4cf5194870c9eb3d 100644 --- a/frontend/src/components/university/modules/PreviousDeparture.js +++ b/frontend/src/components/university/modules/PreviousDeparture.js @@ -1,45 +1,169 @@ import React from "react"; import PropTypes from "prop-types"; import withStyles from "@material-ui/core/styles/withStyles"; + import ExpansionPanel from "@material-ui/core/ExpansionPanel"; import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; -import Typography from "@material-ui/core/Typography"; import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; -import Divider from "@material-ui/core/Divider"; +import Typography from "@material-ui/core/Typography"; +import compose from "recompose/compose"; +import Paper from "@material-ui/core/Paper"; +import Button from "@material-ui/core/Button"; +import Grid from "@material-ui/core/Grid"; + +import Chip from "@material-ui/core/Chip"; + +import CourseFeedback from "./CourseFeedback"; + +let commentary = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; const styles = theme => ({ - root: { - width: "100%", + paper: { + margin: `${theme.spacing.unit}px auto`, + padding: theme.spacing.unit * 2, }, - heading: { - fontSize: theme.typography.pxToRem(15), - fontWeight: theme.typography.fontWeightRegular, + paperGrid: { + textAlign: "center", + padding: theme.spacing.unit * 3, + width: "100%", + background: "#767676", }, + gradingDiv: { + margin: theme.spacing.unit, + } }); -function SimpleExpansionPanel(props) { - const { classes } = props; - return ( -
- - }> - En lire d'avantage... - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, - sit amet blandit leo lobortis eget. - - - -
- ); +class TruncatedCommentaryOrMore extends React.Component { + + constructor(props) { + super(props); + this.state = { + expanded: false + }; + + this.getNewStateText = this.getNewStateText.bind(this); + this.getMoreTextDiv = this.getMoreTextDiv.bind(this); + } + + // Get the opposite of the actual text state (if expanded then unexpanded) + getNewStateText() { + this.setState({ + expanded: !this.state.expanded + }); + } + + getMoreTextDiv() { + if (this.state.expanded) { + return
{commentary}
; + } else { + return
{commentary.slice(0, 100)}...
; + } + } + + render() { + let expandedDiv = this.getMoreTextDiv(); + let button; + + if (this.state.expanded) { + button = ; + } else { + button = ; + } + + return ( +
+ {expandedDiv} + {button} +
+ ); + } } -SimpleExpansionPanel.propTypes = { + +class PreviousDeparture extends React.Component { + render() { + const {classes, rawModelData} = this.props; + + return ( + <> + + + + +
+ + + + Cadre de vie + 8/10 + + + + + Accueil des étudiants étrangers + 9/10 + + + + + Coût de la vie + 4/10 + + + + + Intérêt touristique + 3/10 + + + +
+ + + Avis général : + + commentary={commentary} + + + + }> + Evaluation des cours suivis + + + + + + + + ); + } + +} + + +PreviousDeparture.propTypes = { classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, + rawModelData: PropTypes.object.isRequired, }; -export default withStyles(styles)(SimpleExpansionPanel); +// const mapStateToProps = (state) => { +// return { +// }; +// }; + +// const mapDispatchToProps = (dispatch) => { +// return { +// api: { +// }, +// }; +// }; + + +export default compose( + withStyles(styles, {withTheme: true}), + // connect(mapStateToProps, mapDispatchToProps) +)(PreviousDeparture); diff --git a/frontend/src/components/university/tabs/PreviousDeparturesTab.js b/frontend/src/components/university/tabs/PreviousDeparturesTab.js index ef6b7f217bd03d24be07bfbec2aeebc4e20d394b..491c1aaf9d71a4deab0dcf5b9603a3e8d4b4e3f5 100644 --- a/frontend/src/components/university/tabs/PreviousDeparturesTab.js +++ b/frontend/src/components/university/tabs/PreviousDeparturesTab.js @@ -1,7 +1,21 @@ import React, {Component} from "react"; import PreviousDeparture from "../modules/PreviousDeparture"; -import ModuleWrapper from "../modules/common/ModuleWrapper"; + +const data = [ + { + studentName: "Ségolène", + speciality: "GI", + obj_info: {user_can_edit: true, user_can_moderate: true}, + updated_by: {pseudo: "sbriseme"} + }, + { + studentName: "Florent", + speciality: "GI", + obj_info: {user_can_edit: true, user_can_moderate: true}, + updated_by: {pseudo: "sbriseme"} + }, +]; /** @@ -14,9 +28,16 @@ class PreviousDeparturesTab extends Component { render() { return ( - - - + <> + { + data.map((rawModelData, idx) => ( + + )) + } + ); }