mirror of
https://github.com/grocy/grocy.git
synced 2025-08-18 11:27:03 +00:00
Load all frontend packages conditionally
This commit is contained in:
@@ -249,7 +249,14 @@ __t = function(text, ...placeholderValues)
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(Grocy.Translator.__(text, ...placeholderValues), ...placeholderValues);
|
||||
// sprintf can fail due to invalid placeholders
|
||||
try
|
||||
{
|
||||
return sprintf(Grocy.Translator.__(text, ...placeholderValues), ...placeholderValues);
|
||||
} catch (e)
|
||||
{
|
||||
return Grocy.Translator.__(text, ...placeholderValues);
|
||||
}
|
||||
}
|
||||
__n = function(number, singularForm, pluralForm, isQu = false)
|
||||
{
|
||||
@@ -272,13 +279,15 @@ __n = function(number, singularForm, pluralForm, isQu = false)
|
||||
pluralForm = singularForm;
|
||||
}
|
||||
|
||||
number = Math.abs(number);
|
||||
|
||||
if (isQu)
|
||||
{
|
||||
return Grocy.TranslatorQu.n__(singularForm, pluralForm, Math.abs(number), Math.abs(number))
|
||||
return sprintf(Grocy.TranslatorQu.n__(singularForm, pluralForm, number, number), number.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Grocy.Translator.n__(singularForm, pluralForm, Math.abs(number), Math.abs(number))
|
||||
return sprintf(Grocy.Translator.n__(singularForm, pluralForm, number, number), number.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,20 +674,6 @@ $(document).on("click", ".easy-link-copy-textbox", function()
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
$("textarea.wysiwyg-editor").summernote({
|
||||
minHeight: "300px",
|
||||
lang: __t("summernote_locale"),
|
||||
callbacks: {
|
||||
onImageLinkInsert: function(url)
|
||||
{
|
||||
// Summernote workaround: Make images responsive
|
||||
// By adding the "img-fluid" class to the img tag
|
||||
$img = $('<img>').attr({ src: url, class: "img-fluid" })
|
||||
$(this).summernote("insertNode", $img[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Summernote workaround: Make embeds responsive
|
||||
// By wrapping any embeded video in a container with class "embed-responsive"
|
||||
$(".note-video-clip").each(function()
|
||||
@@ -745,128 +740,6 @@ $(document).on("click", ".show-as-dialog-link", function(e)
|
||||
// Init Bootstrap tooltips
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
|
||||
// Default DataTables initialisation settings
|
||||
var collapsedGroups = {};
|
||||
$.extend(true, $.fn.dataTable.defaults, {
|
||||
'paginate': false,
|
||||
'deferRender': true,
|
||||
'language': IsJsonString(__t('datatables_localization')) ? JSON.parse(__t('datatables_localization')) : {},
|
||||
'scrollY': false,
|
||||
'scrollX': true,
|
||||
'colReorder': true,
|
||||
'stateSave': true,
|
||||
'stateSaveParams': function(settings, data)
|
||||
{
|
||||
data.search.search = "";
|
||||
|
||||
data.columns.forEach(column =>
|
||||
{
|
||||
column.search.search = "";
|
||||
});
|
||||
},
|
||||
'stateSaveCallback': function(settings, data)
|
||||
{
|
||||
var settingKey = 'datatables_state_' + settings.sTableId;
|
||||
if ($.isEmptyObject(data))
|
||||
{
|
||||
//state.clear was called and unfortunately the table is not refresh, so we are reloading the page
|
||||
Grocy.FrontendHelpers.DeleteUserSetting(settingKey, true);
|
||||
} else
|
||||
{
|
||||
var stateData = JSON.stringify(data);
|
||||
Grocy.FrontendHelpers.SaveUserSetting(settingKey, stateData);
|
||||
}
|
||||
},
|
||||
'stateLoadCallback': function(settings, data)
|
||||
{
|
||||
var settingKey = 'datatables_state_' + settings.sTableId;
|
||||
|
||||
if (Grocy.UserSettings[settingKey] == undefined)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return JSON.parse(Grocy.UserSettings[settingKey]);
|
||||
}
|
||||
},
|
||||
'preDrawCallback': function(settings)
|
||||
{
|
||||
// Currently it is not possible to save the state of rowGroup via saveState events
|
||||
var api = new $.fn.dataTable.Api(settings);
|
||||
if (typeof api.rowGroup === "function")
|
||||
{
|
||||
var settingKey = 'datatables_rowGroup_' + settings.sTableId;
|
||||
if (Grocy.UserSettings[settingKey] !== undefined)
|
||||
{
|
||||
var rowGroup = JSON.parse(Grocy.UserSettings[settingKey]);
|
||||
|
||||
// Check if there way changed. the draw event is called often therefore we have to check if it's really necessary
|
||||
if (rowGroup.enable !== api.rowGroup().enabled()
|
||||
|| ("dataSrc" in rowGroup && rowGroup.dataSrc !== api.rowGroup().dataSrc()))
|
||||
{
|
||||
|
||||
api.rowGroup().enable(rowGroup.enable);
|
||||
|
||||
if ("dataSrc" in rowGroup)
|
||||
{
|
||||
api.rowGroup().dataSrc(rowGroup.dataSrc);
|
||||
|
||||
// Apply fixed order for group column
|
||||
api.order.fixed({
|
||||
pre: [rowGroup.dataSrc, 'asc']
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove fixed order
|
||||
api.order.fixed({});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'columnDefs': [
|
||||
{ type: 'chinese-string', targets: '_all' }
|
||||
],
|
||||
'rowGroup': {
|
||||
enable: false,
|
||||
startRender: function(rows, group)
|
||||
{
|
||||
var collapsed = !!collapsedGroups[group];
|
||||
var toggleClass = collapsed ? "fa-caret-right" : "fa-caret-down";
|
||||
|
||||
rows.nodes().each(function(row)
|
||||
{
|
||||
row.style.display = collapsed ? "none" : "";
|
||||
});
|
||||
|
||||
return $("<tr/>")
|
||||
.append('<td colspan="' + rows.columns()[0].length + '">' + group + ' <span class="fa fa-fw d-print-none ' + toggleClass + '"/></td>')
|
||||
.attr("data-name", group)
|
||||
.toggleClass("collapsed", collapsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
$(document).on("click", "tr.dtrg-group", function()
|
||||
{
|
||||
var name = $(this).data('name');
|
||||
collapsedGroups[name] = !collapsedGroups[name];
|
||||
$("table").DataTable().draw();
|
||||
});
|
||||
$.fn.dataTable.ext.type.order["custom-sort-pre"] = function(data)
|
||||
{
|
||||
// Workaround for https://github.com/DataTables/ColReorder/issues/85
|
||||
//
|
||||
// Custom sorting can normally be provided by a "data-order" attribute on the <td> element,
|
||||
// however this causes issues when reordering such a column...
|
||||
//
|
||||
// This here is for a custom column type "custom-sort",
|
||||
// the custom order value needs to be provided in the first child (<span>) of the <td>
|
||||
|
||||
return (Number.parseFloat($(data).get(0).innerText));
|
||||
};
|
||||
|
||||
// serializeJSON defaults
|
||||
$.serializeJSON.defaultOptions.checkboxUncheckedValue = "0";
|
||||
|
||||
@@ -912,38 +785,7 @@ $('.dropdown-item').has('.form-check input[type=checkbox]').on('click', function
|
||||
{
|
||||
$(e.target).find('input[type=checkbox]').click();
|
||||
}
|
||||
})
|
||||
|
||||
$('.table').on('column-sizing.dt', function(e, settings)
|
||||
{
|
||||
var dtScrollWidth = $('.dataTables_scroll').width();
|
||||
var tableWidth = $('.table').width() + 100; // Some extra padding, otherwise the scrollbar maybe only appears after a column is already completely out of the viewport
|
||||
|
||||
if (dtScrollWidth < tableWidth)
|
||||
{
|
||||
$('.dataTables_scrollBody').addClass("no-force-overflow-visible");
|
||||
$('.dataTables_scrollBody').removeClass("force-overflow-visible");
|
||||
}
|
||||
else
|
||||
{
|
||||
$('.dataTables_scrollBody').removeClass("no-force-overflow-visible");
|
||||
$('.dataTables_scrollBody').addClass("force-overflow-visible");
|
||||
}
|
||||
});
|
||||
$(document).on("show.bs.dropdown", "td .dropdown", function(e)
|
||||
{
|
||||
if ($('.dataTables_scrollBody').hasClass("no-force-overflow-visible"))
|
||||
{
|
||||
$('.dataTables_scrollBody').addClass("force-overflow-visible");
|
||||
}
|
||||
});
|
||||
$(document).on("hide.bs.dropdown", "td .dropdown", function(e)
|
||||
{
|
||||
if ($('.dataTables_scrollBody').hasClass("no-force-overflow-visible"))
|
||||
{
|
||||
$('.dataTables_scrollBody').removeClass("force-overflow-visible");
|
||||
}
|
||||
})
|
||||
|
||||
$(window).on("message", function(e)
|
||||
{
|
||||
@@ -955,223 +797,6 @@ $(window).on("message", function(e)
|
||||
}
|
||||
});
|
||||
|
||||
$(".change-table-columns-visibility-button").on("click", function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var dataTableSelector = $(e.currentTarget).attr("data-table-selector");
|
||||
var dataTable = $(dataTableSelector).DataTable();
|
||||
|
||||
var columnCheckBoxesHtml = "";
|
||||
var rowGroupRadioBoxesHtml = "";
|
||||
|
||||
var rowGroupDefined = typeof dataTable.rowGroup === "function";
|
||||
|
||||
if (rowGroupDefined)
|
||||
{
|
||||
var rowGroupChecked = (dataTable.rowGroup().enabled()) ? "" : "checked";
|
||||
rowGroupRadioBoxesHtml = ' \
|
||||
<div class="custom-control custom-radio custom-control-inline"> \
|
||||
<input ' + rowGroupChecked + ' class="custom-control-input change-table-columns-rowgroup-toggle" \
|
||||
type="radio" \
|
||||
name="column-rowgroup" \
|
||||
id="column-rowgroup-none" \
|
||||
data-table-selector="' + dataTableSelector + '" \
|
||||
data-column-index="-1" \
|
||||
> \
|
||||
<label class="custom-control-label font-italic" \
|
||||
for="column-rowgroup-none">' + __t("None") + ' \
|
||||
</label > \
|
||||
</div>';
|
||||
}
|
||||
|
||||
dataTable.columns().every(function()
|
||||
{
|
||||
var index = this.index();
|
||||
var indexForGrouping = index;
|
||||
var headerCell = $(this.header());
|
||||
var title = headerCell.text();
|
||||
var visible = this.visible();
|
||||
|
||||
if (!title || title.trim().length == 0 || title.startsWith("Hidden") || headerCell.hasClass("d-none"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var shadowColumnIndex = headerCell.attr("data-shadow-rowgroup-column");
|
||||
if (shadowColumnIndex)
|
||||
{
|
||||
indexForGrouping = shadowColumnIndex;
|
||||
}
|
||||
|
||||
var checked = "checked";
|
||||
if (!visible)
|
||||
{
|
||||
checked = "";
|
||||
}
|
||||
|
||||
columnCheckBoxesHtml += ' \
|
||||
<div class="custom-control custom-checkbox"> \
|
||||
<input ' + checked + ' class="form-check-input custom-control-input change-table-columns-visibility-toggle" \
|
||||
type="checkbox" \
|
||||
id="column-' + index.toString() + '" \
|
||||
data-table-selector="' + dataTableSelector + '" \
|
||||
data-column-index="' + index.toString() + '" \
|
||||
value="1"> \
|
||||
<label class="form-check-label custom-control-label" \
|
||||
for="column-' + index.toString() + '">' + title + ' \
|
||||
</label> \
|
||||
</div>';
|
||||
|
||||
if (rowGroupDefined && headerCell.hasClass("allow-grouping"))
|
||||
{
|
||||
var rowGroupChecked = "";
|
||||
if (dataTable.rowGroup().enabled() && dataTable.rowGroup().dataSrc() == index)
|
||||
{
|
||||
rowGroupChecked = "checked";
|
||||
}
|
||||
|
||||
rowGroupRadioBoxesHtml += ' \
|
||||
<div class="custom-control custom-radio"> \
|
||||
<input ' + rowGroupChecked + ' class="custom-control-input change-table-columns-rowgroup-toggle" \
|
||||
type="radio" \
|
||||
name="column-rowgroup" \
|
||||
id="column-rowgroup-' + indexForGrouping.toString() + '" \
|
||||
data-table-selector="' + dataTableSelector + '" \
|
||||
data-column-index="' + indexForGrouping.toString() + '" \
|
||||
> \
|
||||
<label class="custom-control-label" \
|
||||
for="column-rowgroup-' + indexForGrouping.toString() + '">' + title + ' \
|
||||
</label > \
|
||||
</div>';
|
||||
}
|
||||
});
|
||||
|
||||
var message = '\
|
||||
<div class="text-center"> \
|
||||
<h5>' + __t('Table options') + '</h5> \
|
||||
<hr> \
|
||||
<h5 class="mb-0">' + __t('Hide/view columns') + '</h5> \
|
||||
<div class="text-left form-group"> \
|
||||
' + columnCheckBoxesHtml + ' \
|
||||
</div> \
|
||||
</div>';
|
||||
|
||||
if (rowGroupDefined)
|
||||
{
|
||||
message += ' \
|
||||
<div class="text-center mt-1"> \
|
||||
<h5 class="pt-3 mb-0">' + __t('Group by') + '</h5> \
|
||||
<div class="text-left form-group"> \
|
||||
' + rowGroupRadioBoxesHtml + ' \
|
||||
</div> \
|
||||
</div>';
|
||||
}
|
||||
|
||||
bootbox.dialog({
|
||||
message: message,
|
||||
size: 'small',
|
||||
backdrop: true,
|
||||
closeButton: false,
|
||||
buttons: {
|
||||
reset: {
|
||||
label: __t('Reset'),
|
||||
className: 'btn-outline-danger float-left responsive-button',
|
||||
callback: function()
|
||||
{
|
||||
bootbox.confirm({
|
||||
message: __t("Are you sure to reset the table options?"),
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: 'No',
|
||||
className: 'btn-danger'
|
||||
},
|
||||
confirm: {
|
||||
label: 'Yes',
|
||||
className: 'btn-success'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
var dataTable = $(dataTableSelector).DataTable();
|
||||
var tableId = dataTable.settings()[0].sTableId;
|
||||
|
||||
// Delete rowgroup settings
|
||||
Grocy.FrontendHelpers.DeleteUserSetting('datatables_rowGroup_' + tableId);
|
||||
|
||||
// Delete state settings
|
||||
dataTable.state.clear();
|
||||
}
|
||||
bootbox.hideAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
ok: {
|
||||
label: __t('OK'),
|
||||
className: 'btn-primary responsive-button',
|
||||
callback: function()
|
||||
{
|
||||
bootbox.hideAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on("click", ".change-table-columns-visibility-toggle", function()
|
||||
{
|
||||
var dataTableSelector = $(this).attr("data-table-selector");
|
||||
var columnIndex = $(this).attr("data-column-index");
|
||||
var dataTable = $(dataTableSelector).DataTable();
|
||||
|
||||
dataTable.columns(columnIndex).visible(this.checked);
|
||||
LoadImagesLazy();
|
||||
});
|
||||
|
||||
|
||||
$(document).on("click", ".change-table-columns-rowgroup-toggle", function()
|
||||
{
|
||||
var dataTableSelector = $(this).attr("data-table-selector");
|
||||
var columnIndex = $(this).attr("data-column-index");
|
||||
var dataTable = $(dataTableSelector).DataTable();
|
||||
var rowGroup;
|
||||
|
||||
if (columnIndex == -1)
|
||||
{
|
||||
rowGroup = {
|
||||
enable: false
|
||||
};
|
||||
|
||||
dataTable.rowGroup().enable(false);
|
||||
|
||||
// Remove fixed order
|
||||
dataTable.order.fixed({});
|
||||
}
|
||||
else
|
||||
{
|
||||
rowGroup = {
|
||||
enable: true,
|
||||
dataSrc: columnIndex
|
||||
}
|
||||
|
||||
dataTable.rowGroup().enable(true);
|
||||
dataTable.rowGroup().dataSrc(columnIndex);
|
||||
|
||||
// Apply fixed order for group column
|
||||
dataTable.order.fixed({
|
||||
pre: [columnIndex, 'asc']
|
||||
});
|
||||
}
|
||||
|
||||
var settingKey = 'datatables_rowGroup_' + dataTable.settings()[0].sTableId;
|
||||
Grocy.FrontendHelpers.SaveUserSetting(settingKey, JSON.stringify(rowGroup));
|
||||
|
||||
dataTable.draw();
|
||||
});
|
||||
|
||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_RECIPES)
|
||||
{
|
||||
if ($(window).width() < 768)
|
||||
|
Reference in New Issue
Block a user