pre-commit

This commit is contained in:
Gabriel Augendre 2022-06-14 16:53:39 +02:00
parent 0f503847c5
commit bf76cd227a
18 changed files with 903 additions and 629 deletions

51
.eslintrc Normal file
View file

@ -0,0 +1,51 @@
{
"env": {
"browser": true,
"es6": true,
"jquery": true
},
"extends": [
"eslint:recommended"
],
"ignorePatterns": ["dist/", "node_modules/"],
"rules": {
"block-scoped-var": "error",
"consistent-return": "error",
"curly": "error",
"default-case": "error",
"default-param-last": ["error"],
"dot-notation": "error",
"eqeqeq": "error",
"guard-for-in": "error",
"max-classes-per-file": "error",
"no-alert": "error",
"no-caller": "error",
"no-else-return": "error",
"no-empty-function": "error",
"no-floating-decimal": "error",
"no-implicit-coercion": "error",
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-param-reassign": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-self-compare": "error",
"no-throw-literal": "error",
"no-useless-concat": "error",
"radix": ["error", "as-needed"],
"require-await": "error",
"yoda": "error",
"no-shadow": "off",
"prefer-destructuring": ["error", { "array": false, "object": true }],
"padding-line-between-statements": [
"error",
{ "blankLine": "always", "prev": "import", "next": "export" },
{ "blankLine": "always", "prev": "export", "next": "export" },
{ "blankLine": "always", "prev": "*", "next": "return" }
]
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
}
}

View file

@ -1,20 +1,18 @@
exclude: \.min\.(js|css)$|/generated/ exclude: (\.min\.(js|css)(\.map)?$|/vendor/)
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0 rev: v4.1.0
hooks: hooks:
- id: check-ast - id: check-ast
types: [python]
- id: check-json - id: check-json
types: [json]
- id: check-toml - id: check-toml
types: [toml]
- id: check-xml - id: check-xml
types: [xml]
- id: check-yaml - id: check-yaml
types: [yaml] args: [--allow-multiple-documents]
- id: end-of-file-fixer - id: end-of-file-fixer
- id: check-merge-conflict - id: check-merge-conflict
- id: debug-statements
- id: detect-private-key
- id: pretty-format-json - id: pretty-format-json
args: args:
- --autofix - --autofix
@ -23,12 +21,57 @@ repos:
args: args:
- --markdown-linebreak-ext=md - --markdown-linebreak-ext=md
- repo: https://github.com/timothycrosley/isort - repo: https://github.com/timothycrosley/isort
rev: 5.8.0 rev: 5.10.1
hooks: hooks:
- id: isort - id: isort
types: [python] args:
- --profile=black
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 20.8b1 rev: 22.1.0
hooks: hooks:
- id: black - id: black
types: [python] args:
- --target-version=py310
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.0
hooks:
- id: pyupgrade
args:
- --py310-plus
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.4.0
hooks:
- id: django-upgrade
args: [--target-version, "4.0"]
- repo: https://github.com/rtts/djhtml
rev: v1.5.0
hooks:
- id: djhtml
- repo: https://github.com/flakeheaven/flakeheaven
rev: 0.11.0
hooks:
- id: flakeheaven
additional_dependencies:
- flake8-annotations-complexity
- flake8-builtins
- flake8-bugbear
- flake8-comprehensions
- flake8-eradicate
- flake8-noqa
- flake8-pytest-style
- flake8-pyi
- wemake-python-styleguide
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.5.1
hooks:
- id: prettier
types_or: [javascript, css]
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.9.0
hooks:
- id: eslint
args: [--fix]
types_or: [javascript, css]
additional_dependencies:
- eslint@^7.29.0
- eslint-config-prettier@^8.3.0

5
.prettierrc Normal file
View file

@ -0,0 +1,5 @@
{
"tabWidth": 4,
"printWidth": 120,
"endOfLine": "auto"
}

View file

@ -22,4 +22,3 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org> For more information, please refer to <https://unlicense.org>

View file

@ -93,7 +93,7 @@ class LevelAdmin(ExportMixin, admin.ModelAdmin):
def get_queryset(self, request): def get_queryset(self, request):
return ( return (
super(LevelAdmin, self) super()
.get_queryset(request) .get_queryset(request)
.prefetch_related(Prefetch("book_set", to_attr="prefetched_books")) .prefetch_related(Prefetch("book_set", to_attr="prefetched_books"))
) )
@ -230,9 +230,7 @@ class BookAdmin(ExportMixin, admin.ModelAdmin):
def get_queryset(self, request): def get_queryset(self, request):
return ( return (
super(BookAdmin, self) super().get_queryset(request).select_related("editor", "level", "teacher")
.get_queryset(request)
.select_related("editor", "level", "teacher")
) )
def update_with_decitre(self, request, queryset): def update_with_decitre(self, request, queryset):
@ -298,8 +296,4 @@ class SuppliesRequirementAdmin(ExportMixin, admin.ModelAdmin):
list_filter = ["done", "teacher", "level"] list_filter = ["done", "teacher", "level"]
def get_queryset(self, request): def get_queryset(self, request):
return ( return super().get_queryset(request).select_related("level", "teacher")
super(SuppliesRequirementAdmin, self)
.get_queryset(request)
.select_related("level", "teacher")
)

View file

@ -1,104 +1,108 @@
document.addEventListener("DOMContentLoaded", function (event) { document.addEventListener("DOMContentLoaded", function () {
$(function () { $(function () {
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
}); });
var isbnButton = document.querySelector('#id_isbn_button'); var isbnButton = document.querySelector("#id_isbn_button");
var isbn = document.querySelector('#id_isbn'); var isbn = document.querySelector("#id_isbn");
var title = document.querySelector('#id_title'); var title = document.querySelector("#id_title");
var authors = document.querySelector('#id_authors'); var authors = document.querySelector("#id_authors");
var year = document.querySelector('#id_publication_year'); var year = document.querySelector("#id_publication_year");
var price = document.querySelector('#id_price'); var price = document.querySelector("#id_price");
var editor = document.querySelector('#id_editor'); var editor = document.querySelector("#id_editor");
var otherEditor = document.querySelector('#id_other_editor'); var otherEditor = document.querySelector("#id_other_editor");
var spinner = document.querySelector('#id_isbn_spinner'); var spinner = document.querySelector("#id_isbn_spinner");
var feedback = document.querySelector('#id_isbn_invalid_feedback'); var feedback = document.querySelector("#id_isbn_invalid_feedback");
function enableFields() { function enableFields() {
isbn.removeAttribute('disabled'); isbn.removeAttribute("disabled");
isbnButton.removeAttribute('disabled'); isbnButton.removeAttribute("disabled");
document.querySelector('#id_title').removeAttribute('disabled'); document.querySelector("#id_title").removeAttribute("disabled");
authors.removeAttribute('disabled'); authors.removeAttribute("disabled");
year.removeAttribute('disabled'); year.removeAttribute("disabled");
price.removeAttribute('disabled'); price.removeAttribute("disabled");
editor.removeAttribute('disabled'); editor.removeAttribute("disabled");
otherEditor.removeAttribute('disabled'); otherEditor.removeAttribute("disabled");
spinner.setAttribute('hidden', 'hidden'); spinner.setAttribute("hidden", "hidden");
} }
function disableFields() { function disableFields() {
isbn.setAttribute('disabled', 'disabled'); isbn.setAttribute("disabled", "disabled");
isbnButton.setAttribute('disabled', 'disabled'); isbnButton.setAttribute("disabled", "disabled");
title.setAttribute('disabled', 'disabled'); title.setAttribute("disabled", "disabled");
authors.setAttribute('disabled', 'disabled'); authors.setAttribute("disabled", "disabled");
year.setAttribute('disabled', 'disabled'); year.setAttribute("disabled", "disabled");
price.setAttribute('disabled', 'disabled'); price.setAttribute("disabled", "disabled");
editor.setAttribute('disabled', 'disabled'); editor.setAttribute("disabled", "disabled");
otherEditor.setAttribute('disabled', 'disabled'); otherEditor.setAttribute("disabled", "disabled");
spinner.removeAttribute('hidden'); spinner.removeAttribute("hidden");
} }
isbnButton.addEventListener('click', function (event) { isbnButton.addEventListener("click", function () {
if (!isbn.value) { if (!isbn.value) {
return; return;
} }
disableFields(); disableFields();
fetch("/isbn_api/" + isbn.value).then(function (data) { fetch("/isbn_api/" + isbn.value)
if (!data.ok) { .then(function (data) {
throw Error("Erreur dans la récupération des données"); if (!data.ok) {
} throw Error("Erreur dans la récupération des données");
return data.json(); }
}).then(function (data) {
isbn.classList.remove('is-invalid');
isbn.classList.add('is-valid');
feedback.style.display = 'none';
feedback.textContent = '';
title.value = data.title; return data.json();
title.classList.add('is-valid'); })
authors.value = data.authors; .then(function (data) {
authors.classList.add('is-valid'); isbn.classList.remove("is-invalid");
year.value = data.year; isbn.classList.add("is-valid");
year.classList.add('is-valid'); feedback.style.display = "none";
price.value = data.price; feedback.textContent = "";
price.classList.add('is-valid');
var editorValue = ""; title.value = data.title;
var editorIsOther = false; title.classList.add("is-valid");
if (data.editor) { authors.value = data.authors;
for (var option of document.querySelector('#id_editor').children) { authors.classList.add("is-valid");
if (editorValue === "" && option.firstChild.data.toLowerCase().indexOf('autre') !== -1) { year.value = data.year;
editorValue = option.value; year.classList.add("is-valid");
editorIsOther = true; price.value = data.price;
} price.classList.add("is-valid");
if (option.firstChild.data.toLowerCase() === data.editor.toLowerCase()) {
editorValue = option.value; var editorValue = "";
editorIsOther = false; var editorIsOther = false;
if (data.editor) {
for (var option of document.querySelector("#id_editor").children) {
if (editorValue === "" && option.firstChild.data.toLowerCase().indexOf("autre") !== -1) {
editorValue = option.value;
editorIsOther = true;
}
if (option.firstChild.data.toLowerCase() === data.editor.toLowerCase()) {
editorValue = option.value;
editorIsOther = false;
}
} }
} }
} editor.value = editorValue;
editor.value = editorValue; editor.classList.add("is-valid");
editor.classList.add('is-valid');
if (editorIsOther) { if (editorIsOther) {
otherEditor.value = data.editor; otherEditor.value = data.editor;
otherEditor.classList.add('is-valid'); otherEditor.classList.add("is-valid");
} }
enableFields(); enableFields();
// The event propagation must be done after the fields have been re-enabled // The event propagation must be done after the fields have been re-enabled
// because a change event can't be propagated to a field that's disabled. // because a change event can't be propagated to a field that's disabled.
var event = document.createEvent("HTMLEvents"); var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true); event.initEvent("change", true, true);
event.eventName = "change"; event.eventName = "change";
document.querySelector('#id_editor').dispatchEvent(event); document.querySelector("#id_editor").dispatchEvent(event);
}).catch(function(error) { })
isbn.classList.add('is-invalid'); .catch(function (error) {
isbn.classList.remove('is-valid'); isbn.classList.add("is-invalid");
feedback.style.display = 'block'; isbn.classList.remove("is-valid");
feedback.textContent = error; feedback.style.display = "block";
enableFields(); feedback.textContent = error;
}); enableFields();
});
}); });
}); });

View file

@ -1,79 +1,78 @@
document.addEventListener("DOMContentLoaded", function (event) { document.addEventListener("DOMContentLoaded", function () {
var selectors = [ var selectors = [
{ {
id: "#id_no_book", id: "#id_no_book",
value: "PAS DE LIVRE POUR CETTE CLASSE" value: "PAS DE LIVRE POUR CETTE CLASSE",
}, },
{ {
id: "#id_see_later", id: "#id_see_later",
value: "VOIR À LA RENTRÉE" value: "VOIR À LA RENTRÉE",
}, },
]; ];
selectors.forEach(function (selector, index, array) { selectors.forEach(function (selector) {
var _selector = document.querySelector(selector.id); var _selector = document.querySelector(selector.id);
if (_selector === null) return; if (_selector === null) {
return;
}
var data = { var data = {
title: document.querySelector('#id_title').value, title: document.querySelector("#id_title").value,
authors: document.querySelector('#id_authors').value, authors: document.querySelector("#id_authors").value,
publicationYear: document.querySelector('#id_publication_year').value, publicationYear: document.querySelector("#id_publication_year").value,
isbn: document.querySelector('#id_isbn').value, isbn: document.querySelector("#id_isbn").value,
price: document.querySelector('#id_price').value, price: document.querySelector("#id_price").value,
editor: document.querySelector('#id_editor').value, editor: document.querySelector("#id_editor").value,
previouslyAcquired: document.querySelector('#id_previously_acquired').value, previouslyAcquired: document.querySelector("#id_previously_acquired").value,
}; };
_selector.addEventListener('change', function (event) { _selector.addEventListener("change", function () {
if (_selector.checked) { if (_selector.checked) {
data = { data = {
title: document.querySelector('#id_title').value, title: document.querySelector("#id_title").value,
authors: document.querySelector('#id_authors').value, authors: document.querySelector("#id_authors").value,
publicationYear: document.querySelector('#id_publication_year').value, publicationYear: document.querySelector("#id_publication_year").value,
isbn: document.querySelector('#id_isbn').value, isbn: document.querySelector("#id_isbn").value,
price: document.querySelector('#id_price').value, price: document.querySelector("#id_price").value,
editor: document.querySelector('#id_editor').value, editor: document.querySelector("#id_editor").value,
previouslyAcquired: document.querySelector('#id_previously_acquired').value, previouslyAcquired: document.querySelector("#id_previously_acquired").value,
}; };
document.querySelector('#id_title').value = selector.value; document.querySelector("#id_title").value = selector.value;
document.querySelector('#id_authors').value = "N/A"; document.querySelector("#id_authors").value = "N/A";
document.querySelector('#id_publication_year').value = 1900; document.querySelector("#id_publication_year").value = 1900;
document.querySelector('#id_isbn').value = "0000000000"; document.querySelector("#id_isbn").value = "0000000000";
document.querySelector('#id_price').value = 0; document.querySelector("#id_price").value = 0;
document.querySelector('#id_previously_acquired').value = "False"; document.querySelector("#id_previously_acquired").value = "False";
var editorValue = null; var editorValue = null;
for (var option of document.querySelector('#id_editor').children) { for (var option of document.querySelector("#id_editor").children) {
if (editorValue === null && option.value !== "") { if (editorValue === null && option.value !== "") {
editorValue = option.value; editorValue = option.value;
} }
if (option.firstChild.data.toLowerCase().indexOf('autre') !== -1) { if (option.firstChild.data.toLowerCase().indexOf("autre") !== -1) {
editorValue = option.value; editorValue = option.value;
} }
} }
document.querySelector('#id_editor').value = editorValue; document.querySelector("#id_editor").value = editorValue;
} else { } else {
document.querySelector('#id_title').value = data.title; document.querySelector("#id_title").value = data.title;
document.querySelector('#id_authors').value = data.authors; document.querySelector("#id_authors").value = data.authors;
document.querySelector('#id_editor').value = data.editor; document.querySelector("#id_editor").value = data.editor;
document.querySelector('#id_publication_year').value = data.publicationYear; document.querySelector("#id_publication_year").value = data.publicationYear;
document.querySelector('#id_isbn').value = data.isbn; document.querySelector("#id_isbn").value = data.isbn;
document.querySelector('#id_price').value = data.price; document.querySelector("#id_price").value = data.price;
document.querySelector('#id_previously_acquired').value = data.previouslyAcquired; document.querySelector("#id_previously_acquired").value = data.previouslyAcquired;
} }
}); });
}); });
function toggleOtherEditorDisplay() { function toggleOtherEditorDisplay() {
var editor = document.querySelector('#id_editor'); var editor = document.querySelector("#id_editor");
var otherEditor = document.querySelector('#id_other_editor').parentElement; var otherEditor = document.querySelector("#id_other_editor").parentElement;
if (editor.options[editor.selectedIndex].text.toLowerCase().indexOf('autre') !== -1) { if (editor.options[editor.selectedIndex].text.toLowerCase().indexOf("autre") !== -1) {
otherEditor.style.display = 'block'; otherEditor.style.display = "block";
} } else {
else { otherEditor.style.display = "none";
otherEditor.style.display = 'none';
} }
} }
toggleOtherEditorDisplay(); toggleOtherEditorDisplay();
document.querySelector('#id_editor').addEventListener('change', toggleOtherEditorDisplay); document.querySelector("#id_editor").addEventListener("change", toggleOtherEditorDisplay);
}); });

View file

@ -19,7 +19,7 @@
Vous avez peut-être déjà rencontré ce type d'erreur (peut-être même sur ce site) sans Vous avez peut-être déjà rencontré ce type d'erreur (peut-être même sur ce site) sans
forcément comprendre ce qu'il signifie. forcément comprendre ce qu'il signifie.
Voici donc un extrait de <a href="https://fr.wikipedia.org/wiki/Erreur_HTTP_404">la page Wikipedia Voici donc un extrait de <a href="https://fr.wikipedia.org/wiki/Erreur_HTTP_404">la page Wikipedia
traitant spécifiquement de l'erreur 404</a> <i class="fas fa-book-reader"></i> traitant spécifiquement de l'erreur 404</a> <i class="fas fa-book-reader"></i>
</p> </p>
<blockquote class="blockquote text-right"> <blockquote class="blockquote text-right">

View file

@ -31,7 +31,7 @@
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="{{ form.see_later.auto_id }}"> <input type="checkbox" class="custom-control-input" id="{{ form.see_later.auto_id }}">
<label class="custom-control-label" <label class="custom-control-label"
for="{{ form.see_later.auto_id }}">{{ form.see_later.label }}</label> for="{{ form.see_later.auto_id }}">{{ form.see_later.label }}</label>
<small class="form-text text-muted"> <small class="form-text text-muted">
{{ form.see_later.help_text|safe }} {{ form.see_later.help_text|safe }}
</small> </small>
@ -44,10 +44,10 @@
{% bootstrap_label content=form.isbn.label label_for=form.isbn.auto_id %} {% bootstrap_label content=form.isbn.label label_for=form.isbn.auto_id %}
<div class="input-group"> <div class="input-group">
<input name="{{ form.isbn.name }}" maxlength="20" <input name="{{ form.isbn.name }}" maxlength="20"
class="form-control" class="form-control"
placeholder="{{ form.isbn.label }}" placeholder="{{ form.isbn.label }}"
{% if form.isbn.value != None %} value="{{ form.isbn.value|stringformat:'s' }}"{% endif %} {% if form.isbn.value != None %} value="{{ form.isbn.value|stringformat:'s' }}"{% endif %}
required="" id="{{ form.isbn.auto_id }}" type="text"> required="" id="{{ form.isbn.auto_id }}" type="text">
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-primary" type="button" id="id_isbn_button" data-toggle="tooltip" data-placement="top" title="Chercher avec Decitre"> <button class="btn btn-primary" type="button" id="id_isbn_button" data-toggle="tooltip" data-placement="top" title="Chercher avec Decitre">
<i class="fas fa-search"></i> <i class="fas fa-spinner fa-spin" id="id_isbn_spinner" hidden></i> <i class="fas fa-search"></i> <i class="fas fa-spinner fa-spin" id="id_isbn_spinner" hidden></i>
@ -95,11 +95,11 @@
<div class="col-12"> <div class="col-12">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" <input type="checkbox" class="custom-control-input"
{% if form.add_another.initial %}checked="checked"{% endif %} {% if form.add_another.initial %}checked="checked"{% endif %}
name="{{ form.add_another.name }}" name="{{ form.add_another.name }}"
id="{{ form.add_another.auto_id }}"> id="{{ form.add_another.auto_id }}">
<label class="custom-control-label" <label class="custom-control-label"
for="{{ form.add_another.auto_id }}">{{ form.add_another.label }}</label> for="{{ form.add_another.auto_id }}">{{ form.add_another.label }}</label>
<small class="form-text text-muted"> <small class="form-text text-muted">
{{ form.add_another.help_text|safe }} {{ form.add_another.help_text|safe }}
</small> </small>

View file

@ -34,11 +34,11 @@
<div class="col-12"> <div class="col-12">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" <input type="checkbox" class="custom-control-input"
{% if form.add_another.initial %}checked="checked"{% endif %} {% if form.add_another.initial %}checked="checked"{% endif %}
name="{{ form.add_another.name }}" name="{{ form.add_another.name }}"
id="{{ form.add_another.auto_id }}"> id="{{ form.add_another.auto_id }}">
<label class="custom-control-label" <label class="custom-control-label"
for="{{ form.add_another.auto_id }}">{{ form.add_another.label }}</label> for="{{ form.add_another.auto_id }}">{{ form.add_another.label }}</label>
<small class="form-text text-muted"> <small class="form-text text-muted">
{{ form.add_another.help_text|safe }} {{ form.add_another.help_text|safe }}
</small> </small>

View file

@ -2,87 +2,87 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"> content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Manuels - {% block title %}{% endblock %}</title> <title>Manuels - {% block title %}{% endblock %}</title>
<link rel="apple-touch-icon" sizes="180x180" <link rel="apple-touch-icon" sizes="180x180"
href="{% static 'icons/apple-touch-icon.png' %}"> href="{% static 'icons/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" <link rel="icon" type="image/png" sizes="32x32"
href="{% static 'icons/favicon-32x32.png' %}"> href="{% static 'icons/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" <link rel="icon" type="image/png" sizes="16x16"
href="{% static 'icons/favicon-16x16.png' %}"> href="{% static 'icons/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'icons/site.webmanifest' %}"> <link rel="manifest" href="{% static 'icons/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'icons/safari-pinned-tab.svg' %}" <link rel="mask-icon" href="{% static 'icons/safari-pinned-tab.svg' %}"
color="#000000"> color="#000000">
<link rel="shortcut icon" href="{% static 'icons/favicon.ico' %}"> <link rel="shortcut icon" href="{% static 'icons/favicon.ico' %}">
<meta name="msapplication-TileColor" content="#2d89ef"> <meta name="msapplication-TileColor" content="#2d89ef">
<meta name="msapplication-config" <meta name="msapplication-config"
content="{% static 'icons/browserconfig.xml' %}"> content="{% static 'icons/browserconfig.xml' %}">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<link rel="stylesheet" <link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
crossorigin="anonymous"> crossorigin="anonymous">
</head> </head>
<body> <body>
<div class="d-flex flex-column min-vh-100"> <div class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{% url 'home_page' %}">Manuels scolaires</a> <a class="navbar-brand" href="{% url 'home_page' %}">Manuels scolaires</a>
{% if user.is_authenticated or teacher and teacher.email in authorized_mails %} {% if user.is_authenticated or teacher and teacher.email in authorized_mails %}
<button class="navbar-toggler" type="button" data-toggle="collapse" <button class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation"> aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'admin:index' %}"> <a class="nav-link" href="{% url 'admin:index' %}">
<i class="fas fa-door-open"></i> <i class="fas fa-door-open"></i>
Administration Administration
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
</nav> </nav>
<main class="flex-fill"> <main class="flex-fill">
<div class="container-fluid"> <div class="container-fluid">
{% for message in messages %} {% for message in messages %}
<div class="alert alert-{{ message.tags }} fade show" role="alert"> <div class="alert alert-{{ message.tags }} fade show" role="alert">
{{ message }} {{ message }}
</div>
{% endfor %}
{% block content %}
{% endblock %}
</div> </div>
{% endfor %} </main>
{% block content %}
{% endblock %} <footer class="bg-light py-3">
<div class="container-fluid">
<span class="text-muted">Ce service est un logiciel libre sous licence MIT réalisé par
Gabriel Augendre d'après des besoins exprimés par Sandrine Augendre. Le code source est disponible
<a href="https://git.augendre.info/gaugendre/manuels-scolaires">à cette adresse</a>.</span>
</div>
</footer>
</div> </div>
</main>
<footer class="bg-light py-3"> <script defer src="https://kit.fontawesome.com/350c07ee78.js"
<div class="container-fluid"> integrity="sha384-IwFbZvLB3nqmwJikzn6JZAqNDTwjFfauT4djixzjaxmR030Fd2gx05kWWwBLwRYZ"
<span class="text-muted">Ce service est un logiciel libre sous licence MIT réalisé par crossorigin="anonymous"></script>
Gabriel Augendre d'après des besoins exprimés par Sandrine Augendre. Le code source est disponible <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
<a href="https://git.augendre.info/gaugendre/manuels-scolaires">à cette adresse</a>.</span> integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
</div> crossorigin="anonymous"></script>
</footer> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
</div> integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns"
crossorigin="anonymous"></script>
<script defer src="https://kit.fontawesome.com/350c07ee78.js" {% block end_js %}
integrity="sha384-IwFbZvLB3nqmwJikzn6JZAqNDTwjFfauT4djixzjaxmR030Fd2gx05kWWwBLwRYZ" {% endblock %}
crossorigin="anonymous"></script> </body>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns"
crossorigin="anonymous"></script>
{% block end_js %}
{% endblock %}
</body>
</html> </html>

View file

@ -18,7 +18,7 @@
<h4 class="alert-heading"><i class="fas fa-exclamation-circle"></i> Danger</h4> <h4 class="alert-heading"><i class="fas fa-exclamation-circle"></i> Danger</h4>
<p class="mb-0"> <p class="mb-0">
Êtes-vous <strong>certain&centerdot;e</strong> de vouloir confirmer vos listes de manuels et de fournitures ? Êtes-vous <strong>certain&centerdot;e</strong> de vouloir confirmer vos listes de manuels et de fournitures ?
Cette action est <u><strong>définitive</strong></u> : vous ne ne serez plus en mesure de les modifier ensuite. Cette action est <u><strong>définitive</strong></u> : vous ne ne serez plus en mesure de les modifier ensuite.
</p> </p>
</div> </div>
<form action="" method="post" class="form"> <form action="" method="post" class="form">

View file

@ -1,6 +1,6 @@
<html> <html>
<p>Bonjour,</p> <p>Bonjour,</p>
<p> <p>
{{ teacher.full_name }} a confirmé ses listes sur <a href="{{ link }}">{{ link }}</a> {{ teacher.full_name }} a confirmé ses listes sur <a href="{{ link }}">{{ link }}</a>
</p> </p>
</html> </html>

View file

@ -1,10 +1,10 @@
<html> <html>
<p>Bonjour {{ teacher.first_name }},</p> <p>Bonjour {{ teacher.first_name }},</p>
<p> <p>
Voici votre lien pour la gestion des manuels scolaires : Voici votre lien pour la gestion des manuels scolaires :
</p> </p>
<p style="text-align: center;"> <p style="text-align: center;">
<a href="{{ link }}">{{ link }}</a> <a href="{{ link }}">{{ link }}</a>
</p> </p>
</html> </html>

View file

@ -34,8 +34,8 @@
Liste des livres demandés Liste des livres demandés
{% if not teacher.has_confirmed_list %} {% if not teacher.has_confirmed_list %}
<a href="{% url 'add_book' pk=teacher.pk %}" <a href="{% url 'add_book' pk=teacher.pk %}"
class="btn btn-primary" class="btn btn-primary"
id="add-book"> id="add-book">
<i class="fas fa-plus-circle"></i> Ajouter un livre <i class="fas fa-plus-circle"></i> Ajouter un livre
</a> </a>
{% endif %} {% endif %}
@ -43,57 +43,57 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover table-sm"> <table class="table table-hover table-sm">
<thead> <thead>
<tr>
{% if not teacher.has_confirmed_list %}
<th scope="col">Modifier</th>
{% endif %}
<th scope="col">Classe</th>
<th scope="col">Discipline</th>
<th scope="col">Titre</th>
<th scope="col">Auteurs</th>
<th scope="col">Éditeur</th>
<th scope="col">Année de publication</th>
<th scope="col">ISBN</th>
<th scope="col">Prix</th>
<th scope="col">Déjà acheté par l'élève</th>
<th scope="col">Consommable</th>
</tr>
</thead>
<tbody>
{% for book in teacher.book_set.all %}
<tr> <tr>
{% if not teacher.has_confirmed_list %} {% if not teacher.has_confirmed_list %}
<th scope="row"> <th scope="col">Modifier</th>
<div class="btn-group">
<a title="Modifier"
href="{% url 'edit_book' teacher_pk=book.teacher.pk pk=book.pk %}"
class="btn btn-sm btn-secondary"><i class="fas fa-edit"></i></a>
<a title="Supprimer"
href="{% url 'delete_book' teacher_pk=book.teacher.pk pk=book.pk %}"
class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></a>
</div>
</th>
{% endif %} {% endif %}
<td>{{ book.level }}</td> <th scope="col">Classe</th>
<td>{{ book.field }}</td> <th scope="col">Discipline</th>
<td>{{ book.title }}</td> <th scope="col">Titre</th>
<td>{{ book.authors }}</td> <th scope="col">Auteurs</th>
<td>{{ book.editor }}{% if book.other_editor %} <th scope="col">Éditeur</th>
({{ book.other_editor }}) <th scope="col">Année de publication</th>
{% endif %}</td> <th scope="col">ISBN</th>
<td>{{ book.publication_year }}</td> <th scope="col">Prix</th>
<td>{{ book.isbn }}</td> <th scope="col">Déjà acheté par l'élève</th>
<td>{{ book.price }}€</td> <th scope="col">Consommable</th>
<td>
<i class="fas fa-{% if book.previously_acquired %}check-circle{% else %}ban{% endif %}"></i>
{{ book.previously_acquired_text }}
</td>
<td>
<i class="fas fa-{% if book.consumable %}check-circle{% else %}ban{% endif %}"></i>
{{ book.consumable_text }}
</td>
</tr> </tr>
{% endfor %} </thead>
<tbody>
{% for book in teacher.book_set.all %}
<tr>
{% if not teacher.has_confirmed_list %}
<th scope="row">
<div class="btn-group">
<a title="Modifier"
href="{% url 'edit_book' teacher_pk=book.teacher.pk pk=book.pk %}"
class="btn btn-sm btn-secondary"><i class="fas fa-edit"></i></a>
<a title="Supprimer"
href="{% url 'delete_book' teacher_pk=book.teacher.pk pk=book.pk %}"
class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></a>
</div>
</th>
{% endif %}
<td>{{ book.level }}</td>
<td>{{ book.field }}</td>
<td>{{ book.title }}</td>
<td>{{ book.authors }}</td>
<td>{{ book.editor }}{% if book.other_editor %}
({{ book.other_editor }})
{% endif %}</td>
<td>{{ book.publication_year }}</td>
<td>{{ book.isbn }}</td>
<td>{{ book.price }}€</td>
<td>
<i class="fas fa-{% if book.previously_acquired %}check-circle{% else %}ban{% endif %}"></i>
{{ book.previously_acquired_text }}
</td>
<td>
<i class="fas fa-{% if book.consumable %}check-circle{% else %}ban{% endif %}"></i>
{{ book.consumable_text }}
</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
@ -112,35 +112,35 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover table-sm"> <table class="table table-hover table-sm">
<thead> <thead>
<tr>
{% if not teacher.has_confirmed_list %}
<th scope="col">Modifier</th>
{% endif %}
<th scope="col">Classe</th>
<th scope="col">Discipline</th>
<th scope="col">Liste de fournitures</th>
</tr>
</thead>
<tbody>
{% for supply in teacher.suppliesrequirement_set.all %}
<tr> <tr>
{% if not teacher.has_confirmed_list %} {% if not teacher.has_confirmed_list %}
<th scope="row"> <th scope="col">Modifier</th>
<div class="btn-group">
<a title="Modifier"
href="{% url 'edit_supplies' teacher_pk=supply.teacher.pk pk=supply.pk %}"
class="btn btn-sm btn-secondary"><i class="fas fa-edit"></i></a>
<a title="Supprimer"
href="{% url 'delete_supplies' teacher_pk=supply.teacher.pk pk=supply.pk %}"
class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></a>
</div>
</th>
{% endif %} {% endif %}
<td>{{ supply.level }}</td> <th scope="col">Classe</th>
<td>{{ supply.field }}</td> <th scope="col">Discipline</th>
<td>{{ supply.supplies|linebreaksbr }}</td> <th scope="col">Liste de fournitures</th>
</tr> </tr>
{% endfor %} </thead>
<tbody>
{% for supply in teacher.suppliesrequirement_set.all %}
<tr>
{% if not teacher.has_confirmed_list %}
<th scope="row">
<div class="btn-group">
<a title="Modifier"
href="{% url 'edit_supplies' teacher_pk=supply.teacher.pk pk=supply.pk %}"
class="btn btn-sm btn-secondary"><i class="fas fa-edit"></i></a>
<a title="Supprimer"
href="{% url 'delete_supplies' teacher_pk=supply.teacher.pk pk=supply.pk %}"
class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></a>
</div>
</th>
{% endif %}
<td>{{ supply.level }}</td>
<td>{{ supply.field }}</td>
<td>{{ supply.supplies|linebreaksbr }}</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>

777
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@ authors = ["Gabriel Augendre <gabriel@augendre.info>"]
license = "MIT" license = "MIT"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.10"
Django = "^3.2.4" Django = "^3.2.4"
django-bootstrap4 = "^3.0.1" django-bootstrap4 = "^3.0.1"
gunicorn = "^20.1.0" gunicorn = "^20.1.0"
@ -32,12 +32,6 @@ vcrpy = "^4.1.1"
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.black]
target-version = ['py38']
[tool.isort]
profile = "black"
[tool.pytest.ini_options] [tool.pytest.ini_options]
addopts = "--html=pytest_result/pytest.html --color=yes" addopts = "--html=pytest_result/pytest.html --color=yes"
minversion = "6.0" minversion = "6.0"