MySC/static/main.js
2024-09-22 19:45:14 +02:00

1629 lines
44 KiB
JavaScript

// AlertifyJS default settings
alertify.defaults = {
// dialogs defaults
modal: true,
movable: true,
resizable: true,
closable: true,
maximizable: true,
pinnable: true,
pinned: true,
padding: true,
overflow: true,
maintainFocus: true,
transition: "fade",
// notifier defaults
notifier: {
// auto-dismiss wait time (in seconds)
delay: 0,
// default position
position: "top-right",
},
// language resources
glossary: {
// Dialog title text
title: _("Confirmation"),
// ok button text
ok: _("OK"),
// cancel button text
cancel: _("Cancel"),
},
theme: {
// class name attached to prompt dialog input textbox.
input: "ajs-input form-control",
// class name attached to ok button
ok: "ajs-ok btn btn-primary",
// class name attached to cancel button
cancel: "ajs-cancel btn btn-default",
},
// global hooks
hooks: {
// invoked before initializing any dialog
preinit: function (instance) {},
// invoked after initializing any dialog
postinit: function (instance) {},
},
};
$("#cats").collapse({
toggle: false,
});
on_title_click = function (event) {
if (event.target.tagName == "BUTTON") {
return;
}
var title = $(this);
var panel = title.parent().parent();
var panel_collapse = panel.find(".panel-collapse");
var show = !panel_collapse.hasClass("in");
$(".panel-collapse").each(function (idx, div) {
$(div).collapse("hide");
});
if (show) panel_collapse.collapse("show");
set_location(
title.data("scase").name,
show ? title.data("cat").name : null,
title.data("trash") ? "trash" : null
);
};
/***********************
* Add scase
**********************/
on_add_scase_btn_click = function (event) {
navbar_collapse_hide();
$("#add_scase_modal").modal("show");
};
on_valid_add_scase_modal = function (e) {
e.preventDefault();
var name = $("#add_scase_name")[0].value;
if (name == "") {
alertify.notify(
_("You have to enter the name of the suitcase!"),
"error",
5
);
return;
}
var nameshake = scases.byName(name);
if (nameshake) {
if (nameshake.removed) {
alertify.notify(
_("A suitcase exist with this name exist in the trash."),
"error",
5
);
} else {
alertify.notify(_("This suitcase already exist!"), "error", 5);
}
return;
}
var scase = scases.newSCase(name);
if (scase) {
scases.save();
show_scase(scase);
auto_sync_local_data();
}
$("#add_scase_modal").modal("hide");
};
on_show_add_scase_modal = function () {
$("#add_scase_name").focus();
};
on_close_add_scase_modal = function () {
$("#add_scase_modal form")[0].reset();
};
/***********************
* Rename scase
**********************/
on_rename_scase_btn_click = function (event) {
navbar_collapse_hide();
$("#rename_scase_name")[0].value = $("#cats").data("scase");
$("#rename_scase_modal").modal("show");
};
on_valid_rename_scase_modal = function (e) {
e.preventDefault();
var name = $("#rename_scase_name")[0].value;
if (name == "") {
alertify.notify(
_("You have to enter the new name of the suitcase!"),
"error",
5
);
return;
}
if ($("#cats").data("scase") != name) {
var nameshake = scases.byName(name);
if (nameshake) {
if (nameshake.removed) {
alertify.notify(
_("A suitcase exist with this name exist in the trash."),
"error",
5
);
} else {
alertify.notify(
_("A suitcase with this name already exist!"),
"error",
5
);
}
return;
}
var scase = scases.renameSCase($("#cats").data("scase"), name);
if (scase) {
scases.save();
show_scase(scase);
auto_sync_local_data();
} else {
alertify.notify(
_("An error occurred renaming this suitcase."),
"error",
5
);
}
}
$("#rename_scase_modal").modal("hide");
};
on_show_rename_scase_modal = function () {
$("#rename_scase_name").focus();
};
on_close_rename_scase_modal = function () {
$("#rename_scase_modal form")[0].reset();
};
/***********************
* Copy scase
**********************/
on_copy_scase_btn_click = function (event) {
navbar_collapse_hide();
$("#copy_scase_modal").modal("show");
};
on_valid_copy_scase_modal = function (e) {
e.preventDefault();
var name = $("#copy_scase_name")[0].value;
if (name == "") {
alertify.notify(_("You have to enter the new suitcase name."), "error", 5);
return;
}
var nameshake = scases.byName(name);
if (nameshake) {
if (nameshake.removed) {
alertify.notify(
_("A suitcase exist with this name exist in the trash."),
"error",
5
);
} else {
alertify.notify(
_("A suitcase with this name already exist!"),
"error",
5
);
}
return;
}
var scase = scases.copySCase($("#cats").data("scase"), name);
if (scase) {
scases.save();
show_scase(scase);
auto_sync_local_data();
} else {
alertify.notify(_("An error occurred copying the suitcase."), "error", 5);
}
$("#copy_scase_modal").modal("hide");
};
on_show_copy_scase_modal = function () {
$("#copy_scase_name").focus();
};
on_close_copy_scase_modal = function () {
$("#copy_scase_modal form")[0].reset();
};
/***********************
* Reset scase
**********************/
on_reset_scase_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
alertify.confirm(
_("Reset the %s suitcase", scase.name),
_("Are-you sure you want to reset the suitcase %s?", scase.name),
function (data) {
scases.resetSCase(scase.name);
scases.save();
show_scase(scase);
auto_sync_local_data();
},
null
);
}
};
/***********************
* Delete scase
**********************/
on_delete_scase_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
alertify.confirm(
_("Delete the %s suitcase", scase.name),
_("Are-you sure you want to delete the suitcase %s?", scase.name),
function (data) {
scases.removeSCase(scase.name);
scases.save();
show_scases();
auto_sync_local_data();
},
null
);
}
};
on_restore_scase_btn_click = function (event) {
navbar_collapse_hide();
var scase = event.data.scase;
if (scase) {
alertify.confirm(
_("Restaure the %s suitcase", scase.name),
_("Are-you sure you want to restaure the suitcase %s?", scase.name),
function (data) {
scase.restore();
scases.save();
show_scases();
},
null
);
}
};
on_scase_trash_btn_click = function (event) {
event.preventDefault();
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
show_scase_trash(scase);
}
};
/***********************
* Add cat
**********************/
on_add_cat_btn_click = function (event) {
navbar_collapse_hide();
$("#add_cat_modal").modal("show");
};
on_valid_add_cat_modal = function (e) {
e.preventDefault();
var name = $("#add_cat_name")[0].value;
if (name == "") {
alertify.notify(_("You have to enter the category name!"), "error", 5);
return;
}
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var nameshake = scase.cats.byName(name);
if (nameshake) {
if (nameshake.removed) {
alertify.notify(
_("A category with this name already exist in the trash!"),
"error",
5
);
} else {
alertify.notify(
_("A category with this name already exist!"),
"error",
5
);
}
return;
}
var cat = scase.cats.newCat(name);
if (cat) {
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
}
}
$("#add_cat_modal").modal("hide");
};
on_show_add_cat_modal = function () {
$("#add_cat_name").focus();
};
on_close_add_cat_modal = function () {
$("#add_cat_modal form")[0].reset();
};
/***********************
* Rename cat
**********************/
on_rename_cat_btn_click = function (event) {
navbar_collapse_hide();
$("#rename_cat_modal").data("cat", event.data.cat.name);
$("#rename_cat_name")[0].value = event.data.cat.name;
$("#rename_cat_modal").modal("show");
};
on_valid_rename_cat_modal = function (e) {
e.preventDefault();
var name = $("#rename_cat_name")[0].value;
if (name == "") {
alertify.notify(
_("You have to enter the new name of the category!"),
"error",
5
);
return;
}
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
if (scase.cats.byName(name)) {
var namesake = scase.cats.byName(name);
if (namesake.removed) {
alertify.notify(
_("A category with this name already exist in the trash!"),
"error",
5
);
} else {
alertify.notify(_("A category with this name already!"), "error", 5);
}
return;
}
var cat = scase.cats.renameCat($("#rename_cat_modal").data("cat"), name);
if (cat) {
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
}
}
$("#rename_cat_modal").modal("hide");
};
on_show_rename_cat_modal = function () {
$("#rename_cat_name").focus();
};
on_close_rename_cat_modal = function () {
$("#rename_cat_modal form")[0].reset();
};
/***********************
* Delete cat
**********************/
on_delete_cat_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = event.data.cat.name;
alertify.confirm(
_("Delete the category %s", cat),
_("Are-you sure you want to delete the category %s?", cat),
function (data) {
scase.cats.removeCat(cat);
scases.save();
show_scase(scase);
auto_sync_local_data();
},
null
);
}
};
on_restore_cat_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = event.data.cat.name;
alertify.confirm(
_("Restore the category %s", cat),
_("Are-you sure you want to restore the category %s?", cat),
function (data) {
scase.cats.restoreCat(cat);
scases.save();
show_scase(scase);
auto_sync_local_data();
},
null
);
}
};
/************************
* Check/Uncheck thing
***********************/
on_li_click = function (event) {
if (event.target.tagName != "LI") return;
var li = $(this);
var ul = li.parent();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = scase.cats.byName(ul.data("cat"));
if (cat) {
var thing = cat.byLabel(li.data("label"));
if (thing) {
li.toggleClass("checked");
thing.setChecked(li.hasClass("checked"));
scases.save();
auto_sync_local_data();
}
show_scase(scase, cat.name);
}
}
};
/***********************
* Add thing
**********************/
on_li_add_click = function (event) {
var li = $(this);
var cat = li.parent().data("cat");
var modal = $("#add_thing_modal");
modal.data("cat", cat);
modal.modal("show");
};
on_valid_add_thing_modal = function (e) {
e.preventDefault();
var modal = $("#add_thing_modal");
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = scase.cats.byName(modal.data("cat"));
if (cat) {
var things = [];
var labels = [];
var error = false;
var add_thing_nbs = $("input.add_thing_nb");
$("input.add_thing_label").each(function (idx, input) {
var label = $(input).val();
if (label && label != "") {
if (labels.indexOf(label) > -1) {
alertify.notify(
_("Tow elements can't have the same name!"),
"error",
5
);
error = true;
return;
}
if (cat.byLabel(label)) {
alertify.notify(_("The element '%s' already exist!"), "error", 5);
error = true;
return;
}
var nb = 1;
if (add_thing_nbs[idx]) {
nb = parseInt($(add_thing_nbs[idx]).val());
if (!nb || nb == 0) {
nb = 1;
}
}
things.push({
label: label,
nb: nb,
});
labels.push(label);
}
});
if (error) {
return;
}
if (things.length == 0) {
alertify.notify(
_("You have to enter at least one element name!"),
"error",
5
);
return;
}
for (idx in things) {
cat.newThing(things[idx]["label"], things[idx]["nb"]);
}
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
}
}
modal.modal("hide");
};
on_show_add_thing_modal = function () {
$(".add_thing_other").remove();
$("input.add_thing_label").val("");
$("input.add_thing_nb").val("");
$("input.add_thing_label").first().focus();
};
on_close_add_thing_modal = function () {
$("#add_thing_modal form")[0].reset();
};
on_add_thing_label_focus = function (event) {
if ($("input.add_thing_label").last()[0] == event.target) {
var new_input_group = $('<div class="form-group add_thing_other"></div>');
var new_input_label = $(
`<input type="text" class="form-control add_thing_label" placeholder="${_(
"Another?"
)}"/>`
);
var new_input_nb = $(
`<input type="number" class="form-control add_thing_nb" placeholder="${_(
"Nb"
)}"/>`
);
new_input_group.append(new_input_label);
new_input_group.append(" ");
new_input_group.append(new_input_nb);
new_input_label.bind("focus", on_add_thing_label_focus);
$(event.target).parent().after(new_input_group);
}
};
/***********************
* Edit thing
**********************/
on_edit_thing_btn_click = function (event) {
navbar_collapse_hide();
$("#edit_thing_modal").data("cat", event.data.cat.name);
$("#edit_thing_modal").data("thing", event.data.thing.label);
$("#edit_thing_label").val(event.data.thing.label);
$("#edit_thing_nb").val(event.data.thing.nb);
$("#edit_thing_modal").modal("show");
};
on_valid_edit_thing_modal = function (e) {
e.preventDefault();
var label = $("#edit_thing_label").val();
if (label == "") {
alertify.notify(_("You have to enter the new element name!"), "error", 5);
return;
}
var nb = parseInt($("#edit_thing_nb").val());
if (!nb || nb == 0) {
nb = 1;
}
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = scase.cats.byName($("#edit_thing_modal").data("cat"));
if (cat) {
if (label != $("#edit_thing_modal").data("thing")) {
var namesake = cat.byLabel(label);
if (namesake) {
if (namesake.removed) {
alertify.notify(
_("An element with this name already exist in the trash!"),
"error",
5
);
} else {
alertify.notify(
_("An element with this name already exist!"),
"error",
5
);
}
return;
}
var thing = cat.renameThing(
$("#edit_thing_modal").data("thing"),
label
);
} else {
var thing = cat.byLabel(label);
}
if (thing) {
thing.setNb(nb);
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
}
}
}
$("#edit_thing_modal").modal("hide");
};
on_show_edit_thing_modal = function () {
$("#edit_thing_label").focus();
};
on_close_edit_thing_modal = function () {
$("#edit_thing_modal form")[0].reset();
};
/***********************
* Delete thing
**********************/
on_delete_thing_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = scase.cats.byName(event.data.cat.name);
if (cat) {
var thing = event.data.thing.label;
alertify.confirm(
_("Delete the element %s", thing),
_("Are-you sure you want to delete the element %s?", thing),
function (data) {
cat.removeThing(thing);
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
},
null
);
}
}
};
on_restore_thing_btn_click = function (event) {
navbar_collapse_hide();
var scase = scases.byName($("#cats").data("scase"));
if (scase) {
var cat = scase.cats.byName(event.data.cat.name);
if (cat) {
var thing = event.data.thing.label;
alertify.confirm(
_("Restore the element %s", thing),
_("Are-you sure you want to restore the element %s?", thing),
function (data) {
cat.restoreThing(thing);
scases.save();
show_scase(scase, cat.name);
auto_sync_local_data();
},
null
);
}
}
};
/********************
* Show one scase
*******************/
show_cat = function (scase, cat, displayed) {
var panel = $('<div class="panel panel-default"></div>');
var panel_heading = $('<div class="panel-heading" role="tab"></div>');
var panel_title = $(`<h4 class="panel-title">${cat.name}</h4>`);
panel_title.data("scase", scase);
panel_title.data("cat", cat);
panel_title.bind("click", on_title_click);
var stats = cat.stats();
var tag = $('<span class="count-tag pull-right"></span>');
if (stats.things == stats.done) {
tag.append(
$(
'<span class="label label-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></span>'
)
);
} else {
tag.append($(`<span class="badge">${stats.done} / ${stats.things}</span>`));
}
var delete_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-trash"></button>'
);
delete_btn.bind("click", { cat: cat }, on_delete_cat_btn_click);
tag.append(delete_btn);
var rename_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-edit"></button>'
);
rename_btn.bind("click", { cat: cat }, on_rename_cat_btn_click);
tag.append(rename_btn);
panel_title.append(tag);
panel_heading.append(panel_title);
panel.append(panel_heading);
var panel_collapse = $(
'<div class="panel-collapse collapse" role="tabpanel"></div>'
);
if (displayed) {
panel_collapse.addClass("in");
}
var ul = $(`<ul class="list-group" data-cat="${cat.name}"></ul>`);
for (idx in cat.things) {
if (cat.things[idx].removed) {
continue;
}
var li = $(
`<li class="list-group-item checkable" data-label="${cat.things[idx].label}">` +
`${cat.things[idx].label}</li>`
);
if (cat.things[idx].nb > 1) {
li.append(` <em>(${cat.things[idx].nb})</em>`);
}
if (cat.things[idx].checked) {
li.addClass("checked");
}
li.bind("click", on_li_click);
var li_actions = $('<span class="actions pull-right"></span>');
var delete_el_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-trash"></button>'
);
delete_el_btn.bind(
"click",
{ cat: cat, thing: cat.things[idx] },
on_delete_thing_btn_click
);
li_actions.append(delete_el_btn);
var edit_el_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-edit"></button>'
);
edit_el_btn.bind(
"click",
{ cat: cat, thing: cat.things[idx] },
on_edit_thing_btn_click
);
li_actions.append(edit_el_btn);
li.append(li_actions);
ul.append(li);
}
var li = $(
`<li class="list-group-item"><span class="glyphicon glyphicon-plus-sign"></span> ${_(
"Add an element"
)}</li>`
);
li.bind("click", on_li_add_click);
ul.append(li);
panel_collapse.append(ul);
panel.append(panel_collapse);
$("#cats").append(panel);
};
show_scase = function (scase, display_cat) {
clear_page(
`<h3><span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span> ${scase.name}</h3>` +
`<div class="panel-group" id="cats" role="tablist" aria-multiselectable="true" data-scase="${scase.name}"></div>`
);
scase.cats.each(function (idx, cat) {
if (cat.removed) {
return;
}
show_cat(scase, cat, cat.name == display_cat);
});
set_location(scase.name, display_cat);
show_menu("scase");
};
on_back_to_scases_btn_click = function (e) {
e.preventDefault();
navbar_collapse_hide();
show_scases();
};
/********************
* Show scase trash
*******************/
show_scase_trash = function (scase, display_cat) {
clear_page(
`<h3><span class="glyphicon glyphicon-trash" aria-hidden="true"></span> ${
scase.name
} - ${_("Trash")}` +
' <button class="btn btn-default btn-xs" id="back_btn"><span class="glyphicon glyphicon-arrow-left"></button>' +
`</h3><div class="panel-group" id="cats" role="tablist" aria-multiselectable="true" data-scase="${scase.name}"></div>`
);
$("#content h3 #back_btn").bind("click", { scase: scase }, function (event) {
show_scase(event.data.scase);
});
scase.cats.each(function (idx, cat) {
show_cat_trash(scase, cat, cat.name == display_cat);
});
if ($("#cats .panel").length == 0) {
$("#content").append(`<p class="center">${_("The trash is empty.")}</p>`);
}
set_location(scase.name, display_cat, "trash");
show_menu("scase");
};
show_cat_trash = function (scase, cat, displayed) {
var panel = $('<div class="panel panel-default"></div>');
var panel_heading = $('<div class="panel-heading" role="tab"></div>');
var panel_title = $(`<h4 class="panel-title">${cat.name}</h4>`);
panel_title.data("scase", scase);
panel_title.data("cat", cat);
panel_title.data("trash", true);
var tag = $('<span class="count-tag pull-right"></span>');
panel_title.append(tag);
panel_heading.append(panel_title);
panel.append(panel_heading);
if (cat.removed) {
var stats = cat.stats();
tag.append($(`<span class="badge">${stats.things}</span>`));
var restore_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-ok"></button>'
);
restore_btn.bind("click", { cat: cat }, on_restore_cat_btn_click);
tag.append(restore_btn);
} else {
var deleted_things = [];
for (idx in cat.things) {
if (cat.things[idx].removed) {
deleted_things.push(cat.things[idx]);
}
}
if (deleted_things.length == 0) {
return true;
}
panel_title.bind("click", on_title_click);
tag.append($(`<span class="badge">${deleted_things.length}</span>`));
var panel_collapse = $(
'<div class="panel-collapse collapse" role="tabpanel"></div>'
);
if (displayed) {
panel_collapse.addClass("in");
}
var ul = $(`<ul class="list-group" data-cat="${cat.name}"></ul>`);
for (idx in deleted_things) {
var li = $(
`<li class="list-group-item" data-label="${deleted_things[idx].label}">${deleted_things[idx].label}</li>`
);
var li_actions = $('<span class="actions pull-right"></span>');
var restore_el_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-ok"></button>'
);
restore_el_btn.bind(
"click",
{ cat: cat, thing: deleted_things[idx] },
on_restore_thing_btn_click
);
li_actions.append(restore_el_btn);
li.append(li_actions);
ul.append(li);
}
panel_collapse.append(ul);
panel.append(panel_collapse);
}
$("#cats").append(panel);
};
on_back_to_scase_btn_click = function (e) {
e.preventDefault();
navbar_collapse_hide();
show_scase(e.data.scase);
};
/********************
* Show scases
*******************/
show_scases = function () {
clear_page(
`<h3>${_("Your suitcases")}</h3><ul class="list-group" id="scases"></ul>`
);
scases.each(function (idx, scase) {
if (scase.removed) {
return;
}
var stats = scase.stats();
var tag = '<span class="count-tag pull-right">';
if (stats.things == stats.done) {
tag +=
'<span class="label label-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></span>';
} else {
tag += `<span class="badge">${stats.done} / ${stats.things}</span>`;
}
tag += "</span>";
var li = $(
`<li class="list-group-item" data-name="${scase.name}"><span class="scase-name">` +
'<span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span> ' +
`${scase.name}</span>${tag}</li>`
);
li.bind("click", on_scase_click);
$("#scases").append(li);
});
set_location();
show_menu("scases");
};
on_scase_click = function (event) {
var li = $(this);
var scase = scases.byName(li.data("name"));
show_scase(scase);
};
/********************
* Show scases trash
*******************/
show_scases_trash = function () {
clear_page(
`<h3>${_("Trash")} <button class="btn btn-default btn-xs" id="back_btn">` +
'<span class="glyphicon glyphicon-arrow-left"></button></h3>' +
'<ul class="list-group" id="scases"></ul>'
);
$("#content h3 #back_btn").bind("click", function (event) {
show_scases();
});
scases.each(function (idx, scase) {
if (!scase.removed) {
return;
}
var stats = scase.stats();
var tags = $('<span class="count-tag pull-right"></span>');
tags.append(`<span class="badge">${stats.things}</span>`);
var restore_btn = $(
'<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-ok"></button>'
);
restore_btn.bind("click", { scase: scase }, on_restore_scase_btn_click);
tags.append(restore_btn);
var li = $(
`<li class="list-group-item" data-name="${scase.name}"><span class="scase-name">` +
'<span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span> ' +
`${scase.name}</span></li>`
);
li.append(tags);
$("#scases").append(li);
});
if ($("#scases li").length == 0) {
$("#content").append(
`<p class="center">${_("No suitcase in the trash.")}</p>`
);
}
show_menu("scases");
};
on_scases_trash_btn = function (e) {
e.preventDefault();
navbar_collapse_hide();
show_scases_trash();
};
clear_page = function (new_content) {
if (new_content) {
$("#content").html(new_content);
} else {
$("#content").html("");
}
};
/************************
* Show menu
***********************/
show_menu = function (menu) {
$(".menu").css("display", "none");
$(`.menu-${menu}`).css("display", "block");
};
/*******************
* pleaseWaitDialog
*******************/
pleaseWaitShow = function () {
$("#please_wait_modal").modal("show");
};
pleaseWaitHide = function () {
$("#please_wait_modal").modal("hide");
};
/****************
* Nav bars
****************/
navbar_collapse_hide = function () {
if ($("#navbar-top-collapse").hasClass("in")) {
$("#navbar-top-collapse").collapse("hide");
}
};
/********************
* Clear local data
********************/
clear_local_data = function () {
navbar_collapse_hide();
alertify.confirm(
_("Delete all local data"),
_("Are-you sure you want to delete all local data (irreversible action)?"),
on_confirm_clear_local_data,
null
);
};
on_confirm_clear_local_data = function (data) {
delete localStorage.scases;
location.reload();
};
/********************
* Clear local data
********************/
load_example_data = function () {
navbar_collapse_hide();
alertify.confirm(
_("Loading example data"),
_(
"Are-you sure you want to load example data in place of your own local data (irreversible action)?"
),
function () {
delete localStorage.scases;
scases = new SCaseList();
scases.importExampleData();
scases.save();
show_scases();
},
null
);
};
/*******************************
* Import/Export local data
*******************************/
export_local_data = function () {
navbar_collapse_hide();
$("#export_local_data").attr(
"href",
`data:application/json;base64,${btoa(JSON.stringify(scases.export()))}`
);
};
import_local_data = function () {
navbar_collapse_hide();
var input = $('<input type="file" accept="application/json">');
input.css("display", "none");
input.bind("change", { input: input }, function (e) {
pleaseWaitShow();
var input = e.data.input;
var file = input.prop("files")[0];
if (file) {
var reader = new FileReader();
$(reader).bind("load", function (e) {
if (
$.type(e.target.result) != "string" ||
!e.target.result.startsWith("data:application/json;base64,")
) {
pleaseWaitHide();
alertify.notify("Fichier.", "error", 5);
return;
}
try {
json_data = atob(
e.target.result.replace("data:application/json;base64,", "")
);
data = JSON.parse(json_data);
} catch (e) {
pleaseWaitHide();
alertify.notify(_("Failed to decode JSON file."), "error", 5);
return;
}
pleaseWaitHide();
alertify.confirm(
_("Import from file"),
_(
"Are-you sure you want to overwrite your local data with the data from this file (irreversible action)?"
),
function () {
var backData = scases.export();
scases = new SCaseList();
if (scases.loadFromJsonData(data)) {
alertify.notify(
_("The file has been imported successfully."),
"success",
3
);
} else {
alertify.notify(
_(
"An error occurred loading this file. Restoring previous data..."
),
"error",
5
);
if (scases.loadFromJsonData(backData)) {
alertify.notify(
_("Previous data has been restored successfully."),
"success",
5
);
} else {
alertify.notify(
_("An error occurred restoring previous data."),
"error",
5
);
}
}
show_scases();
},
null
);
});
reader.readAsDataURL(file);
}
});
$("body").append(input);
input[0].click();
};
/******************************
* Authentication
******************************/
show_user = function () {
if (user.connected()) {
$("#login").parent().css("display", "none");
$("#logout").parent().css("display", "block");
$("#username").html(user.name);
} else {
$("#login").parent().css("display", "block");
$("#logout").parent().css("display", "none");
$("#username").html("");
}
};
on_login_button_click = function () {
if (user.connected()) return;
navbar_collapse_hide();
$("#login_modal").modal("show");
};
on_valid_login_modal = function (e) {
e.preventDefault();
var username = $("#login_username").val();
var password = $("#login_password").val();
if (!username || !password) {
alertify.notify(
_("You have to enter your username and password!"),
"error",
5
);
return;
}
$.post("login", {
username: username,
password: password,
})
.done(function (data) {
if (data.username && data.token) {
user.token = data.token;
user.username = data.username;
user.name = data.name ? data.name : username;
user.save();
$("#login_modal").modal("hide");
show_user();
alertify.notify(_("Connected."), "success", 3);
propose_sync_local_data();
} else {
alertify.notify(_("Invalid username or password."), "error", 5);
}
})
.fail(function () {
alertify.notify(
_("An error occurred logging in. Please try again later."),
"error",
5
);
});
};
on_show_login_modal = function () {
$("#login_username").val(user.username || "");
if (user.username) $("#login_password").focus();
else $("#login_username").focus();
};
on_close_login_modal = function () {
$("#login_modal form")[0].reset();
};
on_logout_button_click = function () {
if (!user.connected()) return;
navbar_collapse_hide();
alertify.confirm(
_("Logout"),
_("Do you really want to log out?"),
function (data) {
$.post("logout", {
username: user.username,
token: user.token,
})
.done(function (data) {
if (data.success) {
user.reset();
user.save();
show_user();
alertify.notify(_("Logged out"), "success", 3);
} else {
alertify.notify(
_("An error occurred logging you out. Please try again later."),
"error",
5
);
}
})
.fail(function () {
alertify.notify(
_("An error occurred logging you out. Please try again later."),
"error",
5
);
});
},
null
);
};
is_connected = function () {
return user && user.token;
};
/*******************************
* Sync local data with server
*******************************/
sync_local_data = function (callback) {
if (!is_connected()) {
if (callback) callback(false);
return;
}
$.post("sync", {
username: user.username,
token: user.token,
data: JSON.stringify(scases.export()),
})
.done(function (data) {
if (data.scases) {
var backData = scases.export();
scases = new SCaseList();
if (scases.loadFromJsonData(data)) {
scases.save();
alertify.notify(_("Data synchronized."), "success", 3);
if (callback) callback(true);
} else {
alertify.notify(
_(
"An error occurred loading data from the server. Restoring previous data..."
),
"error",
5
);
if (scases.loadFromJsonData(backData)) {
alertify.notify(
_("Previous data has been restored successfully."),
"success",
5
);
} else {
alertify.notify(
_("An error occurred restoring previous data."),
"error",
5
);
}
if (callback) callback(false);
}
} else {
alertify.notify(
_(
"An error occurred synchronizing your data. Please try again later."
),
"error",
5
);
if (callback) callback(false);
}
})
.fail(function (xhr, status, error) {
if (xhr.status == 401) {
user.token = null;
user.save();
show_user();
alertify.notify(
_("Your session appears to have expired, please re-authenticate."),
"error",
8
);
$("#login_modal").modal("show");
} else {
alertify.notify(
_(
"An error occurred synchronizing your data. Please try again later."
),
"error",
5
);
}
if (callback) callback(false);
});
};
_auto_sync_timeout = false;
auto_sync_local_data = function () {
if (_auto_sync_timeout) clearTimeout(_auto_sync_timeout);
if (!is_connected() || !navigator.onLine) return;
_auto_sync_timeout = setTimeout(sync_local_data, 3000);
};
on_sync_local_data_btn_click = function () {
navbar_collapse_hide();
if (!is_connected()) {
alertify.notify(
_("You must sign in before you can sync your data."),
"error",
5
);
$("#login_modal").modal("show");
return;
}
pleaseWaitShow();
sync_local_data(function (success) {
pleaseWaitHide();
refresh_location();
});
};
propose_sync_local_data = function () {
alertify.confirm(
_("Synchronize your suitcases from server"),
_("Are-you sure you want to synchronize your suitcases from server?"),
function () {
pleaseWaitShow();
sync_local_data(function (success) {
pleaseWaitHide();
if (!success) return;
if (scases.count() == 0) propose_example_data();
else refresh_location();
});
},
refresh_location
);
};
/***********************
* Manage location hash
***********************/
set_location = function (scase, cat, detail) {
console.log(`set_location(${scase}, ${cat}, ${detail})`);
var parts = [];
if (scase) parts[0] = scase;
if (cat) parts[1] = cat;
if (detail) parts[2] = detail;
location.hash = parts.join("|");
};
parse_location = function (value) {
value = typeof value == "undefined" ? location.hash : value;
console.log(`parse_location(${value})`);
parts = (typeof value == "undefined" ? location.hash : value).split("|");
return {
scase: parts[0] ? decodeURI(parts[0].substring(1)) : null,
cat: parts[0] && parts[1] ? decodeURI(parts[1]) : null,
detail: parts[2] ? decodeURI(parts[2]) : null,
};
};
refresh_location = function () {
var info = parse_location();
console.log(`refresh_location(${info.scase}, ${info.cat}, ${info.detail})`);
var scase = info.scase ? scases.byName(info.scase) : null;
if (!scase) show_scases();
else if (info.detail == "trash") show_scase_trash(scase, info.cat);
else show_scase(scase, info.cat);
};
/***********************
* Welcome modal
***********************/
on_welcome_connect_click = function () {
$("#welcome_modal").modal("hide");
$("#login_modal").modal("show");
};
on_welcome_annonymous_click = function () {
$("#welcome_modal").modal("hide");
if (scases.count() == 0) propose_example_data();
};
propose_example_data = function () {
alertify.confirm(
_("An example of a suitcase?"),
_("Would you like to load a sample suitcase to get started?"),
function () {
scases.importExampleData();
scases.save();
refresh_location();
},
null
);
};
/**************************
* Cache / Update
*************************/
_check_for_update = false;
on_update_ready = function () {
if (_check_for_update) pleaseWaitHide();
alertify.confirm(
_("Update available"),
_(
"An update of the application is available. Do-you want-to update it now?"
),
on_confirm_update,
null
);
};
on_confirm_update = function () {
window.applicationCache.swapCache();
location.reload();
};
update_app = function () {
navbar_collapse_hide();
pleaseWaitShow();
_check_for_update = true;
window.applicationCache.update();
};
on_no_update = function () {
if (!_check_for_update) return;
pleaseWaitHide();
_check_for_update = false;
alertify.notify(_("No available update."), "success", 3);
};
/*********************
* Activate
*********************/
$(document).ready(function () {
if (typeof localStorage === "undefined") {
alertify.notify(
_(
"Your internet browser does not support local data storage. Therefore, unfortunately you cannot use this application."
),
"error",
5
);
return;
}
pleaseWaitShow();
$("#clear_local_data").bind("click", clear_local_data);
$("#load_example_data").bind("click", load_example_data);
$("#import_local_data").bind("click", import_local_data);
$("#export_local_data").bind("click", export_local_data);
$("#sync_local_data").bind("click", on_sync_local_data_btn_click);
$("#add_scase_btn").bind("click", on_add_scase_btn_click);
$("#add_scase_submit").bind("click", on_valid_add_scase_modal);
$("#add_scase_modal").on("shown.bs.modal", on_show_add_scase_modal);
$("#add_scase_modal").on("hidden.bs.modal", on_close_add_scase_modal);
$("#add_scase_modal form").bind("submit", on_valid_add_scase_modal);
$("#scases_trash_btn").bind("click", on_scases_trash_btn);
$("#rename_scase_btn").bind("click", on_rename_scase_btn_click);
$("#rename_scase_submit").bind("click", on_valid_rename_scase_modal);
$("#rename_scase_modal").on("shown.bs.modal", on_show_rename_scase_modal);
$("#rename_scase_modal").on("hidden.bs.modal", on_close_rename_scase_modal);
$("#rename_scase_modal form").bind("submit", on_valid_rename_scase_modal);
$("#copy_scase_btn").bind("click", on_copy_scase_btn_click);
$("#copy_scase_submit").bind("click", on_valid_copy_scase_modal);
$("#copy_scase_modal").on("shown.bs.modal", on_show_copy_scase_modal);
$("#copy_scase_modal").on("hidden.bs.modal", on_close_copy_scase_modal);
$("#copy_scase_modal form").bind("submit", on_valid_copy_scase_modal);
$("#reset_scase_btn").bind("click", on_reset_scase_btn_click);
$("#delete_scase_btn").bind("click", on_delete_scase_btn_click);
$("#scase_trash_btn").bind("click", on_scase_trash_btn_click);
$("#add_cat_btn").bind("click", on_add_cat_btn_click);
$("#add_cat_submit").bind("click", on_valid_add_cat_modal);
$("#add_cat_modal").on("shown.bs.modal", on_show_add_cat_modal);
$("#add_cat_modal").on("hidden.bs.modal", on_close_add_cat_modal);
$("#add_cat_modal form").bind("submit", on_valid_add_cat_modal);
$("#rename_cat_submit").bind("click", on_valid_rename_cat_modal);
$("#rename_cat_modal").on("shown.bs.modal", on_show_rename_cat_modal);
$("#rename_cat_modal").on("hidden.bs.modal", on_close_rename_cat_modal);
$("#rename_cat_modal form").bind("submit", on_valid_rename_cat_modal);
$("#back_to_scases").bind("click", on_back_to_scases_btn_click);
$("input.add_thing_label").bind("focus", on_add_thing_label_focus);
$("#add_thing_submit").bind("click", on_valid_add_thing_modal);
$("#add_thing_modal").on("shown.bs.modal", on_show_add_thing_modal);
$("#add_thing_modal").on("hidden.bs.modal", on_close_add_thing_modal);
$("#add_thing_modal form").bind("submit", on_valid_add_thing_modal);
$("#edit_thing_submit").bind("click", on_valid_edit_thing_modal);
$("#edit_thing_modal").on("shown.bs.modal", on_show_edit_thing_modal);
$("#edit_thing_modal").on("hidden.bs.modal", on_close_edit_thing_modal);
$("#edit_thing_modal form").bind("submit", on_valid_edit_thing_modal);
$("#login").bind("click", on_login_button_click);
$("#logout").bind("click", on_logout_button_click);
$("#login_submit").bind("click", on_valid_login_modal);
$("#login_modal").on("shown.bs.modal", on_show_login_modal);
$("#login_modal").on("hidden.bs.modal", on_close_login_modal);
$("#login_modal form").bind("submit", on_valid_login_modal);
$("#welcome_connect").bind("click", on_welcome_connect_click);
$("#welcome_annonymous").bind("click", on_welcome_annonymous_click);
$("#app-name").bind("click", show_scases);
user = new User();
user.loadFromLocalStorage();
show_user();
scases = new SCaseList();
switch (scases.loadFromLocalStorage()) {
case null:
pleaseWaitHide();
if (is_connected()) propose_sync_local_data();
else $("#welcome_modal").modal("show");
break;
case false:
alertify.confirm(
_("Error loading local data"),
_("An error occurred while loading local data. Should we purge it?"),
function (data) {
delete localStorage.scases;
location.reload();
},
function (data) {
pleaseWaitHide();
location.reload();
}
);
break;
case true:
refresh_location();
pleaseWaitHide();
break;
}
if (
!window.applicationCache ||
window.applicationCache.status == window.applicationCache.UNCACHED
) {
$("#update_app").parent().remove();
} else {
$("#update_app").bind("click", update_app);
window.applicationCache.addEventListener("updateready", on_update_ready);
window.applicationCache.addEventListener("noupdate", on_no_update);
if (window.applicationCache.status === window.applicationCache.UPDATEREADY)
on_update_ready();
}
});