Now with edits, delete confirmations
- and also a better alignment on actions - and konami code that works before login
This commit is contained in:
parent
3d35d47254
commit
3474239727
@ -30,7 +30,6 @@ def auth_only(f):
|
|||||||
def __f(request):
|
def __f(request):
|
||||||
# check that email is valid
|
# check that email is valid
|
||||||
# exp?
|
# exp?
|
||||||
print(request.META, file=sys.stderr)
|
|
||||||
if 'user_data' not in request.session:
|
if 'user_data' not in request.session:
|
||||||
raise PermissionDenied('Not logged in')
|
raise PermissionDenied('Not logged in')
|
||||||
email = request.session['user_data']['email']
|
email = request.session['user_data']['email']
|
||||||
@ -57,6 +56,7 @@ def get_list(request):
|
|||||||
'id': x.id,
|
'id': x.id,
|
||||||
'title': x.title,
|
'title': x.title,
|
||||||
'category': x.category.name,
|
'category': x.category.name,
|
||||||
|
'category_id': x.category.id,
|
||||||
'prototempalte': x.category.prototempalte.name,
|
'prototempalte': x.category.prototempalte.name,
|
||||||
'landscape': x.category.landscape,
|
'landscape': x.category.landscape,
|
||||||
'designation': x.designation,
|
'designation': x.designation,
|
||||||
|
@ -29,6 +29,7 @@ urlpatterns = [
|
|||||||
path('generate', tikette.views.generate),
|
path('generate', tikette.views.generate),
|
||||||
path('newtikette', tikette.views.newtikette),
|
path('newtikette', tikette.views.newtikette),
|
||||||
path('deletetikette', tikette.views.deletetikette),
|
path('deletetikette', tikette.views.deletetikette),
|
||||||
|
path('updatetikette', tikette.views.newtikette), # yes, we use newtikette
|
||||||
path('signin', tikette.views.signin),
|
path('signin', tikette.views.signin),
|
||||||
path('signout', tikette.views.signout),
|
path('signout', tikette.views.signout),
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
@ -21,14 +21,15 @@
|
|||||||
<script src="zetikettes.js"></script>
|
<script src="zetikettes.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
.actions {
|
||||||
display: flex;
|
margin-left: auto;
|
||||||
min-height: 100vh;
|
white-space: nowrap;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
.confirm {
|
||||||
flex: 1 0 auto;
|
width: 35%;
|
||||||
|
min-width: 20em;
|
||||||
|
max-width: 85%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@ -38,7 +39,7 @@ main {
|
|||||||
<a href="#" class="brand-logo">Zětikwett's</a>
|
<a href="#" class="brand-logo">Zětikwett's</a>
|
||||||
<ul id="nav-mobile" class="right hide-on-med-and-down">
|
<ul id="nav-mobile" class="right hide-on-med-and-down">
|
||||||
<li>
|
<li>
|
||||||
<a class="modal-trigger btn orange" href="#newproduct">
|
<a class="modal-trigger btn orange disabled" href="#newproduct">
|
||||||
<i class="material-icons left">add</i>Nouveau produit
|
<i class="material-icons left">add</i>Nouveau produit
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -49,8 +50,8 @@ main {
|
|||||||
<p></p>
|
<p></p>
|
||||||
<div class="col s4 offset-s4" id="signin-prompt" style="display: none"></div>
|
<div class="col s4 offset-s4" id="signin-prompt" style="display: none"></div>
|
||||||
<div class="col m6 offset-m3 s12">
|
<div class="col m6 offset-m3 s12">
|
||||||
<a class="modal-trigger btn orange hide-on-large-only" href="#newproduct"><i class="material-icons left">add</i>Nouveau produit</a>
|
<a class="modal-trigger btn orange hide-on-large-only disabled" href="#newproduct"><i class="material-icons left">add</i>Nouveau produit</a>
|
||||||
<ul class="collapsible" id="appbody">
|
<ul class="collapsible collection" id="appbody">
|
||||||
<div class="shimmer">
|
<div class="shimmer">
|
||||||
<li><div class="collapsible-header"><h6 class="faux-text short"></h6></div></li>
|
<li><div class="collapsible-header"><h6 class="faux-text short"></h6></div></li>
|
||||||
<li><div class="collapsible-header"><h6 class="faux-text"></h6></div></li>
|
<li><div class="collapsible-header"><h6 class="faux-text"></h6></div></li>
|
||||||
@ -58,6 +59,15 @@ main {
|
|||||||
</div>
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="confirmdelete" class="modal confirm">
|
||||||
|
<div class="modal-content">
|
||||||
|
Supprimer le produit <b id="delete-title">blařg titre long de test sa mère</b> ?
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="modal-close waves-effect btn-flat" id="delete-cancel">annuler</button>
|
||||||
|
<button type="submit" class="modal-close waves-effect waves-green btn" id="delete-confirm">supprimer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Modal Structure -->
|
<!-- Modal Structure -->
|
||||||
<div id="newproduct" class="modal">
|
<div id="newproduct" class="modal">
|
||||||
|
@ -30,6 +30,56 @@ function post(url, data) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disableButtons() {
|
||||||
|
$('.btn').addClass("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableButtons() {
|
||||||
|
$('.btn').removeClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetEditModal(force = false) {
|
||||||
|
if ($("#new-add").text() === "Ajouter" && !force) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$("#new-name").val("");
|
||||||
|
$("#new-type").val("").formSelect();
|
||||||
|
$("#new-designation").val("");
|
||||||
|
$("#new-ingredients").val("");
|
||||||
|
$("#new-description").val("");
|
||||||
|
$("#new-color")[0].jscolor.fromString("#97a1cc");
|
||||||
|
$("#new-organic").prop("checked", false);
|
||||||
|
M.updateTextFields();
|
||||||
|
|
||||||
|
$("#new-add").text("Ajouter").off('click').click(() => {
|
||||||
|
const req = getTiketteData();
|
||||||
|
post(backend_api + 'newtikette', req).then(() => {
|
||||||
|
resetEditModal(true);
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEditModal(zett) {
|
||||||
|
M.Modal.getInstance($("#newproduct")[0]).open();
|
||||||
|
|
||||||
|
$("#new-name").val(zett.title);
|
||||||
|
$("#new-type").val(zett.category_id).formSelect();
|
||||||
|
$("#new-designation").val(zett.designation);
|
||||||
|
$("#new-ingredients").val(zett.ingredients);
|
||||||
|
$("#new-description").val(zett.description);
|
||||||
|
$("#new-color")[0].jscolor.fromString(zett.color);
|
||||||
|
$("#new-organic").prop("checked", zett.ab === "inline");
|
||||||
|
M.updateTextFields();
|
||||||
|
|
||||||
|
$("#new-add").text("Modifier").off('click').click(() => {
|
||||||
|
const req = getTiketteData();
|
||||||
|
req.id = zett.id;
|
||||||
|
resetEditModal();
|
||||||
|
post(backend_api + 'updatetikette', req).then(reload);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function addProduct(tikette) {
|
function addProduct(tikette) {
|
||||||
const zett = tikette;
|
const zett = tikette;
|
||||||
const appbody = $("#appbody");
|
const appbody = $("#appbody");
|
||||||
@ -41,7 +91,7 @@ function addProduct(tikette) {
|
|||||||
.hide();
|
.hide();
|
||||||
|
|
||||||
const action = $('<div class="section">')
|
const action = $('<div class="section">')
|
||||||
.append($('<a class="btn">generate<a>')
|
.append($('<a class="btn">générer<a>')
|
||||||
.click(() => {
|
.click(() => {
|
||||||
const subs = block.find(':text')
|
const subs = block.find(':text')
|
||||||
.toArray()
|
.toArray()
|
||||||
@ -58,11 +108,11 @@ function addProduct(tikette) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loader.show();
|
loader.show();
|
||||||
$('.btn').addClass("disabled");
|
disableButtons();
|
||||||
|
|
||||||
post(backend_api + 'generate', req)
|
post(backend_api + 'generate', req)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const pdfbtn = $(`<a class="btn" href="${backend_api}data/${data.file}" target="_blank">open pdf</a>`);
|
const pdfbtn = $(`<a class="btn" href="${backend_api}data/${data.file}" target="_blank">ouvrir le pdf</a>`);
|
||||||
action.append(pdfbtn);
|
action.append(pdfbtn);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
@ -70,27 +120,37 @@ function addProduct(tikette) {
|
|||||||
})
|
})
|
||||||
.always(() => {
|
.always(() => {
|
||||||
loader.hide();
|
loader.hide();
|
||||||
$('.btn').removeClass('disabled');
|
enableButtons();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.append(loader));
|
.append(loader));
|
||||||
|
|
||||||
const deleteAction = $('<a class="btn-flat grey-text"><b class="material-icons">delete</b>');
|
const deleteAction = $('<b class="material-icons">delete</b>').click(() => {
|
||||||
deleteAction.click(() => {
|
$("#delete-title").text(zett.title);
|
||||||
const req = {
|
$("#delete-confirm").off('click').click(() => {
|
||||||
id: zett.id,
|
const req = {
|
||||||
};
|
id: zett.id,
|
||||||
post(backend_api + 'deletetikette', req).then(reload);
|
};
|
||||||
|
post(backend_api + 'deletetikette', req).then(reload);
|
||||||
|
});
|
||||||
|
M.Modal.getInstance($("#confirmdelete")[0]).open();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const editAction = $('<b class="material-icons">edit</b>').click(() => {
|
||||||
|
openEditModal(zett);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
appbody
|
appbody
|
||||||
.append($('<li>')
|
.append($('<li>')
|
||||||
.append($('<div class="collapsible-header valign-wrapper">')
|
.append($('<div class="collapsible-header valign-wrapper">')
|
||||||
.append(`<h6 class="blue-text">${zett.title}</h6>`)
|
.append(`<h6 class="blue-text">${zett.title}</h6>`)
|
||||||
.append($('<span class="badge">')
|
.append($('<span class="actions grey-text">')
|
||||||
.append(deleteAction)))
|
.append(editAction)
|
||||||
|
.append(deleteAction)
|
||||||
|
))
|
||||||
.append($('<div class="collapsible-body">')
|
.append($('<div class="collapsible-body">')
|
||||||
.append(block)
|
.append(block)
|
||||||
.append(action)));
|
.append(action)));
|
||||||
@ -103,6 +163,28 @@ function setCategories() {
|
|||||||
for (let kat of tikats) {
|
for (let kat of tikats) {
|
||||||
katsel.append($(`<option value="${kat.id}">${kat.name}</option>`));
|
katsel.append($(`<option value="${kat.id}">${kat.name}</option>`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('select').formSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTiketteData() {
|
||||||
|
const title = $("#new-name").val();
|
||||||
|
const category_id = $("#new-type").val();
|
||||||
|
const designation = $("#new-designation").val();
|
||||||
|
const ingredients = $("#new-ingredients").val();
|
||||||
|
const description = $("#new-description").val();
|
||||||
|
const color = $("#new-color").val().substring(1);
|
||||||
|
const ab = $("#new-organic").is(":checked") ? 'inline' : 'none';
|
||||||
|
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
category_id,
|
||||||
|
designation,
|
||||||
|
ingredients,
|
||||||
|
description,
|
||||||
|
color,
|
||||||
|
ab,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAll(zetikettes) {
|
function loadAll(zetikettes) {
|
||||||
@ -112,33 +194,6 @@ function loadAll(zetikettes) {
|
|||||||
addProduct(zett);
|
addProduct(zett);
|
||||||
}
|
}
|
||||||
setCategories();
|
setCategories();
|
||||||
|
|
||||||
$('.collapsible').collapsible();
|
|
||||||
$('.modal').modal();
|
|
||||||
$('select').formSelect();
|
|
||||||
|
|
||||||
konami();
|
|
||||||
|
|
||||||
$('#new-add').off('click').click(() => {
|
|
||||||
const title = $("#new-name").val();
|
|
||||||
const category_id = $("#new-type").val();
|
|
||||||
const designation = $("#new-designation").val();
|
|
||||||
const ingredients = $("#new-ingredients").val();
|
|
||||||
const description = $("#new-description").val();
|
|
||||||
const color = $("#new-color").val().substring(1);
|
|
||||||
const ab = $("#new-organic").is(":checked") ? 'visible' : 'none';
|
|
||||||
|
|
||||||
const req = {
|
|
||||||
title,
|
|
||||||
category_id,
|
|
||||||
designation,
|
|
||||||
ingredients,
|
|
||||||
description,
|
|
||||||
color,
|
|
||||||
ab,
|
|
||||||
};
|
|
||||||
post(backend_api + 'newtikette', req).then(reload);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function konami() {
|
function konami() {
|
||||||
@ -164,6 +219,8 @@ async function googleCred(creds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function reload() {
|
async function reload() {
|
||||||
|
disableButtons();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await $.ajax({
|
const resp = await $.ajax({
|
||||||
url: backend_api + 'list',
|
url: backend_api + 'list',
|
||||||
@ -176,6 +233,7 @@ async function reload() {
|
|||||||
xhrFields: { withCredentials: true },
|
xhrFields: { withCredentials: true },
|
||||||
})).tikats.sort((a, b) => a.name > b.name ? 1 : -1);
|
})).tikats.sort((a, b) => a.name > b.name ? 1 : -1);
|
||||||
loadAll(resp.tikettes.sort((a, b) => (a.title < b.title) ? -1 : 1));
|
loadAll(resp.tikettes.sort((a, b) => (a.title < b.title) ? -1 : 1));
|
||||||
|
enableButtons();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (e.status === 403) {
|
if (e.status === 403) {
|
||||||
$("#signin-prompt").show();
|
$("#signin-prompt").show();
|
||||||
@ -196,5 +254,10 @@ $(document).ready(() => {
|
|||||||
document.getElementById("signin-prompt"),
|
document.getElementById("signin-prompt"),
|
||||||
{ theme: "outline", size: "large" } // customization attributes
|
{ theme: "outline", size: "large" } // customization attributes
|
||||||
);
|
);
|
||||||
|
konami();
|
||||||
|
|
||||||
|
$('.collapsible').collapsible();
|
||||||
|
$('.modal').modal({onOpenStart: resetEditModal});
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ class Tikette:
|
|||||||
'ingredients': self.ingredients,
|
'ingredients': self.ingredients,
|
||||||
'description': self.description,
|
'description': self.description,
|
||||||
'color': self.color,
|
'color': self.color,
|
||||||
'ab': 'inline' if self.ab else 'none',
|
'ab': 'inline' if self.ab is 'True' else 'none',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user