diff --git a/advlabdb/adminModelViews.py b/advlabdb/adminModelViews.py index 3a2ea0e..8d0e52f 100644 --- a/advlabdb/adminModelViews.py +++ b/advlabdb/adminModelViews.py @@ -26,7 +26,7 @@ from wtforms.validators import URL, DataRequired, Email, NumberRange, Optional from advlabdb import adminSpace, app, assistantSpace, db, user_datastore from advlabdb.configUtils import getConfig -from advlabdb.customClasses import SecureAdminBaseView, SecureAdminModelView +from advlabdb.customClasses import SecureAdminBaseView, SecureAdminModelView, CustomIdEndpointLinkRowAction from advlabdb.database_import import importFromFile from advlabdb.exceptions import DataBaseException, ModelViewException from advlabdb.models import ( @@ -59,7 +59,25 @@ def semesterExperimentQueryFactory(): return SemesterExperiment.query.filter(SemesterExperiment.semester == userActiveSemester()) +def semesterFilterOptions(): + semesters = Semester.query.order_by(Semester.id.desc()) + return tuple((semester.id, semester.repr()) for semester in semesters) + + class UserView(SecureAdminModelView): + @expose("/") + def index_view(self): + # To update filter options + self._refresh_filters_cache() + return super().index_view() + + class SemesterFilter(FilterEqual): + def get_options(self, view): + return semesterFilterOptions() + + def apply(self, query, value, alias=None): + return query.filter(self.column.active_semester_id == int(value)) + class CreateForm(Form): def roleQueryFactory(): return Role.query @@ -135,8 +153,8 @@ class UserView(SecureAdminModelView): "email", ] column_filters = ( + SemesterFilter(User, "Active Semester"), "active", - "active_semester", ) column_editable_list = [ "active", @@ -218,12 +236,12 @@ class UserView(SecureAdminModelView): class RoleView(SecureAdminModelView): + can_export = False + can_set_page_size = False can_create = False can_edit = False can_delete = False column_display_actions = False - can_export = False - can_set_page_size = False column_list = [ "name", @@ -326,7 +344,6 @@ class PartView(SecureAdminModelView): column_list = [ "program", "number", - "semester", ] column_details_list = column_list + [ "part_students", @@ -342,6 +359,8 @@ class PartView(SecureAdminModelView): ) } + column_searchable_list = ["program.label", "number"] + def queryFilter(self): return Part.semester == userActiveSemester() @@ -390,10 +409,10 @@ class StudentView(SecureAdminModelView): column_extra_row_actions = [ EndpointLinkRowAction( - "glyphicon glyphicon-time", + icon_class="fa fa-history", + endpoint="experimentmark.index_view", id_arg="flt1_0", title="Experiments history", - endpoint="experimentmark.index_view", ) ] @@ -426,6 +445,18 @@ class PartStudentView(SecureAdminModelView): def apply(self, query, value, alias=None): return query.filter(self.column.part_id == int(value)) + class StudentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.student_id + + class GroupEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.group_id + + class PartEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.part_id + class CreateForm(Form): def studentQueryFactory(): return Student.query @@ -474,6 +505,24 @@ class PartStudentView(SecureAdminModelView): "experiment_marks", ) + column_extra_row_actions = [ + StudentEndpointLinkRowAction( + icon_class="fa fa-user", + endpoint="student.details_view", + title="Student", + ), + GroupEndpointLinkRowAction( + icon_class="fa fa-users", + endpoint="group.details_view", + title="Group", + ), + PartEndpointLinkRowAction( + icon_class="fa fa-puzzle-piece", + endpoint="part.details_view", + title="Part", + ), + ] + def queryFilter(self): return PartStudent.part.has(Part.semester == userActiveSemester()) @@ -530,12 +579,15 @@ class GroupView(SecureAdminModelView): return CustomForm + can_view_details = True + column_list = [ "number", "program", "part_students", "group_experiments", ] + column_details_list = column_list column_filters = ( ProgramFilter(Group, "Program"), "number", @@ -624,6 +676,10 @@ class SemesterExperimentView(SecureAdminModelView): def apply(self, query, value, alias=None): return query.filter(self.column.experiment.has(Experiment.program_id == int(value))) + class ExperimentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.experiment_id + class CreateForm(Form): def experimentQueryFactory(): return Experiment.query.filter(Experiment.active == True) @@ -680,6 +736,14 @@ class SemesterExperimentView(SecureAdminModelView): "experiment.title", ] + column_extra_row_actions = [ + ExperimentEndpointLinkRowAction( + icon_class="fa fa-flask", + endpoint="experiment.details_view", + title="Experiment", + ), + ] + def queryFilter(self): return SemesterExperiment.semester == userActiveSemester() @@ -698,6 +762,10 @@ class SemesterExperimentView(SecureAdminModelView): class AssistantView(SecureAdminModelView): + class UserEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.user_id + def assistantUserQueryFactory(): return User.query.filter(User.roles.any(Role.name == "assistant")) @@ -706,7 +774,6 @@ class AssistantView(SecureAdminModelView): column_list = [ "user.first_name", "user.last_name", - "user", "semester_experiments", ] column_details_list = column_list + [ @@ -744,8 +811,39 @@ class AssistantView(SecureAdminModelView): ), } + column_extra_row_actions = [ + UserEndpointLinkRowAction( + icon_class="fa fa-user", + endpoint="user.details_view", + title="User", + ), + ] -# TODO: Add AdminView + +class AdminView(SecureAdminModelView): + class UserEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.user_id + + can_export = False + can_set_page_size = False + can_create = False + can_edit = False + can_delete = False + + column_list = [ + "user.first_name", + "user.last_name", + ] + column_filters = ("user.active",) + + column_extra_row_actions = [ + UserEndpointLinkRowAction( + icon_class="fa fa-user", + endpoint="user.details_view", + title="User", + ), + ] assistantBlankText = "Auto assign if experiment has only one assistant" @@ -755,7 +853,7 @@ def experimentFilterOptions(): activeExperiments = Experiment.query.filter(Experiment.active == True) return tuple( ( - f"{activeExperiment.number},{activeExperiment.program.id}", + f"{activeExperiment.number},{activeExperiment.program_id}", f"{activeExperiment.number} {activeExperiment.program.repr()}", ) for activeExperiment in activeExperiments @@ -787,6 +885,14 @@ class GroupExperimentView(SecureAdminModelView): ), ) + class GroupEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.group_id + + class SemesterExperimentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.semester_experiment_id + class CreateForm(Form): group = QuerySelectField( "Group", @@ -830,6 +936,7 @@ class GroupExperimentView(SecureAdminModelView): form = CreateForm can_edit = False + can_view_details = True column_list = [ "group", @@ -837,6 +944,7 @@ class GroupExperimentView(SecureAdminModelView): "appointments", "experiment_marks", ] + column_details_list = column_list column_filters = ( ExperimentFilter(GroupExperiment, "Experiment"), "group.number", @@ -844,6 +952,19 @@ class GroupExperimentView(SecureAdminModelView): "experiment_marks", ) + column_extra_row_actions = [ + GroupEndpointLinkRowAction( + icon_class="fa fa-users", + endpoint="group.details_view", + title="Group", + ), + SemesterExperimentEndpointLinkRowAction( + icon_class="fa fa-flask", + endpoint="semesterexperiment.details_view", + title="SemesterExperiment", + ), + ] + def queryFilter(self): return GroupExperiment.group.has(Group.semester == userActiveSemester()) @@ -917,6 +1038,14 @@ class AppointmentView(SecureAdminModelView): def apply(self, query, value, alias=None): return query.filter(self.column.assistant_id == int(value)) + class GroupExperimentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.group_experiment_id + + class AssistantEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.assistant_id + class CreateForm(Form): group_experiment = QuerySelectField( "Group Experiment", @@ -948,6 +1077,19 @@ class AppointmentView(SecureAdminModelView): "special", ] + column_extra_row_actions = [ + GroupExperimentEndpointLinkRowAction( + icon_class="fa fa-flask", + endpoint="groupexperiment.details_view", + title="GroupExperiment", + ), + AssistantEndpointLinkRowAction( + icon_class="fa fa-user-secret", + endpoint="assistant.details_view", + title="Assistant", + ), + ] + def queryFilter(self): return Appointment.group_experiment.has( GroupExperiment.semester_experiment.has(SemesterExperiment.semester == userActiveSemester()) @@ -1051,8 +1193,7 @@ class ExperimentMarkView(SecureAdminModelView): class SemesterFilter(FilterEqual): def get_options(self, view): - semesters = Semester.query.order_by(Semester.id.desc()) - return tuple((semester.id, semester.repr()) for semester in semesters) + return semesterFilterOptions() def apply(self, query, value, alias=None): return query.filter( @@ -1061,6 +1202,18 @@ class ExperimentMarkView(SecureAdminModelView): ) ) + class PartStudentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.part_student_id + + class GroupExperimentEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.group_experiment_id + + class AssistantEndpointLinkRowAction(CustomIdEndpointLinkRowAction): + def customId(self, row): + return row.assistant_id + class CreateForm(Form): part_student = QuerySelectField( "Part Student", @@ -1114,6 +1267,24 @@ class ExperimentMarkView(SecureAdminModelView): ) column_default_sort = [("oral_mark", False), ("protocol_mark", False)] + column_extra_row_actions = [ + PartStudentEndpointLinkRowAction( + icon_class="fa fa-user", + endpoint="partstudent.details_view", + title="PartStudent", + ), + GroupExperimentEndpointLinkRowAction( + icon_class="fa fa-flask", + endpoint="groupexperiment.details_view", + title="GroupExperiment", + ), + AssistantEndpointLinkRowAction( + icon_class="fa fa-user-secret", + endpoint="assistant.details_view", + title="Assistant", + ), + ] + """ # Deactivated for the experiments history of a student. def queryFilter(self): @@ -1148,6 +1319,9 @@ class ExperimentMarkView(SecureAdminModelView): class ProgramView(SecureAdminModelView): + can_export = False + can_set_page_size = False + can_view_details = True column_list = [ @@ -1210,6 +1384,7 @@ adminSpace.add_view(SemesterExperimentView(SemesterExperiment, db.session)) adminSpace.add_view(SemesterView(Semester, db.session)) adminSpace.add_view(PartView(Part, db.session)) adminSpace.add_view(AssistantView(Assistant, db.session)) +adminSpace.add_view(AdminView(Admin, db.session)) adminSpace.add_view(UserView(User, db.session)) adminSpace.add_view(RoleView(Role, db.session)) adminSpace.add_view(ProgramView(Program, db.session))