diff --git a/js/configs/datatable.js b/js/configs/datatable.js
index fbe68753..bfa9f922 100644
--- a/js/configs/datatable.js
+++ b/js/configs/datatable.js
@@ -7,7 +7,7 @@ function setDatatableDefaults(Grocy)
$.extend(true, $.fn.dataTable.defaults, {
'paginate': false,
'deferRender': true,
- 'language': IsJsonString(__t('datatables_localization')) ? JSON.parse(__t('datatables_localization')) : {},
+ 'language': IsJsonString(Grocy.translate('datatables_localization')) ? JSON.parse(Grocy.translate('datatables_localization')) : {},
'scrollY': false,
'scrollX': true,
'colReorder': true,
@@ -34,7 +34,7 @@ function setDatatableDefaults(Grocy)
Grocy.FrontendHelpers.SaveUserSetting(settingKey, stateData);
}
},
- 'stateLoadCallback': function(settings, data)
+ 'stateLoadCallback': function(settings)
{
var settingKey = 'datatables_state_' + settings.sTableId;
diff --git a/js/configs/globalstate.js b/js/configs/globalstate.js
index a3f45ef8..9ac9f9e5 100644
--- a/js/configs/globalstate.js
+++ b/js/configs/globalstate.js
@@ -1,7 +1,6 @@
import { ResizeResponsiveEmbeds } from "../helpers/embeds";
import { IsTouchInputDevice } from "../helpers/input";
-import { BoolVal } from "../helpers/extensions";
-
+import { BoolVal, GetFileNameFromPath, GetUriParam } from "../helpers/extensions";
// This function sets some global state and adds some global event listeners.
function setInitialGlobalState(Grocy)
@@ -22,7 +21,7 @@ function setInitialGlobalState(Grocy)
$(parentMenuSelector).collapse("show");
$(parentMenuSelector).prev(".nav-link-collapse").addClass("active-page");
- $(parentMenuSelector).on("shown.bs.collapse", function(e)
+ $(parentMenuSelector).on("shown.bs.collapse", function()
{
if (!menuItem.isVisibleInViewport(75))
{
@@ -154,7 +153,7 @@ function setInitialGlobalState(Grocy)
$("#about-dialog-link").on("click", function()
{
bootbox.alert({
- message: '',
+ message: '',
closeButton: false,
size: "large"
});
@@ -216,11 +215,11 @@ function setInitialGlobalState(Grocy)
var base = $(this).data('href');
if (base.contains('?'))
{
- $(this).attr('href', base + '&returnto' + encodeURIComponent(location.pathname));
+ $(this).attr('href', base + '&returnto' + encodeURIComponent(window.location.pathname));
}
else
{
- $(this).attr('href', base + '?returnto=' + encodeURIComponent(location.pathname));
+ $(this).attr('href', base + '?returnto=' + encodeURIComponent(window.location.pathname));
}
})
@@ -232,11 +231,11 @@ function setInitialGlobalState(Grocy)
var link = GetUriParam("returnto");
if (!link || !link.length > 0)
{
- location.href = $(e.currentTarget).attr("href");
+ window.location.href = $(e.currentTarget).attr("href");
}
else
{
- location.href = U(link);
+ window.location.href = Grocy.FormatUrl(link);
}
});
@@ -485,7 +484,7 @@ function setInitialGlobalState(Grocy)
$(document).on("change", "#show-clock-in-header", function()
{
- CheckHeaderClockEnabled();
+ Grocy.HeaderClock.CheckHeaderClockEnabled();
});
if (Grocy.UserId !== -1 && BoolVal(Grocy.UserSettings.auto_reload_on_db_change))
diff --git a/js/configs/timeago.js b/js/configs/timeago.js
index 71222b4a..5929fb21 100644
--- a/js/configs/timeago.js
+++ b/js/configs/timeago.js
@@ -1,3 +1,4 @@
+/* global __t */
function RefreshContextualTimeago(rootSelector = "#page-content")
{
diff --git a/js/grocy.js b/js/grocy.js
index b5073515..a12c5074 100644
--- a/js/grocy.js
+++ b/js/grocy.js
@@ -11,6 +11,7 @@ import { Nightmode } from "./lib/nightmode";
import { HeaderClock } from "./helpers/clock";
import { animateCSS, BoolVal, Delay, EmptyElementWhenMatches, GetUriParam, RemoveUriParam, UpdateUriParam } from "./helpers/extensions";
import Translator from "gettext-translator";
+import { WindowMessageBag } from './helpers/messagebag';
import "./helpers/string";
@@ -48,7 +49,7 @@ class GrocyClass
// Init some classes
this.Api = new GrocyApi(this);
this.Translator = new Translator(config.GettextPo);
- this.FrontendHelpers = new GrocyFrontendHelpers(this.Api);
+ this.FrontendHelpers = new GrocyFrontendHelpers(this, this.Api);
this.WakeLock = new WakeLock(this);
this.UISound = new UISound(this);
this.Nightmode = new Nightmode(this);
@@ -62,7 +63,7 @@ class GrocyClass
{
moment.updateLocale(moment.locale(), {
week: {
- dow: Grocy.CalendarFirstDayOfWeek
+ dow: this.CalendarFirstDayOfWeek
}
});
}
@@ -102,7 +103,7 @@ class GrocyClass
window.onscroll = grocy.ResetIdleTime;
window.onkeypress = grocy.ResetIdleTime;
- window.__t = function(key, ...placeholder) { return grocy.translate(key, ...placeholder) };;
+ window.__t = function(key, ...placeholder) { return grocy.translate(key, ...placeholder) };
window.__n = function(key, ...placeholder) { return grocy.translaten(key, ...placeholder) };
window.U = path => grocy.FormatUrl(path);
@@ -195,10 +196,11 @@ class GrocyClass
UndoStockBooking(bookingId)
{
+ var self = this;
this.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
- function(result)
+ function()
{
- toastr.success(__t("Booking successfully undone"));
+ toastr.success(self.translate("Booking successfully undone"));
},
function(xhr)
{
@@ -209,10 +211,11 @@ class GrocyClass
UndoStockTransaction(transactionId)
{
+ var self = this;
this.Api.Post('stock/transactions/' + transactionId.toString() + '/undo', {},
- function(result)
+ function()
{
- toastr.success(__t("Transaction successfully undone"));
+ toastr.success(self.translate("Transaction successfully undone"));
},
function(xhr)
{
@@ -223,10 +226,11 @@ class GrocyClass
UndoChoreExecution(executionId)
{
+ var self = this;
this.Api.Post('chores/executions/' + executionId.toString() + '/undo', {},
- function(result)
+ function()
{
- toastr.success(__t("Chore execution successfully undone"));
+ toastr.success(self.translate("Chore execution successfully undone"));
},
function(xhr)
{
@@ -237,10 +241,11 @@ class GrocyClass
UndoChargeCycle(chargeCycleId)
{
+ var self = this;
this.Api.Post('batteries/charge-cycles/' + chargeCycleId.toString() + '/undo', {},
- function(result)
+ function()
{
- toastr.success(__t("Charge cycle successfully undone"));
+ toastr.success(self.translate("Charge cycle successfully undone"));
},
function(xhr)
{
@@ -250,18 +255,42 @@ class GrocyClass
}
UndoStockBookingEntry(bookingId, stockRowId)
{
- Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
- function(result)
+ var self = this;
+ this.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
+ function()
{
- window.postMessage(WindowMessageBag("StockEntryChanged", stockRowId), Grocy.BaseUrl);
- toastr.success(__t("Booking successfully undone"));
+ window.postMessage(WindowMessageBag("StockEntryChanged", stockRowId), self.BaseUrl);
+ toastr.success(self.translate("Booking successfully undone"));
},
function(xhr)
{
console.error(xhr);
}
);
- };
+ }
+
+ ScanModeSubmit(singleUnit = true)
+ {
+ if (BoolVal(this.UserSettings.scan_mode_purchase_enabled))
+ {
+ if (singleUnit)
+ {
+ $("#display_amount").val(1);
+ $(".input-group-productamountpicker").trigger("change");
+ }
+
+ this.FrontendHelpers.ValidateForm("purchase-form");
+ if (document.getElementById("purchase-form").checkValidity() === true)
+ {
+ $('#save-purchase-button').click();
+ }
+ else
+ {
+ toastr.warning(this.translate("Scan mode is on but not all required fields could be populated automatically"));
+ this.UISound.Error();
+ }
+ }
+ }
}
// also set on the Window object, just because.
diff --git a/js/helpers/clock.js b/js/helpers/clock.js
index 1ccecfa6..109b0acd 100644
--- a/js/helpers/clock.js
+++ b/js/helpers/clock.js
@@ -30,7 +30,7 @@ class HeaderClock
// Refresh the clock in the header every second when enabled
if (BoolVal(this.Grocy.UserSettings.show_clock_in_header))
{
- RefreshHeaderClock();
+ this.RefreshHeaderClock();
$("#clock-container").removeClass("d-none");
this.HeaderClockInterval = setInterval(this.RefreshHeaderClock, 1000);
diff --git a/js/helpers/embeds.js b/js/helpers/embeds.js
index 0f3fc406..2bae8ac4 100644
--- a/js/helpers/embeds.js
+++ b/js/helpers/embeds.js
@@ -1,12 +1,13 @@
function ResizeResponsiveEmbeds(fillEntireViewport = false)
{
+ var maxHeight = null;
if (!fillEntireViewport)
{
- var maxHeight = $("body").height() - $("#mainNav").outerHeight() - 62;
+ maxHeight = $("body").height() - $("#mainNav").outerHeight() - 62;
}
else
{
- var maxHeight = $("body").height();
+ maxHeight = $("body").height();
}
$("embed.embed-responsive").attr("height", maxHeight.toString() + "px");
diff --git a/js/helpers/extensions.js b/js/helpers/extensions.js
index 55d79f39..87add254 100644
--- a/js/helpers/extensions.js
+++ b/js/helpers/extensions.js
@@ -4,7 +4,7 @@ function EmptyElementWhenMatches(selector, text)
{
$(selector).text('');
}
-};
+}
function GetUriParam(key)
{
@@ -20,21 +20,21 @@ function GetUriParam(key)
return currentParam[1] === undefined ? true : decodeURIComponent(currentParam[1]);
}
}
-};
+}
function UpdateUriParam(key, value)
{
- var queryParameters = new URLSearchParams(location.search);
+ var queryParameters = new URLSearchParams(window.location.search);
queryParameters.set(key, value);
- window.history.replaceState({}, "", decodeURIComponent(`${location.pathname}?${queryParameters}`));
-};
+ window.history.replaceState({}, "", decodeURIComponent(`${window.location.pathname}?${queryParameters}`));
+}
function RemoveUriParam(key)
{
- var queryParameters = new URLSearchParams(location.search);
+ var queryParameters = new URLSearchParams(window.location.search);
queryParameters.delete(key);
- window.history.replaceState({}, "", decodeURIComponent(`${location.pathname}?${queryParameters}`));
-};
+ window.history.replaceState({}, "", decodeURIComponent(`${window.location.pathname}?${queryParameters}`));
+}
function BoolVal(test)
@@ -60,11 +60,6 @@ function GetFileNameFromPath(path)
return path.split("/").pop().split("\\").pop();
}
-function GetFileExtension(pathOrFileName)
-{
- return pathOrFileName.split(".").pop();
-}
-
$.extend($.expr[":"],
{
"contains_case_insensitive": function(elem, i, match, array)
@@ -139,15 +134,6 @@ function RandomString()
return Math.random().toString(36).substring(2, 100) + Math.random().toString(36).substring(2, 100);
}
-Date.prototype.getWeekNumber = function()
-{
- var date = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
- var dayNumber = date.getUTCDay() || 7;
- date.setUTCDate(date.getUTCDate() + 4 - dayNumber);
- var yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
- return Math.ceil((((date - yearStart) / 86400000) + 1) / 7)
-};
-
export
{
RandomString,
@@ -155,7 +141,6 @@ export
Delay,
IsJsonString,
BoolVal,
- GetFileExtension,
GetFileNameFromPath,
RemoveUriParam,
UpdateUriParam,
diff --git a/js/helpers/frontend.js b/js/helpers/frontend.js
index f8bf3299..aa0bcfba 100644
--- a/js/helpers/frontend.js
+++ b/js/helpers/frontend.js
@@ -1,8 +1,9 @@
class GrocyFrontendHelpers
{
- constructor(Api)
+ constructor(Grocy, Api)
{
+ this.Grocy = Grocy;
this.Api = Api;
}
@@ -48,11 +49,11 @@ class GrocyFrontendHelpers
ShowGenericError(message, exception)
{
- toastr.error(__t(message) + '
' + __t('Click to show technical details'), '', {
+ toastr.error(this.Grocy.translate(message) + '
' + this.Grocy.translate('Click to show technical details'), '', {
onclick: function()
{
bootbox.alert({
- title: __t('Error details'),
+ title: this.Grocy.translate('Error details'),
message: '
' + JSON.stringify(exception, null, 4) + '',
closeButton: false
});
@@ -64,7 +65,7 @@ class GrocyFrontendHelpers
SaveUserSetting(settingsKey, value)
{
- Grocy.UserSettings[settingsKey] = value;
+ this.Grocy.UserSettings[settingsKey] = value;
var jsonData = {};
jsonData.value = value;
@@ -84,14 +85,14 @@ class GrocyFrontendHelpers
}
DeleteUserSetting(settingsKey, reloadPageOnSuccess = false)
{
- delete Grocy.UserSettings[settingsKey];
+ delete this.Grocy.UserSettings[settingsKey];
this.Delete('user/settings/' + settingsKey, {},
function(result)
{
if (reloadPageOnSuccess)
{
- location.reload();
+ window.location.reload();
}
},
function(xhr)
@@ -109,14 +110,14 @@ class GrocyFrontendHelpers
Object.assign(data, webhook.extra_data);
var hasAlreadyFailed = false;
- for (i = 0; i < repetitions; i++)
+ for (var i = 0; i < repetitions; i++)
{
$.post(webhook.hook, data).fail(function(req, status, errorThrown)
{
if (!hasAlreadyFailed)
{
hasAlreadyFailed = true;
- this.ShowGenericError(__t("Error while executing WebHook", { "status": status, "errorThrown": errorThrown }));
+ this.ShowGenericError(this.Grocy.translate("Error while executing WebHook", { "status": status, "errorThrown": errorThrown }));
}
});
}
diff --git a/js/helpers/input.js b/js/helpers/input.js
index 75500b50..238392be 100644
--- a/js/helpers/input.js
+++ b/js/helpers/input.js
@@ -1,3 +1,7 @@
+/* global DocumentTouch */
+
+// TODO: DocumentTouch is deprecated
+// https://developer.mozilla.org/en-US/docs/Web/API/DocumentTouch
function IsTouchInputDevice()
{
if (("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch)
diff --git a/js/helpers/numberdisplay.js b/js/helpers/numberdisplay.js
index 99870a56..2867f64f 100644
--- a/js/helpers/numberdisplay.js
+++ b/js/helpers/numberdisplay.js
@@ -1,3 +1,5 @@
+/* global Grocy */
+
function RefreshLocaleNumberDisplay(rootSelector = "#page-content")
{
$(rootSelector + " .locale-number.locale-number-currency").each(function()