mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
348 lines
7.0 KiB
JavaScript
348 lines
7.0 KiB
JavaScript
L = function(text, ...placeholderValues)
|
|
{
|
|
var localizedText = Grocy.LocalizationStrings[text];
|
|
if (localizedText === undefined)
|
|
{
|
|
if (Grocy.Mode === 'dev')
|
|
{
|
|
jsonData = {};
|
|
jsonData.text = text;
|
|
Grocy.Api.Post('system/log-missing-localization', jsonData,
|
|
function(result)
|
|
{
|
|
// Nothing to do...
|
|
},
|
|
function(xhr)
|
|
{
|
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
|
}
|
|
);
|
|
}
|
|
|
|
localizedText = text;
|
|
}
|
|
|
|
for (var i = 0; i < placeholderValues.length; i++)
|
|
{
|
|
localizedText = localizedText.replace('#' + (i + 1), placeholderValues[i]);
|
|
}
|
|
|
|
return localizedText;
|
|
}
|
|
|
|
U = function(relativePath)
|
|
{
|
|
return Grocy.BaseUrl.replace(/\/$/, '') + relativePath;
|
|
}
|
|
|
|
Pluralize = function(number, singularForm, pluralForm)
|
|
{
|
|
var text = singularForm;
|
|
if (number != 1 && pluralForm !== null && !pluralForm.isEmpty())
|
|
{
|
|
text = pluralForm;
|
|
}
|
|
return text;
|
|
}
|
|
|
|
if (!Grocy.ActiveNav.isEmpty())
|
|
{
|
|
var menuItem = $('#sidebarResponsive').find("[data-nav-for-page='" + Grocy.ActiveNav + "']");
|
|
menuItem.addClass('active-page');
|
|
|
|
var parentMenuSelector = menuItem.data("sub-menu-of");
|
|
if (typeof parentMenuSelector !== "undefined")
|
|
{
|
|
$(parentMenuSelector).collapse("show");
|
|
$(parentMenuSelector).prev(".nav-link-collapse").addClass("active-page");
|
|
}
|
|
}
|
|
|
|
var observer = new MutationObserver(function(mutations)
|
|
{
|
|
mutations.forEach(function(mutation)
|
|
{
|
|
if (mutation.attributeName === "class")
|
|
{
|
|
var attributeValue = $(mutation.target).prop(mutation.attributeName);
|
|
if (attributeValue.contains("sidenav-toggled"))
|
|
{
|
|
window.localStorage.setItem("sidebar_state", "collapsed");
|
|
}
|
|
else
|
|
{
|
|
window.localStorage.setItem("sidebar_state", "expanded");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
observer.observe(document.body, {
|
|
attributes: true
|
|
});
|
|
if (window.localStorage.getItem("sidebar_state") === "collapsed")
|
|
{
|
|
$("#sidenavToggler").click();
|
|
}
|
|
|
|
$.timeago.settings.allowFuture = true;
|
|
RefreshContextualTimeago = function()
|
|
{
|
|
$("time.timeago").each(function()
|
|
{
|
|
var element = $(this);
|
|
var timestamp = element.attr("datetime");
|
|
element.timeago("update", timestamp);
|
|
});
|
|
}
|
|
RefreshContextualTimeago();
|
|
|
|
toastr.options = {
|
|
toastClass: 'alert',
|
|
closeButton: true,
|
|
timeOut: 20000,
|
|
extendedTimeOut: 5000
|
|
};
|
|
|
|
window.FontAwesomeConfig = {
|
|
searchPseudoElements: true
|
|
}
|
|
|
|
// Don't show tooltips on touch input devices
|
|
if (IsTouchInputDevice())
|
|
{
|
|
var css = document.createElement("style");
|
|
css.innerHTML = ".tooltip { display: none; }";
|
|
document.body.appendChild(css);
|
|
}
|
|
|
|
Grocy.Api = { };
|
|
Grocy.Api.Get = function(apiFunction, success, error)
|
|
{
|
|
var xhr = new XMLHttpRequest();
|
|
var url = U('/api/' + apiFunction);
|
|
|
|
xhr.onreadystatechange = function()
|
|
{
|
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
|
{
|
|
if (xhr.status === 200)
|
|
{
|
|
if (success)
|
|
{
|
|
success(JSON.parse(xhr.responseText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (error)
|
|
{
|
|
error(xhr);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
xhr.open('GET', url, true);
|
|
xhr.send();
|
|
};
|
|
|
|
Grocy.Api.Post = function(apiFunction, jsonData, success, error)
|
|
{
|
|
var xhr = new XMLHttpRequest();
|
|
var url = U('/api/' + apiFunction);
|
|
|
|
xhr.onreadystatechange = function()
|
|
{
|
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
|
{
|
|
if (xhr.status === 200)
|
|
{
|
|
if (success)
|
|
{
|
|
success(JSON.parse(xhr.responseText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (error)
|
|
{
|
|
error(xhr);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
xhr.open('POST', url, true);
|
|
xhr.setRequestHeader('Content-type', 'application/json');
|
|
xhr.send(JSON.stringify(jsonData));
|
|
};
|
|
|
|
Grocy.Api.UploadFile = function(file, group, fileName, success, error)
|
|
{
|
|
var xhr = new XMLHttpRequest();
|
|
var url = U('/api/file/' + group + '?file_name=' + encodeURIComponent(fileName));
|
|
|
|
xhr.onreadystatechange = function()
|
|
{
|
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
|
{
|
|
if (xhr.status === 200)
|
|
{
|
|
if (success)
|
|
{
|
|
success(JSON.parse(xhr.responseText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (error)
|
|
{
|
|
error(xhr);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
xhr.open('PUT', url, true);
|
|
xhr.setRequestHeader('Content-type', 'application/octet-stream');
|
|
xhr.send(file);
|
|
};
|
|
|
|
Grocy.Api.DeleteFile = function(fileName, group, success, error)
|
|
{
|
|
var xhr = new XMLHttpRequest();
|
|
var url = U('/api/file/' + group + '?file_name=' + encodeURIComponent(fileName));
|
|
|
|
xhr.onreadystatechange = function()
|
|
{
|
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
|
{
|
|
if (xhr.status === 200)
|
|
{
|
|
if (success)
|
|
{
|
|
success(JSON.parse(xhr.responseText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (error)
|
|
{
|
|
error(xhr);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
xhr.open('DELETE', url, true);
|
|
xhr.setRequestHeader('Content-type', 'application/json');
|
|
xhr.send();
|
|
};
|
|
|
|
Grocy.FrontendHelpers = { };
|
|
Grocy.FrontendHelpers.ValidateForm = function(formId)
|
|
{
|
|
var form = document.getElementById(formId);
|
|
if (form.checkValidity() === true)
|
|
{
|
|
$(form).find(':submit').removeClass('disabled');
|
|
}
|
|
else
|
|
{
|
|
$(form).find(':submit').addClass('disabled');
|
|
}
|
|
|
|
$(form).addClass('was-validated');
|
|
}
|
|
|
|
Grocy.FrontendHelpers.ShowGenericError = function(message, exception)
|
|
{
|
|
toastr.error(L(message) + '<br><br>' + L('Click to show technical details'), '', {
|
|
onclick: function()
|
|
{
|
|
bootbox.alert({
|
|
title: L('Error details'),
|
|
message: JSON.stringify(exception, null, 4)
|
|
});
|
|
}
|
|
});
|
|
|
|
console.error(exception);
|
|
}
|
|
|
|
$("form").on("keyup paste", "input, textarea", function()
|
|
{
|
|
$(this).closest("form").addClass("is-dirty");
|
|
});
|
|
$("form").on("click", "select", function()
|
|
{
|
|
$(this).closest("form").addClass("is-dirty");
|
|
});
|
|
|
|
// Auto saving user setting controls
|
|
$(".user-setting-control").on("change", function()
|
|
{
|
|
var element = $(this);
|
|
var settingKey = element.attr("data-setting-key");
|
|
|
|
var inputType = "unknown";
|
|
if (typeof element.attr("type") !== typeof undefined && element.attr("type") !== false)
|
|
{
|
|
inputType = element.attr("type").toLowerCase();
|
|
}
|
|
|
|
if (inputType === "checkbox")
|
|
{
|
|
value = element.is(":checked");
|
|
}
|
|
else
|
|
{
|
|
var value = element.val();
|
|
}
|
|
|
|
Grocy.UserSettings[settingKey] = value;
|
|
|
|
jsonData = { };
|
|
jsonData.value = value;
|
|
Grocy.Api.Post('user/settings/' + settingKey, jsonData,
|
|
function(result)
|
|
{
|
|
// Nothing to do...
|
|
},
|
|
function(xhr)
|
|
{
|
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
|
}
|
|
);
|
|
});
|
|
|
|
// Show file name Bootstrap custom file input
|
|
$('input.custom-file-input').on('change', function()
|
|
{
|
|
$(this).next('.custom-file-label').html(GetFileNameFromPath($(this).val()));
|
|
});
|
|
|
|
// Translation of "Browse"-button of Bootstrap custom file input
|
|
if ($(".custom-file-label").length > 0)
|
|
{
|
|
$("<style>").html('.custom-file-label::after { content: "' + L("Select file") + '"; }').appendTo("head");
|
|
}
|
|
|
|
ResizeResponsiveEmbeds = function(fillEntireViewport = false)
|
|
{
|
|
if (!fillEntireViewport)
|
|
{
|
|
var maxHeight = $("body").height() - $("#mainNav").outerHeight() - 62;
|
|
}
|
|
else
|
|
{
|
|
var maxHeight = $("body").height();
|
|
}
|
|
|
|
$(".embed-responsive").attr("height", maxHeight.toString() + "px");
|
|
}
|
|
$(window).on('resize', function()
|
|
{
|
|
ResizeResponsiveEmbeds($("body").hasClass("fullscreen-card"));
|
|
});
|