mirror of
https://codeberg.org/Mo8it/AdvLabDB.git
synced 2024-12-20 23:41:20 +00:00
Added assistantSpace
This commit is contained in:
parent
e56aca7545
commit
0be6b64b8a
8 changed files with 111 additions and 47 deletions
|
@ -50,7 +50,6 @@ This URL leads to the home page where you can login with this testing admin acco
|
||||||
- password: admin
|
- password: admin
|
||||||
|
|
||||||
# To-Do:
|
# To-Do:
|
||||||
- Rest of admin model views
|
|
||||||
- Calculate final experiment and part mark
|
- Calculate final experiment and part mark
|
||||||
- Assistants space
|
- Assistants space
|
||||||
- Deactivate assistants account after a while if not assigned to experiments
|
- Deactivate assistants account after a while if not assigned to experiments
|
||||||
|
|
|
@ -26,11 +26,25 @@ fsqla.FsModels.set_db_info(db)
|
||||||
|
|
||||||
from advlabdb import customClasses
|
from advlabdb import customClasses
|
||||||
|
|
||||||
admin = Admin(
|
adminSpace = Admin(
|
||||||
app,
|
app,
|
||||||
name="Admin@AdvLabDB",
|
name="Admin@AdvLabDB",
|
||||||
|
url="/admin",
|
||||||
|
endpoint="adminSpace",
|
||||||
template_mode="bootstrap3",
|
template_mode="bootstrap3",
|
||||||
index_view=customClasses.SecureAdminIndexView(template="admin_index.html"),
|
index_view=customClasses.SecureAdminIndexView(
|
||||||
|
name="Admin", template="admin_index.html", url="/admin", endpoint="adminSpace"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assistantSpace = Admin(
|
||||||
|
app,
|
||||||
|
name="Assistant@AdvLabDB",
|
||||||
|
url="/assistant",
|
||||||
|
endpoint="assistantSpace",
|
||||||
|
template_mode="bootstrap3",
|
||||||
|
index_view=customClasses.SecureAssistantIndexView(
|
||||||
|
name="Assistant", template="assistant_index.html", url="/assistant", endpoint="assistantSpace"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
from advlabdb import models
|
from advlabdb import models
|
||||||
|
|
|
@ -10,16 +10,27 @@ def adminViewIsAccessible():
|
||||||
return current_user.has_role("admin")
|
return current_user.has_role("admin")
|
||||||
|
|
||||||
|
|
||||||
class SecureAdminIndexView(AdminIndexView):
|
def assistantViewIsAccessible():
|
||||||
def is_accessible(self):
|
return current_user.has_role("assistant")
|
||||||
return adminViewIsAccessible()
|
|
||||||
|
|
||||||
|
|
||||||
|
class CustomIndexView(AdminIndexView):
|
||||||
def inaccessible_callback(self, name, **kwargs):
|
def inaccessible_callback(self, name, **kwargs):
|
||||||
# Redirect to login page if user doesn't have access
|
# Redirect to login page if user doesn't have access
|
||||||
return redirect(url_for("security.login", next=request.url))
|
return redirect(url_for("security.login", next=request.url))
|
||||||
|
|
||||||
|
|
||||||
class SecureModelView(ModelView):
|
class SecureAdminIndexView(CustomIndexView):
|
||||||
|
def is_accessible(self):
|
||||||
|
return adminViewIsAccessible()
|
||||||
|
|
||||||
|
|
||||||
|
class SecureAssistantIndexView(CustomIndexView):
|
||||||
|
def is_accessible(self):
|
||||||
|
return assistantViewIsAccessible()
|
||||||
|
|
||||||
|
|
||||||
|
class CustomModelView(ModelView):
|
||||||
can_export = True
|
can_export = True
|
||||||
can_set_page_size = True
|
can_set_page_size = True
|
||||||
|
|
||||||
|
@ -27,16 +38,9 @@ class SecureModelView(ModelView):
|
||||||
edit_modal = True
|
edit_modal = True
|
||||||
details_modal = True
|
details_modal = True
|
||||||
|
|
||||||
list_template = "admin_list.html"
|
|
||||||
create_template = "admin_create.html"
|
|
||||||
edit_template = "admin_edit.html"
|
|
||||||
|
|
||||||
queryFilter = None
|
queryFilter = None
|
||||||
customCreateModel = None
|
customCreateModel = None
|
||||||
|
|
||||||
def is_accessible(self):
|
|
||||||
return adminViewIsAccessible()
|
|
||||||
|
|
||||||
def inaccessible_callback(self, name, **kwargs):
|
def inaccessible_callback(self, name, **kwargs):
|
||||||
# Redirect to login page if user doesn't have access
|
# Redirect to login page if user doesn't have access
|
||||||
return redirect(url_for("security.login", next=request.url))
|
return redirect(url_for("security.login", next=request.url))
|
||||||
|
@ -80,3 +84,21 @@ class SecureModelView(ModelView):
|
||||||
self.after_model_change(form, model, True)
|
self.after_model_change(form, model, True)
|
||||||
|
|
||||||
return model
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
class SecureAdminModelView(CustomModelView):
|
||||||
|
list_template = "admin_list.html"
|
||||||
|
create_template = "admin_create.html"
|
||||||
|
edit_template = "admin_edit.html"
|
||||||
|
|
||||||
|
def is_accessible(self):
|
||||||
|
return adminViewIsAccessible()
|
||||||
|
|
||||||
|
|
||||||
|
class SecureAssistantModelView(CustomModelView):
|
||||||
|
list_template = "assistant_list.html"
|
||||||
|
create_template = "assistant_create.html"
|
||||||
|
edit_template = "assistant_edit.html"
|
||||||
|
|
||||||
|
def is_accessible(self):
|
||||||
|
return assistantViewIsAccessible()
|
||||||
|
|
|
@ -10,9 +10,9 @@ from flask_admin.contrib.sqla.fields import QuerySelectMultipleField, QuerySelec
|
||||||
from flask_admin.helpers import get_form_data
|
from flask_admin.helpers import get_form_data
|
||||||
from wtforms.fields.html5 import DateField
|
from wtforms.fields.html5 import DateField
|
||||||
|
|
||||||
from advlabdb import admin, app, db, user_datastore
|
from advlabdb import adminSpace, app, db, user_datastore
|
||||||
from advlabdb.configUtils import getConfig
|
from advlabdb.configUtils import getConfig
|
||||||
from advlabdb.customClasses import SecureModelView
|
from advlabdb.customClasses import SecureAdminModelView
|
||||||
from advlabdb.models import (
|
from advlabdb.models import (
|
||||||
Appointment,
|
Appointment,
|
||||||
Assistant,
|
Assistant,
|
||||||
|
@ -37,7 +37,7 @@ from advlabdb.utils import (
|
||||||
from advlabdb.exceptions import ModelViewException, DataBaseException
|
from advlabdb.exceptions import ModelViewException, DataBaseException
|
||||||
|
|
||||||
|
|
||||||
class UserView(SecureModelView):
|
class UserView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
def roleQueryFactory():
|
def roleQueryFactory():
|
||||||
return Role.query
|
return Role.query
|
||||||
|
@ -132,7 +132,7 @@ class UserView(SecureModelView):
|
||||||
) # Password is automatically hashed with this method
|
) # Password is automatically hashed with this method
|
||||||
|
|
||||||
|
|
||||||
class RoleView(SecureModelView):
|
class RoleView(SecureAdminModelView):
|
||||||
can_create = False
|
can_create = False
|
||||||
can_edit = False
|
can_edit = False
|
||||||
can_delete = False
|
can_delete = False
|
||||||
|
@ -141,7 +141,7 @@ class RoleView(SecureModelView):
|
||||||
column_list = ["name", "description"]
|
column_list = ["name", "description"]
|
||||||
|
|
||||||
|
|
||||||
class SemesterView(SecureModelView):
|
class SemesterView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
def labelDefault():
|
def labelDefault():
|
||||||
if userActiveSemester().label == "WS":
|
if userActiveSemester().label == "WS":
|
||||||
|
@ -191,7 +191,7 @@ class SemesterView(SecureModelView):
|
||||||
def after_model_change(self, form, model, is_created):
|
def after_model_change(self, form, model, is_created):
|
||||||
setUserActiveSemester(model.id)
|
setUserActiveSemester(model.id)
|
||||||
|
|
||||||
admin.add_link(
|
adminSpace.add_link(
|
||||||
MenuLink(
|
MenuLink(
|
||||||
name=model.repr(),
|
name=model.repr(),
|
||||||
url=url_for("set_semester") + "?semester_id=" + str(model.id),
|
url=url_for("set_semester") + "?semester_id=" + str(model.id),
|
||||||
|
@ -204,7 +204,7 @@ def programQueryFactory():
|
||||||
return Program.query
|
return Program.query
|
||||||
|
|
||||||
|
|
||||||
class PartView(SecureModelView):
|
class PartView(SecureAdminModelView):
|
||||||
can_view_details = True
|
can_view_details = True
|
||||||
|
|
||||||
column_sortable_list = []
|
column_sortable_list = []
|
||||||
|
@ -225,7 +225,7 @@ class PartView(SecureModelView):
|
||||||
return Part(program=form.program.data, number=form.number.data, semester=userActiveSemester())
|
return Part(program=form.program.data, number=form.number.data, semester=userActiveSemester())
|
||||||
|
|
||||||
|
|
||||||
class StudentView(SecureModelView):
|
class StudentView(SecureAdminModelView):
|
||||||
can_view_details = True
|
can_view_details = True
|
||||||
|
|
||||||
column_list = ["student_number", "first_name", "last_name", "uni_email", "contact_email", "part_students"]
|
column_list = ["student_number", "first_name", "last_name", "uni_email", "contact_email", "part_students"]
|
||||||
|
@ -262,7 +262,7 @@ def groupQueryFactory():
|
||||||
markChoices = [(-1, "-")] + list(zip(range(16)[::-1], range(16)[::-1]))
|
markChoices = [(-1, "-")] + list(zip(range(16)[::-1], range(16)[::-1]))
|
||||||
|
|
||||||
|
|
||||||
class PartStudentView(SecureModelView):
|
class PartStudentView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
def studentQueryFactory():
|
def studentQueryFactory():
|
||||||
return Student.query
|
return Student.query
|
||||||
|
@ -318,7 +318,7 @@ def partStudentQueryFactory():
|
||||||
return PartStudent.query.filter(PartStudent.part_id.in_([part.id for part in userActiveSemester().parts]))
|
return PartStudent.query.filter(PartStudent.part_id.in_([part.id for part in userActiveSemester().parts]))
|
||||||
|
|
||||||
|
|
||||||
class GroupView(SecureModelView):
|
class GroupView(SecureAdminModelView):
|
||||||
def formFactory(create, group):
|
def formFactory(create, group):
|
||||||
if create:
|
if create:
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ class GroupView(SecureModelView):
|
||||||
return form(get_form_data(), obj=obj)
|
return form(get_form_data(), obj=obj)
|
||||||
|
|
||||||
|
|
||||||
class ExperimentView(SecureModelView):
|
class ExperimentView(SecureAdminModelView):
|
||||||
can_view_details = True
|
can_view_details = True
|
||||||
|
|
||||||
column_filters = ["active"]
|
column_filters = ["active"]
|
||||||
|
@ -396,7 +396,7 @@ def assistantQueryFactory():
|
||||||
return Assistant.query.filter(Assistant.user_id.in_([user.id for user in User.query.filter(User.active == True)]))
|
return Assistant.query.filter(Assistant.user_id.in_([user.id for user in User.query.filter(User.active == True)]))
|
||||||
|
|
||||||
|
|
||||||
class SemesterExperimentView(SecureModelView):
|
class SemesterExperimentView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
def experimentQueryFactory():
|
def experimentQueryFactory():
|
||||||
return Experiment.query.filter(Experiment.active == True)
|
return Experiment.query.filter(Experiment.active == True)
|
||||||
|
@ -428,7 +428,7 @@ class SemesterExperimentView(SecureModelView):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AssistantView(SecureModelView):
|
class AssistantView(SecureAdminModelView):
|
||||||
def assistantUserQueryFactory():
|
def assistantUserQueryFactory():
|
||||||
return User.query.filter(User.roles.any(Role.name == "assistant"))
|
return User.query.filter(User.roles.any(Role.name == "assistant"))
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ class AssistantView(SecureModelView):
|
||||||
assistantBlankText = "Auto assign if experiment has only one assistant"
|
assistantBlankText = "Auto assign if experiment has only one assistant"
|
||||||
|
|
||||||
|
|
||||||
class GroupExperimentView(SecureModelView):
|
class GroupExperimentView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
def semesterExperimentQueryFactory():
|
def semesterExperimentQueryFactory():
|
||||||
return SemesterExperiment.query.filter(SemesterExperiment.semester == userActiveSemester())
|
return SemesterExperiment.query.filter(SemesterExperiment.semester == userActiveSemester())
|
||||||
|
@ -545,7 +545,7 @@ def groupExperimentQueryFactory():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AppointmentView(SecureModelView):
|
class AppointmentView(SecureAdminModelView):
|
||||||
class CreateForm(Form):
|
class CreateForm(Form):
|
||||||
group_experiment = QuerySelectField(
|
group_experiment = QuerySelectField(
|
||||||
"Group Experiment",
|
"Group Experiment",
|
||||||
|
@ -600,7 +600,7 @@ class AppointmentView(SecureModelView):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ExperimentMarkView(SecureModelView):
|
class ExperimentMarkView(SecureAdminModelView):
|
||||||
class StudentIdFilter(BaseSQLAFilter):
|
class StudentIdFilter(BaseSQLAFilter):
|
||||||
def apply(self, query, value, alias=None):
|
def apply(self, query, value, alias=None):
|
||||||
return query.filter(self.column == value)
|
return query.filter(self.column == value)
|
||||||
|
@ -680,7 +680,7 @@ class ExperimentMarkView(SecureModelView):
|
||||||
self.session.rollback()
|
self.session.rollback()
|
||||||
|
|
||||||
|
|
||||||
class ProgramView(SecureModelView):
|
class ProgramView(SecureAdminModelView):
|
||||||
can_view_details = True
|
can_view_details = True
|
||||||
|
|
||||||
column_list = ["label"]
|
column_list = ["label"]
|
||||||
|
@ -688,25 +688,25 @@ class ProgramView(SecureModelView):
|
||||||
column_details_list = column_list + form_excluded_columns
|
column_details_list = column_list + form_excluded_columns
|
||||||
|
|
||||||
|
|
||||||
admin.add_view(StudentView(Student, db.session))
|
adminSpace.add_view(StudentView(Student, db.session))
|
||||||
admin.add_view(PartStudentView(PartStudent, db.session))
|
adminSpace.add_view(PartStudentView(PartStudent, db.session))
|
||||||
admin.add_view(GroupView(Group, db.session))
|
adminSpace.add_view(GroupView(Group, db.session))
|
||||||
admin.add_view(GroupExperimentView(GroupExperiment, db.session))
|
adminSpace.add_view(GroupExperimentView(GroupExperiment, db.session))
|
||||||
admin.add_view(AppointmentView(Appointment, db.session))
|
adminSpace.add_view(AppointmentView(Appointment, db.session))
|
||||||
admin.add_view(ExperimentMarkView(ExperimentMark, db.session))
|
adminSpace.add_view(ExperimentMarkView(ExperimentMark, db.session))
|
||||||
admin.add_view(ExperimentView(Experiment, db.session))
|
adminSpace.add_view(ExperimentView(Experiment, db.session))
|
||||||
admin.add_view(SemesterExperimentView(SemesterExperiment, db.session))
|
adminSpace.add_view(SemesterExperimentView(SemesterExperiment, db.session))
|
||||||
admin.add_view(AssistantView(Assistant, db.session))
|
adminSpace.add_view(AssistantView(Assistant, db.session))
|
||||||
admin.add_view(ProgramView(Program, db.session))
|
adminSpace.add_view(ProgramView(Program, db.session))
|
||||||
admin.add_view(PartView(Part, db.session))
|
adminSpace.add_view(PartView(Part, db.session))
|
||||||
admin.add_view(SemesterView(Semester, db.session))
|
adminSpace.add_view(SemesterView(Semester, db.session))
|
||||||
admin.add_view(UserView(User, db.session))
|
adminSpace.add_view(UserView(User, db.session))
|
||||||
admin.add_view(RoleView(Role, db.session))
|
adminSpace.add_view(RoleView(Role, db.session))
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
semesters = Semester.query.order_by(Semester.id)
|
semesters = Semester.query.order_by(Semester.id)
|
||||||
for semester in semesters:
|
for semester in semesters:
|
||||||
admin.add_link(
|
adminSpace.add_link(
|
||||||
MenuLink(
|
MenuLink(
|
||||||
name=semester.repr(),
|
name=semester.repr(),
|
||||||
url=url_for("set_semester") + "?semester_id=" + str(semester.id),
|
url=url_for("set_semester") + "?semester_id=" + str(semester.id),
|
||||||
|
@ -714,4 +714,4 @@ with app.app_context():
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
admin.add_link(MenuLink(name="Logout", url=url_for("security.logout")))
|
adminSpace.add_link(MenuLink(name="Logout", url=url_for("security.logout")))
|
||||||
|
|
7
advlabdb/templates/assistant_create.html
Normal file
7
advlabdb/templates/assistant_create.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{% from "macros.html" import information %}
|
||||||
|
{% extends "admin/model/create.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{ information(current_user, userActiveSemester, role="assistant") }}
|
||||||
|
{{super()}}
|
||||||
|
{% endblock %}
|
7
advlabdb/templates/assistant_edit.html
Normal file
7
advlabdb/templates/assistant_edit.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{% from "macros.html" import information %}
|
||||||
|
{% extends "admin/model/edit.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{ information(current_user, userActiveSemester, role="assistant") }}
|
||||||
|
{{super()}}
|
||||||
|
{% endblock %}
|
8
advlabdb/templates/assistant_index.html
Normal file
8
advlabdb/templates/assistant_index.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% from "macros.html" import information %}
|
||||||
|
{% extends "admin/index.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{ information(current_user, userActiveSemester, role="assistant") }}
|
||||||
|
<h3>Welcome back!</h3>
|
||||||
|
{{super()}}
|
||||||
|
{% endblock %}
|
7
advlabdb/templates/assistant_list.html
Normal file
7
advlabdb/templates/assistant_list.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{% from "macros.html" import information %}
|
||||||
|
{% extends "admin/model/list.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{ information(current_user, userActiveSemester, role="assistant") }}
|
||||||
|
{{super()}}
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue