[UPDT] PMS: Updated pms ffeedback creation form

This commit is contained in:
Horilla
2025-03-14 16:15:11 +05:30
parent 31aa1087ee
commit 0dca71f5af
3 changed files with 124 additions and 167 deletions

View File

@@ -18,7 +18,7 @@ from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from base.forms import ModelForm as BaseForm from base.forms import ModelForm as BaseForm
from base.forms import ModelForm as MF from base.forms import ModelForm as HorillaModelForm
from base.methods import ( from base.methods import (
filtersubordinatesemployeemodel, filtersubordinatesemployeemodel,
is_reportingmanager, is_reportingmanager,
@@ -447,10 +447,7 @@ class EmployeeKeyResultForm(BaseForm):
) )
from base.forms import ModelForm as MF class KRForm(HorillaModelForm):
class KRForm(MF):
""" """
A form used for creating KeyResult object A form used for creating KeyResult object
""" """
@@ -661,28 +658,20 @@ class KeyResultForm(ModelForm):
return cleaned_data return cleaned_data
class FeedbackForm(ModelForm): class FeedbackForm(HorillaModelForm):
""" """
A form used for creating and updating Feedback objects. FeedbackForm for better performance.
""" """
period = forms.ModelChoiceField( period = forms.ModelChoiceField(
queryset=Period.objects.all(), queryset=Period.objects.none(),
label=_("Period"),
empty_label="", empty_label="",
widget=forms.Select( widget=forms.Select(attrs={"class": "oh-select--period-change"}),
attrs={
"class": " oh-select--period-change ",
"style": "width:100%;",
}
),
required=False, required=False,
) )
class Meta: class Meta:
"""
A nested class that specifies the model,fields and exclude fields for the form.
"""
model = Feedback model = Feedback
fields = "__all__" fields = "__all__"
exclude = ["status", "archive", "is_active"] exclude = ["status", "archive", "is_active"]
@@ -692,45 +681,10 @@ class FeedbackForm(ModelForm):
attrs={"placeholder": _("Enter a title"), "class": "oh-input w-100"} attrs={"placeholder": _("Enter a title"), "class": "oh-input w-100"}
), ),
"start_date": forms.DateInput( "start_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"} attrs={"type": "date", "class": "oh-input w-100"}
), ),
"end_date": forms.DateInput( "end_date": forms.DateInput(
attrs={"type": "date", "class": "oh-input w-100"} attrs={"type": "date", "class": "oh-input w-100"}
),
"employee_id": forms.Select(
attrs={
"class": "oh-select oh-select-2",
"required": "false",
},
),
"manager_id": forms.Select(
attrs={
"class": "oh-select oh-select-2 ",
"style": "width:100%;",
"required": "true",
},
),
"colleague_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%;",
}
),
"subordinate_id": forms.SelectMultiple(
attrs={
"class": "oh-select oh-select-2 w-100",
"multiple": "multiple",
"style": "width:100%;",
"required": "false",
}
),
"question_template_id": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search",
"style": "width:100%;",
"required": "true",
}
), ),
"cyclic_feedback": forms.CheckboxInput( "cyclic_feedback": forms.CheckboxInput(
attrs={ attrs={
@@ -738,41 +692,41 @@ class FeedbackForm(ModelForm):
"onchange": "changeCyclicFeedback(this)", "onchange": "changeCyclicFeedback(this)",
} }
), ),
"cyclic_feedback_period": forms.Select(
attrs={
"class": "oh-select oh-select--lg oh-select-no-search",
"style": "width:100%;",
}
),
"cyclic_feedback_days_count": forms.NumberInput(
attrs={
"class": "oh-input",
}
),
} }
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
Initializes the feedback form instance. Initializes the form and queryset filtering.
If an instance is provided, sets the initial value for the form's date fields.
""" """
# fetch request
request = getattr(horilla_middlewares._thread_locals, "request", None) request = getattr(horilla_middlewares._thread_locals, "request", None)
# get instance
instance = kwargs.get("instance")
# set employee
if instance:
employee = instance.employee_id
else:
employee = request.user.employee_get
if not instance:
today = datetime.datetime.today().date()
kwargs["initial"] = {"start_date": today, "end_date": today}
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Horilla multi select filter for employee user = request.user if request else None
user_perms = user.get_all_permissions() if user else set()
self.fields["period"].queryset = Period.objects.all()
self.fields["period"].widget.attrs.update({"class": "w-100"})
if user and ("pms.add_period" in user_perms or is_reportingmanager(request)):
self.fields["period"].choices = [
*self.fields["period"].choices,
("create_new_period", "Create new period"),
]
employee_queryset = Employee.objects.none()
if user and ("pms.add_feedback" in user_perms or is_reportingmanager(request)):
employee_queryset = filtersubordinatesemployeemodel(
request,
Employee.objects.all(),
perm="pms.add_feedback",
)
self.fields["employee_id"].queryset = (
employee_queryset | Employee.objects.filter(employee_user_id=request.user)
)
self.fields["employee_id"].widget.attrs["onchange"] = "get_collegues($(this))"
# Horilla multi-select filter for subordinates
self.fields["subordinate_id"] = HorillaMultiSelectField( self.fields["subordinate_id"] = HorillaMultiSelectField(
queryset=Employee.objects.all(), queryset=Employee.objects.all(),
widget=HorillaMultiSelectWidget( widget=HorillaMultiSelectWidget(
@@ -783,32 +737,10 @@ class FeedbackForm(ModelForm):
instance=self.instance, instance=self.instance,
required=False, required=False,
), ),
label="Subordinates", label=_("Subordinates"),
) )
reload_queryset(self.fields)
# check the request user has permission to add period reload_queryset(self.fields)
if request.user.has_perm("pms.add_period") or is_reportingmanager(request):
# add dyanamic period creation as choice
self.fields["period"].choices = list(self.fields["period"].choices)
self.fields["period"].choices.append(
("create_new_period", "Create new period")
)
# add onchange function to get employee data
self.fields["employee_id"].widget.attrs.update(
{"onchange": "get_collegues($(this))"}
)
# filtering employees accordig to the request user
if request.user.has_perm("pms.add_feedback") or is_reportingmanager(request):
# Queryset of subordinate employees
employees = filtersubordinatesemployeemodel(
request, Employee.objects.all(), perm="pms.add_feedback"
)
self.fields["employee_id"].queryset = employees | Employee.objects.filter(
employee_user_id=request.user
)
if not instance:
self.fields["employee_id"].initial = employee
def clean(self): def clean(self):
""" """
@@ -1119,7 +1051,7 @@ class MeetingsForm(BaseForm):
pass pass
class BonusPointSettingForm(MF): class BonusPointSettingForm(HorillaModelForm):
""" """
BonusPointSetting form BonusPointSetting form
""" """
@@ -1165,7 +1097,7 @@ class BonusPointSettingForm(MF):
return cleaned_data return cleaned_data
class EmployeeBonusPointForm(MF): class EmployeeBonusPointForm(HorillaModelForm):
""" """
EmployeeBonusPoint form EmployeeBonusPoint form
""" """

View File

@@ -497,13 +497,16 @@ class Feedback(HorillaModel):
("months", _("Months")), ("months", _("Months")),
("years", _("Years")), ("years", _("Years")),
) )
review_cycle = models.CharField(max_length=100, null=False, blank=False) review_cycle = models.CharField(
max_length=100, null=False, blank=False, verbose_name=_("Title")
)
manager_id = models.ForeignKey( manager_id = models.ForeignKey(
Employee, Employee,
related_name="feedback_manager", related_name="feedback_manager",
on_delete=models.DO_NOTHING, on_delete=models.DO_NOTHING,
null=True, null=True,
blank=False, blank=False,
verbose_name=_("Manager"),
) )
employee_id = models.ForeignKey( employee_id = models.ForeignKey(
Employee, Employee,
@@ -511,12 +514,19 @@ class Feedback(HorillaModel):
related_name="feedback_employee", related_name="feedback_employee",
null=False, null=False,
blank=False, blank=False,
verbose_name=_("Employee"),
) )
colleague_id = models.ManyToManyField( colleague_id = models.ManyToManyField(
Employee, related_name="feedback_colleague", blank=True Employee,
related_name="feedback_colleague",
blank=True,
verbose_name=_("Colleague"),
) )
subordinate_id = models.ManyToManyField( subordinate_id = models.ManyToManyField(
Employee, related_name="feedback_subordinate", blank=True Employee,
related_name="feedback_subordinate",
blank=True,
verbose_name=_("Subordinates"),
) )
question_template_id = models.ForeignKey( question_template_id = models.ForeignKey(
QuestionTemplate, QuestionTemplate,
@@ -524,19 +534,23 @@ class Feedback(HorillaModel):
related_name="feedback_question_template", related_name="feedback_question_template",
null=False, null=False,
blank=False, blank=False,
verbose_name=_("Question Template"),
) )
status = models.CharField( status = models.CharField(
max_length=50, choices=STATUS_CHOICES, default="Not Started" max_length=50, choices=STATUS_CHOICES, default="Not Started"
) )
archive = models.BooleanField(null=True, blank=True, default=False) archive = models.BooleanField(null=True, blank=True, default=False)
start_date = models.DateField(null=False, blank=False) start_date = models.DateField(null=False, blank=False, verbose_name=_("Start Date"))
end_date = models.DateField(null=True, blank=False) end_date = models.DateField(null=True, blank=False, verbose_name=_("End Date"))
employee_key_results_id = models.ManyToManyField( employee_key_results_id = models.ManyToManyField(
EmployeeKeyResult, EmployeeKeyResult, blank=True, verbose_name=_("Key Result")
blank=True, )
cyclic_feedback = models.BooleanField(
default=False, verbose_name=_("Is Cyclic Feedback")
)
cyclic_feedback_days_count = models.IntegerField(
blank=True, null=True, verbose_name=_("Cycle Period")
) )
cyclic_feedback = models.BooleanField(default=False)
cyclic_feedback_days_count = models.IntegerField(blank=True, null=True)
cyclic_feedback_period = models.CharField( cyclic_feedback_period = models.CharField(
max_length=50, choices=PERIOD, blank=True, null=True max_length=50, choices=PERIOD, blank=True, null=True
) )
@@ -547,6 +561,8 @@ class Feedback(HorillaModel):
class Meta: class Meta:
ordering = ["-id"] ordering = ["-id"]
verbose_name = _("Feedback")
verbose_name_plural = _("Feedbacks")
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
start_date = self.start_date start_date = self.start_date

View File

@@ -9,32 +9,29 @@
{% block content %} {% block content %}
{% if feedback_form.errors %} {% if feedback_form.errors %}
<!-- form errors --> <div class="oh-wrapper">
<div class="oh-wrapper"> <div class="oh-alert-container">
<div class="oh-alert-container"> {% for error in feedback_form.non_field_errors %}
<div class="oh-alert oh-alert--animated oh-alert--danger">
{% for error in feedback_form.non_field_errors %} {{ error }}
<div class="oh-alert oh-alert--animated oh-alert--danger"> </div>
{{ error }} {% endfor %}
</div> </div>
{% endfor %}
</div> </div>
</div>
{% endif %} {% endif %}
<div class="oh-wrapper" id="message"> <div class="oh-wrapper" id="message"></div>
</div>
<!-- Feedback form'--> <!-- Feedback form'-->
<main class="oh-onboarding"> <main class="oh-onboarding">
<div class="oh-onboarding-card oh-profile-section" style="max-width: 868px;"> <div class="oh-onboarding-card oh-profile-section" style="max-width: 868px;">
<form action="{%url 'feedback-creation' %}" id="feedbackCreationForm" method="post"> <form action="{%url 'feedback-creation' %}" id="feedbackCreationForm" method="post">
{{feedback_form.non_field_errors}} {{feedback_form.non_field_errors}}
{% csrf_token %} {% csrf_token %}
<div class="oh-onboarding-card__address-group"> <div class="oh-onboarding-card__address-group">
<h2 class="oh-onboarding-card__section-title">{% trans "Feedback" %}</h2> <h2 class="oh-onboarding-card__section-title">{{feedback_form.verbose_name}}</h2>
<div class="oh-input__group "> <div class="oh-input__group ">
<label class="oh-input__label" for="{{feedback_form.review_cycle.id_for_label}}">{% trans "Title" %}</label> <label class="oh-input__label"
for="{{feedback_form.review_cycle.id_for_label}}">{{feedback_form.review_cycle.label}}</label>
{{feedback_form.review_cycle}} {{feedback_form.review_cycle}}
{{feedback_form.review_cycle.errors}} {{feedback_form.review_cycle.errors}}
</div> </div>
@@ -42,7 +39,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.employee_id.id_for_label}}">{% trans "Employee" %}</label> <label class="oh-input__label"
for="{{feedback_form.employee_id.id_for_label}}">{{feedback_form.employee_id.label}}</label>
{{feedback_form.employee_id }} {{feedback_form.employee_id }}
{{feedback_form.employee_id.errors }} {{feedback_form.employee_id.errors }}
<ul id="error-list" class="errorlist" style="display: none"> <ul id="error-list" class="errorlist" style="display: none">
@@ -54,7 +52,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.manager_id.id_for_label}}">{% trans "Manager" %}</label> <label class="oh-input__label"
for="{{feedback_form.manager_id.id_for_label}}">{{feedback_form.manager_id.label}}</label>
{{feedback_form.manager_id}} {{feedback_form.manager_id}}
{{feedback_form.manager_id.errros}} {{feedback_form.manager_id.errros}}
<ul id="error-list" class="errorlist" style="display: none"> <ul id="error-list" class="errorlist" style="display: none">
@@ -68,7 +67,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.subordinate_id.id_for_label}}">{% trans "Subordinates" %}</label> <label class="oh-input__label"
for="{{feedback_form.subordinate_id.id_for_label}}">{{feedback_form.subordinate_id.label}}</label>
{{feedback_form.subordinate_id}} {{feedback_form.subordinate_id}}
{{feedback_form.subordinate_id.errors}} {{feedback_form.subordinate_id.errors}}
</div> </div>
@@ -77,7 +77,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.colleague_id.id_for_label}}">{% trans "Colleague" %}</label> <label class="oh-input__label"
for="{{feedback_form.colleague_id.id_for_label}}">{{feedback_form.colleague_id.label}}</label>
{{feedback_form.colleague_id}} {{feedback_form.colleague_id}}
{{feedback_form.colleague_id.errors}} {{feedback_form.colleague_id.errors}}
</div> </div>
@@ -88,7 +89,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4"> <div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.period.id_for_label}}">{% trans "Period" %}</label> <label class="oh-input__label"
for="{{feedback_form.period.id_for_label}}">{{feedback_form.period.label}}</label>
{{feedback_form.period}} {{feedback_form.period}}
{{feedback_form.period.errors}} {{feedback_form.period.errors}}
</div> </div>
@@ -97,7 +99,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4"> <div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.start_date.id_for_label}}">{% trans "Start Date" %}</label> <label class="oh-input__label"
for="{{feedback_form.start_date.id_for_label}}">{{feedback_form.start_date.label}}</label>
{{feedback_form.start_date}} {{feedback_form.start_date}}
{{feedback_form.start_date.errors}} {{feedback_form.start_date.errors}}
</div> </div>
@@ -106,7 +109,8 @@
<div class="col-12 col-sm-12 col-md-6 col-lg-4"> <div class="col-12 col-sm-12 col-md-6 col-lg-4">
<div class="oh-input__group"> <div class="oh-input__group">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.end_date.id_for_label}}">{% trans "End Date" %}</label> <label class="oh-input__label"
for="{{feedback_form.end_date.id_for_label}}">{{feedback_form.end_date.label}}</label>
{{feedback_form.end_date}} {{feedback_form.end_date}}
{{feedback_form.end_date.errors}} {{feedback_form.end_date.errors}}
</div> </div>
@@ -116,7 +120,8 @@
<div class="row"> <div class="row">
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.question_template_id.id_for_label}}">{% trans "Question Template" %}</label> <label class="oh-input__label"
for="{{feedback_form.question_template_id.id_for_label}}">{{feedback_form.question_template_id.label}}</label>
{{feedback_form.question_template_id}} {{feedback_form.question_template_id}}
{{feedback_form.question_template_id.errors}} {{feedback_form.question_template_id.errors}}
<ul id="error-list" class="errorlist" style="display: none"> <ul id="error-list" class="errorlist" style="display: none">
@@ -126,26 +131,27 @@
</div> </div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6"> <div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="id_employee_key_results_id">{% trans "Key Result" %}</label> <label class="oh-input__label"
<select name="employee_key_results_id" id="id_employee_key_results_id" class="oh-select oh-select--lg oh-select-no-search w-100 oh-select-2--large" multiple="multiple" style="display: none;"> for="id_employee_key_results_id">{{feedback_form.employee_key_results_id.label}}</label>
<option value="">------------------</option> {{feedback_form.employee_key_results_id}}
</select> {{feedback_form.employee_key_results_id.errors}}
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 col-sm-12 col-md-6 col-lg-6 mb-5" id=""> <div class="col-12 col-sm-12 col-md-6 col-lg-6 mb-5" id="">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label" for="{{feedback_form.cyclic_feedback.id_for_label}}">{% trans "Is Cyclic Feedback" %}</label> <label class="oh-input__label"
for="{{feedback_form.cyclic_feedback.id_for_label}}">{{feedback_form.cyclic_feedback.label}}</label>
<div class="oh-switch"> <div class="oh-switch">
{{feedback_form.cyclic_feedback}} {{feedback_form.cyclic_feedback}}
</div> </div>
{{feedback_form.cyclic_feedback.errors}} {{feedback_form.cyclic_feedback.errors}}
</div> </div>
</div> </div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6" style="display:none" id="cyclic_feedback_period"> <div class="col-12 col-sm-12 col-md-6 col-lg-6" style="display:none" id="cyclic_feedback_period">
<div class="oh-input__group"> <div class="oh-input__group">
<label class="oh-input__label">{% trans "Cycle Period" %}</label> <label class="oh-input__label" for="{{feedback_form.cyclic_feedback_days_count.id_for_label}}">{{feedback_form.cyclic_feedback_days_count.label}}</label>
<div class="w-100 d-flex"> <div class="w-100 d-flex">
{{feedback_form.cyclic_feedback_days_count}} {{feedback_form.cyclic_feedback_days_count}}
{{feedback_form.cyclic_feedback_period}} {{feedback_form.cyclic_feedback_period}}
@@ -157,10 +163,7 @@
</section> </section>
<div class="w-100 d-flex align-items-center justify-content-end"> <div class="w-100 d-flex align-items-center justify-content-end">
<button <button type="submit" class="oh-btn oh-btn--secondary oh-btn--w-100-resp">
type="submit"
class="oh-btn oh-btn--secondary oh-btn--w-100-resp"
>
{% trans "Save" %} {% trans "Save" %}
</button> </button>
</div> </div>
@@ -171,28 +174,36 @@
<!-- period modal --> <!-- period modal -->
<div class="oh-modal" id="PeriodModal" role="dialog" aria-labelledby="editKeyResultModal" aria-hidden="true"> <div class="oh-modal" id="PeriodModal" role="dialog" aria-labelledby="editKeyResultModal" aria-hidden="true">
<div class="oh-modal__dialog"> <div class="oh-modal__dialog">
<!-- for creating period --> <!-- for creating period -->
<div class="oh-modal__dialog-header"> <div class="oh-modal__dialog-header">
<button type="button" class="oh-modal__close" aria-label="Close"> <button type="button" class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon> <ion-icon name="close-outline"></ion-icon>
</button> </button>
</div> </div>
<div class="oh-modal__dialog-body" id="periodModalTarget"> <div class="oh-modal__dialog-body" id="periodModalTarget">
</div> </div>
</div> </div>
</div> </div>
<!-- end of period modal --> <!-- end of period modal -->
</main> </main>
<button id="colleguesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_colleague_id" hidden > </button> <button id="colleguesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_colleague_id" hidden> </button>
<button id="managerButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_manager_id" hidden > </button> <button id="managerButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_manager_id" hidden> </button>
<button id="subordinatesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_subordinate_id" hidden > </button> <button id="subordinatesButton" hx-get="{% url 'get-collegues' %}" hx-target="#id_subordinate_id" hidden> </button>
<button id="keyresultButtton" hx-get="{% url 'get-collegues' %}" hx-target="#id_employee_key_results_id" hidden > </button> <button id="keyresultButtton" hx-get="{% url 'get-collegues' %}" hx-target="#id_employee_key_results_id" hidden></button>
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
get_collegues($('#id_employee_id')) get_collegues($('#id_employee_id'));
$('#id_colleague_id').on('click', function() {
console.log('Colleague field clicked');
});
$('#id_subordinate_id').on('click', function() {
console.log('Subordinate field clicked');
});
}); });
function get_collegues(element) { function get_collegues(element) {
var employee_id = $(element).val(); var employee_id = $(element).val();
@@ -214,6 +225,4 @@
</script> </script>
<script src="{% static 'src/feedback/feedback_creation.js' %}"></script> <script src="{% static 'src/feedback/feedback_creation.js' %}"></script>
<script src="{% static 'src/period/period.js' %}"></script> <script src="{% static 'src/period/period.js' %}"></script>
{% endblock%} {% endblock%}