Skip to content

Commit

Permalink
Added remove option for personalized points goals and fixed issues fr…
Browse files Browse the repository at this point in the history
…om review
  • Loading branch information
mikaelGusse committed Aug 15, 2024
1 parent f0263b6 commit b93cbd1
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 25 deletions.
2 changes: 2 additions & 0 deletions e2e_tests/test_points_goal_set.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from playwright.sync_api import Page, expect

from e2e_tests.helpers import login


def test_points_goal_set(page: Page) -> None:
login(page, "student", "student")

Expand Down
65 changes: 63 additions & 2 deletions exercise/static/exercise/personalized_points_goal.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
$(document).ready(function() {
const $pointsGoalForm = $('#pointsGoalForm');
document.getElementById('id_personalized_points_goal_input').focus();
const $inputField = $('#id_personalized_points_goal_input'); // Use jQuery to select the input field
$inputField.focus();
$pointsGoalForm.on('submit', function(event) {
event.preventDefault();

// Validate input
const inputValue = $inputField.val().trim();

const isNumber = !isNaN(inputValue) && inputValue !== '';
const isPercentage = inputValue.endsWith('%') && !isNaN(inputValue.slice(0, -1));

if (!isNumber && !isPercentage) {
$('#validation-alert').show();
setTimeout(function() {
$('#validation-errors-alert').hide();
}, 5000);
return;
}

$.ajax({
type: 'POST',
url: $pointsGoalForm.attr('action'),
Expand Down Expand Up @@ -39,7 +55,7 @@ $(document).ready(function() {
// If the span element does not exist, create it
if (spanElement == null) {
spanElement = doc.createElement('span');
spanElement.className = 'personalized-points-text text-nowrap';
spanElement.className = 'personalized-points-full-text text-nowrap';
doc.body.appendChild(spanElement);
spanElement.innerHTML = "<br>" + $pointsGoalForm.data('personalized-points-goal-tooltip-text') + ": " + response.personalized_points_goal_points;
}
Expand Down Expand Up @@ -82,4 +98,49 @@ $(document).ready(function() {
}
});
});
$('#deletePointsGoalForm').on('submit', function(event) {
event.preventDefault();

$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize() + '&delete=true',
success: function(response) {
// Update page dynamically
const $progressElement = $('#progress-' + $pointsGoalForm.data('module-url'));
const $progressDiv = $progressElement.find('.progress');

// Remove goal indicator
let $goalPointsElement = $progressElement.find('.goal-points');
$goalPointsElement.removeClass('goal-points');

// Update tooltip
const tooltipTitle = $progressDiv.attr('data-original-title');
const parser = new DOMParser();
const doc = parser.parseFromString(tooltipTitle, 'text/html');

let spanElement = doc.querySelector('span.personalized-points-full-text');
spanElement.remove();

const updatedTooltipTitle = doc.body.innerHTML;
$progressDiv.attr('data-original-title', updatedTooltipTitle);

// Update progress-bar style
$progressDiv.find('.progress-bar').removeClass('progress-bar-primary');

$('#remove-success-alert').show();
setTimeout(function() {
$('#remove-success-alert').hide();
}, 5000);

},
error: function(xhr, status, error) {
// Handle error response
$('#remove-warning-alert').show();
setTimeout(function() {
$('#remove-warning-alert').hide();
}, 5000);
}
});
});
});
2 changes: 1 addition & 1 deletion exercise/templates/exercise/_points_progress.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="progress" data-toggle="tooltip" data-html="true" data-placement="bottom"
title="{% translate 'POINTS' %}: &lt;span class='text-nowrap'&gt;{{ formatted_points }} / {{ max }}&lt;/span&gt;
{% if required %} &lt;br&gt; {% translate 'POINTS_TO_PASS' %}: &lt;span class='text-nowrap'&gt;{{ required }}&lt;/span&gt; {% endif %}
{% if personalized_points_module_goal %} &lt;br&gt;{% translate 'PERSONALIZED_POINTS_GOAL' %}: &lt;span class='personalized-points-text text-nowrap'&gt;{{ personalized_points_module_goal_points|floatformat:"0" }}&lt;/span&gt;{% endif %}"
{% if personalized_points_module_goal %} &lt;br&gt;&lt;span class='personalized-points-full-text text-nowrap'&gt;{% translate 'PERSONALIZED_POINTS_GOAL' %}: &lt;span class='personalized-points-text text-nowrap'&gt;&lt;/span&gt;{{ personalized_points_module_goal_points|floatformat:"0" }}&lt;/span&gt;{% endif %}"
>
<div class="progress-bar progress-bar-striped progress-bar-{% if full_score %}success{% elif percentage >= personalized_points_module_goal %}primary{% elif passed %}warning{% else %}danger{% endif %}"
rel="progressbar" aria-valuenow="{{ points }}" aria-valuemin="0" aria-valuemax="{{ max }}"
Expand Down
28 changes: 24 additions & 4 deletions exercise/templates/exercise/personalized_points_goal_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@
<div class="alert alert-warning" id="warning-alert" style="display: none;">
{% translate "PERSONALIZED_POINTS_MODAL_FAILURE" %}
</div>
<div class="alert alert-warning" id="validation-alert" style="display: none;">
{% translate "PERSONALIZED_POINTS_MODAL_NOT_NUMBER" %}
</div>
<div class="alert alert-danger" id="danger-alert" style="display: none;">
{% translate "PERSONALIZED_POINTS_MODAL_LESS_THAN_REQUIRED" %}
</div>
<h4 class="title" id="pointsGoalModalLabel">{% translate "PERSONALIZED_POINTS_MODAL_TITLE" %} {{ module.name|parse_localization}}</h4>
<div class="alert alert-success" id="remove-success-alert" style="display: none;">
{% translate "PERSONALIZED_POINTS_MODAL_REMOVE_SUCCESS" %}
</div>
<div class="alert alert-warning" id="remove-warning-alert" style="display: none;">
{% translate "PERSONALIZED_POINTS_MODAL_REMOVE_FAILURE" %}
</div>
<h4 class="title" id="pointsGoalModalLabel">{% translate "PERSONALIZED_POINTS_MODAL_TITLE" %} "{{ module.name|parse_localization}}"</h4>
</div>
<div class="modal-body">
<form id="pointsGoalForm" method="POST"
Expand All @@ -38,8 +47,19 @@ <h4 class="title" id="pointsGoalModalLabel">{% translate "PERSONALIZED_POINTS_MO
<p style="margin-top: 5px;">{% translate "POINTS_TO_PASS" %}: <span id="required-points">{{ module.points_to_pass }}</span></p>
{% endif %}
</div>
<div>
<button type="submit" class="aplus-button--default aplus-button--md">{% translate "SAVE" %}</button>
</div>
<div style="display: flex;">
<button type="submit" class="aplus-button--default aplus-button--md" style="margin-top: 10px;">{% translate "SAVE" %}</button>
</form>
<form id="deletePointsGoalForm" method="POST"
action="{% url 'save_points_goal_form_view' course_slug=course.url instance_slug=instance.url module_slug=module.url %}"
data-module-url="{{module.url|lower}}"
data-personalized-points-goal-text="{% translate 'PERSONALIZED_POINTS_GOAL ' %}"
data-personalized-points-goal-tooltip-text="{% translate 'POINTS_GOAL' %}"
data-points="{{ points }}"
>
{% csrf_token %}
<button type="submit" class="aplus-button--danger aplus-button--md" style="margin-top: 10px; margin-left: 5px;">{% translate "REMOVE" %}</button>
</form>
</div>

</div>
3 changes: 3 additions & 0 deletions exercise/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@
re_path(MODULE_URL_PREFIX + r'save_points_goal_form/$',
views.StudentModuleGoalFormView.as_view(),
name="save_points_goal_form_view"),
re_path(MODULE_URL_PREFIX + r'delete_points_goal_form/$',
views.StudentModuleGoalFormView.as_view(),
name="delete_points_goal_form_view"),

re_path(EDIT_URL_PREFIX + r'analytics/$',
staff_views.AnalyticsView.as_view(),
Expand Down
13 changes: 13 additions & 0 deletions exercise/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> JsonResponse:
user_id = request.user.id
module_slug = self.kwargs['module_slug']
points_goal = request.POST.get('personalized_points_goal_input')
delete = request.POST.get('delete')

if delete:
student = UserProfile.objects.get(id=user_id)
module = CourseModule.objects.get(url=module_slug)
try:
StudentModuleGoal.objects.get(student=user_id, module=module.id).delete()
cached_points = CachedPoints(module.course_instance, student, True)
cached_module, _, _, _ = cached_points.find(module)
cached_points.invalidate(module.course_instance, student)
return JsonResponse({"success": "deleted"}, status=200)
except Exception as e:
return JsonResponse({"error": e}, status=404)

if not points_goal.replace('%', '').isdigit() and not points_goal.isdigit():
return JsonResponse({"error": "not_a_number"}, status=400)
Expand Down
29 changes: 18 additions & 11 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -1259,33 +1259,40 @@ msgstr "Points goal"

#: exercise/templates/exercise/_user_results.html
msgid "POINTS_GOAL_TOOLTIP"
msgstr "Set a personal points goal for this module. This goal is only visible to you. Once the goal has been reached, the points progress bar changes color to blue."
msgstr "Set a personal points goal for this module. This goal is only visible to you. Once the goal has been reached, the points progress bar changes colour to blue."

#: exercise/templates/exercise/save_personalized_points_goal.html
#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_TITLE"
msgstr "Set personalized points goal for module"

#: exercise/templates/exercise/save_personalized_points_goal.html
#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "LABEL_POINTS_GOAL_INPUT"
msgstr "Input personalized goal as percentage or points (e.g., 50% or 150)"
msgstr "Input personalized goal as a percentage or points (e.g., 50% or 150)"

#: exercise/templates/exercise/save_personalized_points_goal.html
msgid "REQUIRED_POINTS"
msgstr "Points required to pass for module"

#: exercise/templates/exercise/save_personalized_points_goal.html
#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_SUCCESS"
msgstr "Succesfully set personalized points goal"

#: exercise/templates/exercise/save_personalized_points_goal.html
#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_FAILURE"
msgstr "Failed to set personalized points goal"

#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_NOT_NUMBER"
msgstr "Input needs to be a percentage or a number (e.g., 50% or 150)"

msgid "PERSONALIZED_POINTS_GOAL"
msgstr "Points goal"

msgid "PERSONALIZED_POINTS_MODAL_LESS_THAN_REQUIRED"
msgstr "You cannot set the personalized points goal to be less than the points required to pass"
msgstr "You cannot set the personalized points goal to be less than the points required to pass the module"

msgid "PERSONALIZED_POINTS_MODAL_REMOVE_SUCCESS"
msgstr "Succesfully removed personalized points goal"

msgid "PERSONALIZED_POINTS_MODAL_REMOVE_FAILURE"
msgstr "Failed to remove personalized points goal"


#: course/templates/course/staff/_tag_remove_modal.html
msgid "UNTAG_MULTIPLE_USERS"
Expand Down
19 changes: 12 additions & 7 deletions locale/fi/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -763,11 +763,6 @@ msgstr "Aseta pistetavoite moduulille"
msgid "LABEL_POINTS_GOAL_INPUT"
msgstr "Anna pistetavoite prosentteina tai pisteinä (esim. 50% tai 150)"

#: exercise/templates/exercise/personalized_points_goal_modal.html
#: exercise/templates/exercise/_user_results.html
msgid "REQUIRED_POINTS"
msgstr "Vaaditut pisteet"

#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_SUCCESS"
msgstr "Pistetavoite asetettu onnistuneesti"
Expand All @@ -776,11 +771,21 @@ msgstr "Pistetavoite asetettu onnistuneesti"
msgid "PERSONALIZED_POINTS_MODAL_FAILURE"
msgstr "Pistetavoitteen asettaminen epäonnistui"

#: exercise/templates/exercise/personalized_points_goal_modal.html
msgid "PERSONALIZED_POINTS_MODAL_NOT_NUMBER"
msgstr "Pistetavoite tulee antaa joko prosentteina tai pisteinä (esim. 50% or 150)"

msgid "PERSONALIZED_POINTS_GOAL"
msgstr "Pistetavoite"

msgid "PERSONALIZED_POINTS_MODAL_LESS_THAN_REQUIRED"
msgstr "Pistetavoite ei voi olla vähemmän kuin läpipääsyyn vaaditut pisteet"
msgstr "Pistetavoite ei voi olla vähemmän kuin moduulin läpipääsyyn vaaditut pisteet"

msgid "PERSONALIZED_POINTS_MODAL_REMOVE_SUCCESS"
msgstr "Pistetavoite poistettu onnistuneesti"

msgid "PERSONALIZED_POINTS_MODAL_REMOVE_FAILURE"
msgstr "Pistetavoitteen poistaminen epäonnistui"

#: course/models.py
msgid "LABEL_MODEL_ANSWER"
Expand Down Expand Up @@ -4478,7 +4483,7 @@ msgstr "Aloita uudelleenarviointi"

#: exercise/templates/exercise/staff/_resubmit_modal.html
msgid "RE-SUBMIT_TO_SERVICE"
msgstr "Lähetä arvosteltavaksi uudelleen"#: exercise/templates/exercise/_user_results.html
msgstr "Lähetä arvosteltavaksi uudelleen"

#: exercise/templates/exercise/staff/_resubmit_modal.html
msgid "RE-SUBMIT_TO_SERVICE_DESCRIPTION"
Expand Down

0 comments on commit b93cbd1

Please sign in to comment.