mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-10-06 12:35:28 +00:00
Bootstrap 5 & remove jQuery (#661)
* build: move frontend assets to Bootstrap 5.3 and Tom Select * feat: migrate templates and scripts to Bootstrap 5, dropping jQuery Templates - Rename Bootstrap 4 classes and data attributes (data-bs-*, ms-/me-/ps-/pe-, text-start/end, form-group -> mb-3, input-group wrappers removed, badges, custom controls -> form-check/form-select, media -> d-flex, btn-close, ...) - Dark mode now uses Bootstrap 5.3 colour modes (data-bs-theme on <html>), set from <head> to avoid a flash of the light theme - Remove the Bootstrap 4 /bootstrap/ demo page - Contextual table classes (table-success etc.) still work as plain backgrounds for the rigboard key JavaScript - Remove jQuery: src.js/interaction.js and every inline template script are rewritten in plain JS on top of small helpers (helpers.js, bundled with Bootstrap into jpop.js so inline scripts can use them) - Replace bootstrap-select/ajax-bootstrap-select with Tom Select. The remote search now sends the `q` parameter and reads `text`, which is what the API actually uses (the old picker sent `term` and read `label`) - HTML fragments are fetched with an X-Requested-With header so views keep rendering their modal variants, and fetched scripts are re-executed - Remove the Bootstrap 4 plugin script includes * fix: stop rigboard header buttons stretching to full width under Bootstrap 5 * fix: restore dark-mode brand colours and contextual table colours under Bootstrap 5 * fix: brighten dark-mode links and make coloured card outlines visible * fix: calendar layout and grid borders, navbar search button width, guard missing modal links * fix: readable text in dark-mode Tom Select inputs and placeholders, restore form-control column widths * build: split the Dockerfile into cached stages with prod and dev targets * deploy: make compose.yml development-only with live reload, and document it * fix: keep badge text colour for links inside badges * fix: restore table-bordered grid lines in dark mode * fix: include Bootstrap's progress styles and keep progress labels readable
This commit is contained in:
@@ -361,7 +361,7 @@ class TrainingLevel(models.Model, RevisionMixin):
|
||||
else:
|
||||
icon = "".join([w[0] for w in str(self).split()])
|
||||
return mark_safe(
|
||||
f"<span class='badge badge-{self.department_colour} badge-pill' data-toggle='tooltip' title='{str(self)}'>{icon}</span>"
|
||||
f"<span class='badge text-bg-{self.department_colour} rounded-pill' data-bs-toggle='tooltip' title='{str(self)}'>{icon}</span>"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -15,25 +15,16 @@
|
||||
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if form.errors %}
|
||||
{% include 'form_errors.html' %}
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script>
|
||||
//Has to be done here or the pickers disappear on modal error
|
||||
$('document').ready(function(){
|
||||
$(document).find(".selectpicker").selectpicker().each(function(){initPicker($(this))});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
<form id="requirement-form" action="{{ form.action|default:request.path }}" method="post">{% csrf_token %}
|
||||
{% render_field form.level|attr:'hidden' value=form.level.initial %}
|
||||
{% include 'partials/item_field.html' %}
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
<label for="depth" class="col-sm-2 col-form-label">Depth</label>
|
||||
{% render_field form.depth|add_class:'form-control col-sm'|attr:'required' %}
|
||||
</div>
|
||||
@@ -44,7 +35,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<div class="col-sm-12 text-right pr-0">
|
||||
<div class="col-sm-12 text-end pe-0">
|
||||
<button type="submit" class="btn btn-primary" title="Save" form="requirement-form"><span class="fas fa-save align-middle"></span> <span class="d-none d-sm-inline align-middle">Save</span></button>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle text-info" href="#" id="navbarDropdownMy" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<a class="nav-link dropdown-toggle text-info" href="#" id="navbarDropdownMy" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
My Record
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMy">
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownLists" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownLists" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Lists
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownLists">
|
||||
|
||||
@@ -13,30 +13,22 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script>
|
||||
//Has to be done here or the pickers disappear on modal error
|
||||
$('document').ready(function(){
|
||||
$(document).find(".selectpicker").selectpicker().each(function(){initPicker($(this))});
|
||||
});
|
||||
</script>
|
||||
<form role="form" action="{{ form.action|default:request.path }}" method="POST" id="add_record_form">
|
||||
{% include 'form_errors.html' %}
|
||||
{% csrf_token %}
|
||||
{% render_field form.trainee|attr:'hidden' value=form.trainee.initial %}
|
||||
{% include 'partials/item_field.html' %}
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
<label for="depth" class="col-sm-2 col-form-label">Depth</label>
|
||||
{% render_field form.depth|add_class:'form-control custom-select col-sm-8' %}
|
||||
{% render_field form.depth|add_class:'form-control form-select col-sm-8' %}
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
{% include 'partials/supervisor_field.html' %}
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
<label for="date" class="col-sm-2 col-form-label">Training Date</label>
|
||||
<div class="col-sm-8">
|
||||
{% with training_date=object.date|date:"Y-m-d" %}
|
||||
@@ -45,14 +37,14 @@
|
||||
</div>
|
||||
{% button 'today' id='id_date' %}
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
<label for="id_notes" class="col-sm-2 col-form-label">Notes</label>
|
||||
<div class="col-sm-8">
|
||||
{% render_field form.notes|add_class:'form-control' rows=3 %}
|
||||
</div>
|
||||
</div>
|
||||
{% if not is_ajax %}
|
||||
<div class="col-sm-12 text-right pr-0">
|
||||
<div class="col-sm-12 text-end pe-0">
|
||||
{% button 'submit' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -60,7 +52,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<div class="col-sm-12 text-right pr-0">
|
||||
<div class="col-sm-12 text-end pe-0">
|
||||
<button type="submit" class="btn btn-primary" title="Save" form="add_record_form"><span class="fas fa-save align-middle"></span> <span class="d-none d-sm-inline align-middle">Save</span></button>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,25 +3,25 @@
|
||||
{% load button from filters %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-12 text-right py-2 pr-0">
|
||||
<div class="col-12 text-end py-2 pe-0">
|
||||
{% button 'print' 'item_list_export' %}
|
||||
</div>
|
||||
<div id="accordion">
|
||||
{% for category in categories %}
|
||||
<div class="card">
|
||||
<div class="card-header" id="heading{{forloop.counter}}">
|
||||
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse{{forloop.counter}}" aria-expanded="true" aria-controls="collapse{{forloop.counter}}">
|
||||
<button class="btn btn-link collapsed" data-bs-toggle="collapse" data-bs-target="#collapse{{forloop.counter}}" aria-expanded="true" aria-controls="collapse{{forloop.counter}}">
|
||||
{{ category }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="collapse{{forloop.counter}}" class="collapse" aria-labelledby="heading{{forloop.counter}}" data-parent="#accordion">
|
||||
<div id="collapse{{forloop.counter}}" class="collapse" aria-labelledby="heading{{forloop.counter}}" data-bs-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<div class="list-group list-group-flush">
|
||||
{% for item in category.items.all %}
|
||||
<li class="list-group-item {% if not item.active%}text-warning{%endif%}">{{ item }} <a href="{% url 'item_qualification' item.pk %}" class="btn btn-info float-right"><span class="fas fa-user"></span> Qualified Users</a>
|
||||
<li class="list-group-item {% if not item.active%}text-warning{%endif%}">{{ item }} <a href="{% url 'item_qualification' item.pk %}" class="btn btn-info float-end"><span class="fas fa-user"></span> Qualified Users</a>
|
||||
<br><small>{{ item.description }}</small>
|
||||
{% if item.prerequisites.exists %}
|
||||
<div class="ml-3 font-italic">
|
||||
<div class="ms-3 fst-italic">
|
||||
<p class="text-info mb-0">Competency Assessment Prerequisites:</p>
|
||||
<ul>
|
||||
{% for p in item.prerequisites.all %}
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
{% load static %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static "js/tooltip.js" %}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -16,28 +16,15 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
<script>
|
||||
$('document').ready(function(){
|
||||
$('#requirement_button').click(function (e) {
|
||||
e.preventDefault();
|
||||
var url = $(this).attr("href");
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(){
|
||||
$link = $(this);
|
||||
// Anti modal inception
|
||||
if ($link.parents('#modal').length === 0) {
|
||||
modaltarget = $link.data('target');
|
||||
modalobject = "";
|
||||
$('#modal').load(url, function (e) {
|
||||
$('#modal').modal();
|
||||
$(".selectpicker").selectpicker().each(function(){initPicker($(this))});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
ready(function(){
|
||||
var link = document.getElementById('requirement_button');
|
||||
if (!link) { return; }
|
||||
link.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
modaltarget = undefined;
|
||||
modalobject = "";
|
||||
loadModal(this.getAttribute("href"));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -45,7 +32,7 @@
|
||||
|
||||
{% block content %}
|
||||
{% if request.user.is_supervisor %}
|
||||
<div class="col-sm-12 text-right pr-0">
|
||||
<div class="col-sm-12 text-end pe-0">
|
||||
<a type="button" class="btn btn-success mb-3" href="{% url 'add_requirement' pk=object.pk %}" id="requirement_button">
|
||||
<span class="fas fa-plus"></span> Add New Requirement
|
||||
</a>
|
||||
@@ -58,7 +45,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><h4 class="card-title">Level Requirements</h4> {% if u.pk != request.user.pk %}<h5 class="card-subtitle font-italic">for {{ u }}</h5>{% endif %}</div>
|
||||
<div class="card-header"><h4 class="card-title">Level Requirements</h4> {% if u.pk != request.user.pk %}<h5 class="card-subtitle fst-italic">for {{ u }}</h5>{% endif %}</div>
|
||||
<div class="table-responsive card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
@@ -70,7 +57,7 @@
|
||||
</thead>
|
||||
<tbody class="table-body">
|
||||
{% for level in object.prerequisite_levels.all %}
|
||||
<tr data-toggle="collapse" data-target="#{{level.pk}}" style="cursor: pointer;"><th colspan="3" class="text-center font-italic" data-toggle="collapse" data-target="#level_{{level.pk}}">{{level}} (prerequisite)</th></tr>
|
||||
<tr data-bs-toggle="collapse" data-bs-target="#{{level.pk}}" style="cursor: pointer;"><th colspan="3" class="text-center fst-italic" data-bs-toggle="collapse" data-bs-target="#level_{{level.pk}}">{{level}} (prerequisite)</th></tr>
|
||||
<tr id="level_{{level.pk}}" class="collapse">
|
||||
<td><ul class="list-unstyled">{% for req in level.started_requirements %}<li>{{ req.item }} {% user_has_qualification u req.item 0 %}</li>{% endfor %}</ul></td>
|
||||
<td><ul class="list-unstyled">{% for req in level.complete_requirements %}<li>{{ req.item }} {% user_has_qualification u req.item 1 %}</li>{% endfor %}</ul></td>
|
||||
@@ -135,7 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
<div class="col text-end">
|
||||
{% include 'partials/last_edited.html' with target="traininglevel_history" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="form-group form-row">
|
||||
<div class="mb-3 row g-2">
|
||||
<label for="item_id" class="col col-form-label">Item</label>
|
||||
<select name="item" id="item_id" class="selectpicker col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" required>
|
||||
<select name="item" id="item_id" class="ts-select col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" required>
|
||||
{% if item %}
|
||||
<option value="{{form.item.value}}" selected>{{item}}</option>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<label for="supervisor" class="col-sm-2 col-form-label">Supervisor</label>
|
||||
<select name="supervisor" id="supervisor_id" class="selectpicker col-sm-10" data-live-search="true"
|
||||
<select name="supervisor" id="supervisor_id" class="ts-select col-sm-10" data-live-search="true"
|
||||
data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required
|
||||
data-noclear="true">
|
||||
{% if supervisor %}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script src="{% static 'js/interaction.js' %}"></script>
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@@ -28,31 +26,31 @@
|
||||
{% include 'form_errors.html' %}
|
||||
{% csrf_token %}
|
||||
<h3>People</h3>
|
||||
<div class="form-group row" id="supervisor_group">
|
||||
<div class="mb-3 row" id="supervisor_group">
|
||||
{% include 'partials/supervisor_field.html' %}
|
||||
</div>
|
||||
<div class="form-group row" id="trainees_group">
|
||||
<div class="mb-3 row" id="trainees_group">
|
||||
<label for="trainees_id" class="col-sm-2">Select Attendees</label>
|
||||
<select multiple name="trainees" id="trainees_id" class="selectpicker col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" data-noclear="true">
|
||||
<select multiple name="trainees" id="trainees_id" class="ts-select col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" data-noclear="true">
|
||||
</select>
|
||||
</div>
|
||||
<h3>Training Items</h3>
|
||||
{% for depth in depths %}
|
||||
<div class="form-group row" id="{{depth.0}}">
|
||||
<label for="selectpicker" class="col-sm-2 text-{% colour_from_depth depth.0 %} py-1">{{ depth.1 }} Items</label>
|
||||
<select multiple name="items_{{depth.0}}" id="items_{{depth.0}}_id" class="selectpicker col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" data-noclear="true">
|
||||
<div class="mb-3 row" id="{{depth.0}}">
|
||||
<label for="ts-select" class="col-sm-2 text-{% colour_from_depth depth.0 %} py-1">{{ depth.1 }} Items</label>
|
||||
<select multiple name="items_{{depth.0}}" id="items_{{depth.0}}_id" class="ts-select col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" data-noclear="true">
|
||||
</select>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<h3>Session Information</h3>
|
||||
<div class="form-group row">
|
||||
<div class="mb-3 row">
|
||||
{% include 'partials/form_field.html' with field=form.date col='col-sm-6' %}
|
||||
{% button 'today' id='id_date' %}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="mb-3">
|
||||
{% include 'partials/form_field.html' with field=form.notes %}
|
||||
</div>
|
||||
<div class="col-sm-12 text-right my-3">
|
||||
<div class="col-sm-12 text-end my-3">
|
||||
{% button 'submit' %}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -14,35 +14,23 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
<script>
|
||||
$('document').ready(function(){
|
||||
$('#add_record').click(function (e) {
|
||||
e.preventDefault();
|
||||
var url = $(this).attr("href");
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(){
|
||||
$link = $(this);
|
||||
// Anti modal inception
|
||||
if ($link.parents('#modal').length === 0) {
|
||||
modaltarget = $link.data('target');
|
||||
modalobject = "";
|
||||
$('#modal').load(url, function (e) {
|
||||
$('#modal').modal();
|
||||
//$(".selectpicker").selectpicker().each(function(){initPicker($(this))});
|
||||
});
|
||||
}
|
||||
}
|
||||
ready(function(){
|
||||
var link = document.getElementById('add_record');
|
||||
if (!link) { return; }
|
||||
link.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
modaltarget = undefined;
|
||||
modalobject = "";
|
||||
loadModal(this.getAttribute("href"));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm-12 text-right">
|
||||
<div class="col-sm-12 text-end">
|
||||
<div class="btn-group">
|
||||
{% include 'partials/add_qualification.html' %}
|
||||
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a>
|
||||
@@ -72,16 +60,17 @@
|
||||
{{ level.description|markdown }}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {{completion}}%" aria-valuenow="{{completion}}" aria-valuemin="0" aria-valuemax="100">{{completion}}% complete</div>
|
||||
<div class="progress" style="height: 1.5rem;">
|
||||
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {{completion}}%" aria-valuenow="{{completion}}" aria-valuemin="0" aria-valuemax="100">{% if completion >= 30 %}{{completion}}% complete{% endif %}</div>
|
||||
</div>
|
||||
{% if completion < 30 %}<small class="text-body-secondary">{{completion}}% complete</small>{% endif %}
|
||||
{% if completion == 100 %}
|
||||
<br>
|
||||
{% confirm_button request.user object level as cb %}
|
||||
{% if cb %}
|
||||
<div class="d-flex justify-content-between">{{ cb }}</div>
|
||||
{% else %}
|
||||
<p class="font-italic pt-2 pb-0">Missing prerequisite level(s)</p>
|
||||
<p class="fst-italic pt-2 pb-0">Missing prerequisite level(s)</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -90,7 +79,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
<div class="col text-end">
|
||||
{% include 'partials/last_edited.html' with target="trainee_history" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,33 +16,22 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
<script>
|
||||
$('document').ready(function(){
|
||||
$('#edit').click(function (e) {
|
||||
e.preventDefault();
|
||||
var url = $(this).attr("href");
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(){
|
||||
$link = $(this);
|
||||
// Anti modal inception
|
||||
if ($link.parents('#modal').length === 0) {
|
||||
modaltarget = $link.data('target');
|
||||
modalobject = "";
|
||||
$('#modal').load(url, function (e) {
|
||||
$('#modal').modal();
|
||||
});
|
||||
}
|
||||
}
|
||||
ready(function(){
|
||||
var link = document.getElementById('edit');
|
||||
if (!link) { return; }
|
||||
link.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
modaltarget = undefined;
|
||||
modalobject = "";
|
||||
loadModal(this.getAttribute("href"));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p class="text-muted text-right">Search by supervisor name, item name or item ID</p>{% include 'partials/list_search.html' %}
|
||||
<p class="text-muted text-end">Search by supervisor name, item name or item ID</p>{% include 'partials/list_search.html' %}
|
||||
<div class="row pt-2">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
@@ -82,7 +71,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
<div class="col text-end">
|
||||
{% include 'partials/last_edited.html' with target="trainee_history" object=trainee %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,23 +10,17 @@
|
||||
{% load static %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static "js/tooltip.js" %}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="GET" class="ml-auto w-25 d-flex flex-column justify-content-end">
|
||||
<form method="GET" class="ms-auto w-25 d-flex flex-column justify-content-end">
|
||||
{% csrf_token %}
|
||||
<div class="input-group">
|
||||
<input type="search" name="q" placeholder="Search" value="{{ request.GET.q }}"
|
||||
class="form-control" id="id_search_text"/>
|
||||
<span class="input-group-append">{% button 'search' id="id_search" %}</span>
|
||||
{% button 'search' id="id_search" %}
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2 {% if request.GET.is_supervisor %}active{%endif%}" data-toggle="button" aria-pressed="{% if request.GET.is_supervisor %}true{%endif%}" name="is_supervisor" value="{% if request.GET.is_supervisor %}{% else %}True{% endif %}">
|
||||
<button type="submit" class="btn btn-primary mt-2 {% if request.GET.is_supervisor %}active{%endif%}" data-bs-toggle="button" aria-pressed="{% if request.GET.is_supervisor %}true{%endif%}" name="is_supervisor" value="{% if request.GET.is_supervisor %}{% else %}True{% endif %}">
|
||||
Only Supervisors
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<p>Are you sure you wish to delete {{ page_title }}</p>
|
||||
|
||||
<div class="text-right">
|
||||
<div class="text-end">
|
||||
<form action="{{ action_link }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{% url 'level_detail' object.level.pk %}"/>
|
||||
|
||||
@@ -47,7 +47,7 @@ def get_levels_of_depth(trainee, level):
|
||||
@register.simple_tag
|
||||
def confirm_button(user, trainee, level):
|
||||
if level.user_has_requirements(trainee):
|
||||
string = "<span class='badge badge-warning p-2'>Awaiting Confirmation</span>"
|
||||
string = "<span class='badge text-bg-warning p-2'>Awaiting Confirmation</span>"
|
||||
if models.Trainee.objects.get(pk=user.pk).is_supervisor or user.has_perm(
|
||||
"training.add_traininglevelqualification"
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user