-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create training basics --> implement take training feature and resume…
… training feature for user (#1951) ## What? Here i have added a feature that will allow users to take the training from settings. User can choose from a list of available trainings and take the onplatform training. Users can also see the progress of the training and can resume the training from where they left off. ## Why? This is a follow up PR for #1950 ## How? Here we create 3 new views to handle the training. **1. `training.views.take_training`** This view will take care of training homepage. It will show progress of the training if the user has already started the training, show them details of the training and allow them to start/resume and review the training. **2. `training.views.take_module_training`** This view will take care of letting users take individual modules of the training. It will allow users to take the module from where they left off. Users will need to finish module1 before they can start module2 and so on. Here we have used a considerable amount of javascript to make the training interactive. How it works is when the user loads the module page, we initially load all the content, quizzes and order them based on the `order` field, and initially we hide all the content and quizzes. Then we show either the first content,quiz or the next one after a content, quiz that they had completed last time. and we keep doing this until the user has completed the module. **3. `training.views.update_module_progress`** This view uses a simple post request and expects an ajax request from the client. It will update the progress of the module and the progress of the training. ## Testing? [WIP] Following tests will be added 1. Check access to the training homepage 2. Check access to the training module page 3. Check valid and invalid submission of the training module 4. Check valid and invalid submission of the training ## Screenshots (optional) ![image](https://user-images.githubusercontent.com/24412619/228581570-568f28bc-28d3-4e22-a699-bd05092f77f2.png) ![image](https://user-images.githubusercontent.com/24412619/228581290-4615bc2e-8fbe-4aaf-9706-e19f34e7e1e0.png) ![image](https://user-images.githubusercontent.com/24412619/228581693-d42ab459-9563-49ee-98a0-bb5b61dfce2f.png) ![image](https://user-images.githubusercontent.com/24412619/228581764-e4368b6d-755c-460e-9496-0252c109a449.png) ## Anything Else? ### How to take a training as a user? 1. Login as user 2. Navigate to `Settings` 3. Select the training from the dropdown 4. Start the training
- Loading branch information
Showing
20 changed files
with
868 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.eachQuiz{ | ||
display: none | ||
} | ||
|
||
.blockContent{ | ||
display: none | ||
} | ||
|
||
.quizContainer { | ||
max-width: 100%; | ||
position: relative; | ||
margin: auto; | ||
display: block; | ||
} | ||
|
||
.blockContainer { | ||
max-width: 100%; | ||
position: relative; | ||
margin: auto; | ||
display: block; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from django import forms | ||
from django.db.models import Max, F, OuterRef | ||
|
||
from training.models import Course | ||
from user.models import TrainingType | ||
from user.enums import RequiredField | ||
|
||
|
||
class CourseForm(forms.ModelForm): | ||
|
||
class Meta: | ||
model = Course | ||
fields = ('training_type', ) | ||
labels = {'training_type': 'Training Type'} | ||
|
||
def __init__(self, *args, **kwargs): | ||
training_id = kwargs.pop('training_type', None) | ||
super().__init__(*args, **kwargs) | ||
|
||
self.fields['training_type'].queryset = self.fields['training_type'].queryset.annotate( | ||
max_version=Max('courses__version') | ||
).filter( | ||
courses__version=F('max_version'), | ||
required_field=RequiredField.PLATFORM, | ||
courses__is_active=True | ||
) | ||
|
||
self.training_type = TrainingType.objects.filter(id=training_id).first() | ||
|
||
self.fields['training_type'].initial = self.training_type | ||
|
||
if self.training_type: | ||
self.fields['training_type'].help_text = self.training_type.description |
29 changes: 29 additions & 0 deletions
29
physionet-django/training/migrations/0006_remove_course_trainings_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Generated by Django 4.2.11 on 2024-08-20 18:56 | ||
|
||
from django.db import migrations | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("training", "0005_course_trainings"), | ||
] | ||
|
||
operations = [ | ||
migrations.RemoveField( | ||
model_name="course", | ||
name="trainings", | ||
), | ||
migrations.AlterUniqueTogether( | ||
name="completedcontent", | ||
unique_together={("module_progress", "content")}, | ||
), | ||
migrations.AlterUniqueTogether( | ||
name="completedquiz", | ||
unique_together={("module_progress", "quiz")}, | ||
), | ||
migrations.AlterUniqueTogether( | ||
name="moduleprogress", | ||
unique_together={("course_progress", "module")}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{% extends 'base.html' %} | ||
|
||
{% load static %} | ||
|
||
{% block title %}Training - {{ course.training_type.name }}{% endblock %} | ||
|
||
{% block local_css %} | ||
<link rel="stylesheet" | ||
type="text/css" | ||
href="{% static 'project/css/project-home.css' %}"> | ||
{% endblock %} | ||
|
||
{% block content %} | ||
<div class="container"> | ||
<h1>{{ course.training_type.name }}</h1> | ||
{% include "message_snippet.html" %} | ||
<div class="description"> | ||
<h2>Training Description</h2> | ||
{{ course.training_type.description | safe }} | ||
</div> | ||
|
||
<div class="card mb-3"> | ||
<div class="card-header"> | ||
<h3>Training Modules</h3> | ||
</div> | ||
<div class="card-body"> | ||
{% if modules %} | ||
<table class="table table-hover"> | ||
<thead> | ||
<tr> | ||
<th scope="col">Module</th> | ||
<th scope="col">Progress</th> | ||
<th scope="col">Dates</th> | ||
<th scope="col">Action</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% for module in modules %} | ||
<tr> | ||
<td> | ||
<strong>{{ module.name }}</strong> | ||
</td> | ||
<td>{{ module.progress_status }}</td> | ||
<td>{{ module.progress_updated_date}}</td> | ||
<td> | ||
<a href="{% url 'current_module_block' course.training_type.slug module.pk module.last_completed_order %}"> | ||
{% if module.progress_status == ModuleStatus.COMPLETED.label %} | ||
Review | ||
{% elif module.progress_status == ModuleStatus.IN_PROGRESS.label %} | ||
Continue | ||
{% else %} | ||
Start | ||
{% endif %} | ||
</a> | ||
</td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
{% else %} | ||
<p>No datasets available.</p> | ||
{% endif %} | ||
</div> | ||
</div> | ||
<br> | ||
|
||
</div> | ||
{% endblock %} | ||
|
||
{% block local_js_bottom %} | ||
<script> | ||
</script> | ||
<script src="{% static 'custom/js/resize-ck.js' %}"></script> | ||
{% endblock %} |
Oops, something went wrong.