UI test/review

This commit is contained in:
Bernd Bestel
2020-11-08 19:00:12 +01:00
parent d82fd09fba
commit 3e3321bf11
33 changed files with 796 additions and 640 deletions

View File

@@ -634,7 +634,7 @@ msgstr ""
msgid "Quantity unit" msgid "Quantity unit"
msgstr "" msgstr ""
msgid "Only check if a single unit is in stock (a different quantity can then be used above)" msgid "Only check if a single unit is in stock (a different quantity can then be used below)"
msgstr "" msgstr ""
msgid "Are you sure to consume all ingredients needed by recipe \"%s\" (ingredients marked with \"check only if a single unit is in stock\" will be ignored)?" msgid "Are you sure to consume all ingredients needed by recipe \"%s\" (ingredients marked with \"check only if a single unit is in stock\" will be ignored)?"
@@ -1784,9 +1784,6 @@ msgstr ""
msgid "Calories" msgid "Calories"
msgstr "" msgstr ""
msgid "By default the amount to be added to the shopping list is `needed amount - stock amount - shopping list amount` - when this is enabled, it is only checked against the stock amount, not against what is already on the shopping list"
msgstr ""
msgid "means %1$s per %2$s" msgid "means %1$s per %2$s"
msgstr "" msgstr ""
@@ -1933,3 +1930,15 @@ msgstr ""
msgid "Edit shopping list" msgid "Edit shopping list"
msgstr "" msgstr ""
msgid "Save & continue to add quantity unit conversions & barcodes"
msgstr ""
msgid "Save & return to products"
msgstr ""
msgid "Save & continue to add conversions"
msgstr ""
msgid "Save & return to quantity units"
msgstr ""

View File

@@ -13,7 +13,14 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/batteries'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/batteries');
}
}); });
}, },
function(xhr) function(xhr)
@@ -30,7 +37,14 @@
{ {
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/batteries'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/batteries');
}
}); });
}, },
function(xhr) function(xhr)

View File

@@ -122,12 +122,12 @@ $('.input-group-chore-period-type').on('change', function(e)
$(".period-type-input").addClass("d-none"); $(".period-type-input").addClass("d-none");
$(".period-type-" + periodType).removeClass("d-none"); $(".period-type-" + periodType).removeClass("d-none");
$('#chore-period-type-info').text(""); $('#chore-period-type-info').attr("title", "");
$("#period_config").val(""); $("#period_config").val("");
if (periodType === 'manually') if (periodType === 'manually')
{ {
$('#chore-period-type-info').text(__t('This means the next execution of this chore is not scheduled')); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is not scheduled'));
} }
else if (periodType === 'dynamic-regular') else if (periodType === 'dynamic-regular')
{ {
@@ -135,32 +135,32 @@ $('.input-group-chore-period-type').on('change', function(e)
$("#period_days").attr("min", "0"); $("#period_days").attr("min", "0");
$("#period_days").attr("max", "9999"); $("#period_days").attr("max", "9999");
$("#period_days").parent().find(".invalid-feedback").text(__t('This cannot be negative')); $("#period_days").parent().find(".invalid-feedback").text(__t('This cannot be negative'));
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled %s days after the last execution', periodDays.toString())); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is scheduled %s days after the last execution', periodDays.toString()));
} }
else if (periodType === 'daily') else if (periodType === 'daily')
{ {
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled 1 day after the last execution')); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is scheduled 1 day after the last execution'));
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s days', periodInterval.toString())); $('#chore-period-interval-info').attr("title", __t('This means the next execution of this chore should only be scheduled every %s days', periodInterval.toString()));
} }
else if (periodType === 'weekly') else if (periodType === 'weekly')
{ {
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled 1 day after the last execution, but only for the weekdays selected below')); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is scheduled 1 day after the last execution, but only for the weekdays selected below'));
$("#period_config").val($(".period-type-weekly input:checkbox:checked").map(function() { return this.value; }).get().join(",")); $("#period_config").val($(".period-type-weekly input:checkbox:checked").map(function() { return this.value; }).get().join(","));
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s weeks', periodInterval.toString())); $('#chore-period-interval-info').attr("title", __t('This means the next execution of this chore should only be scheduled every %s weeks', periodInterval.toString()));
} }
else if (periodType === 'monthly') else if (periodType === 'monthly')
{ {
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled on the below selected day of each month')); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is scheduled on the below selected day of each month'));
$("label[for='period_days']").text(__t("Day of month")); $("label[for='period_days']").text(__t("Day of month"));
$("#period_days").attr("min", "1"); $("#period_days").attr("min", "1");
$("#period_days").attr("max", "31"); $("#period_days").attr("max", "31");
$("#period_days").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", "31")); $("#period_days").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", "31"));
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s months', periodInterval.toString())); $('#chore-period-interval-info').attr("title", __t('This means the next execution of this chore should only be scheduled every %s months', periodInterval.toString()));
} }
else if (periodType === 'yearly') else if (periodType === 'yearly')
{ {
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled 1 year after the last execution')); $('#chore-period-type-info').attr("title", __t('This means the next execution of this chore is scheduled 1 year after the last execution'));
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s years', periodInterval.toString())); $('#chore-period-interval-info').attr("title", __t('This means the next execution of this chore should only be scheduled every %s years', periodInterval.toString()));
} }
Grocy.FrontendHelpers.ValidateForm('chore-form'); Grocy.FrontendHelpers.ValidateForm('chore-form');
@@ -176,23 +176,23 @@ $('.input-group-chore-assignment-type').on('change', function(e)
if (assignmentType === 'no-assignment') if (assignmentType === 'no-assignment')
{ {
$('#chore-assignment-type-info').text(__t('This means the next execution of this chore will not be assigned to anyone')); $('#chore-assignment-type-info').attr("title", __t('This means the next execution of this chore will not be assigned to anyone'));
} }
else if (assignmentType === 'who-least-did-first') else if (assignmentType === 'who-least-did-first')
{ {
$('#chore-assignment-type-info').text(__t('This means the next execution of this chore will be assigned to the one who executed it least')); $('#chore-assignment-type-info').attr("title", __t('This means the next execution of this chore will be assigned to the one who executed it least'));
$("#assignment_config").attr("required", ""); $("#assignment_config").attr("required", "");
$("#assignment_config").removeAttr("disabled"); $("#assignment_config").removeAttr("disabled");
} }
else if (assignmentType === 'random') else if (assignmentType === 'random')
{ {
$('#chore-assignment-type-info').text(__t('This means the next execution of this chore will be assigned randomly')); $('#chore-assignment-type-info').attr("title", __t('This means the next execution of this chore will be assigned randomly'));
$("#assignment_config").attr("required", ""); $("#assignment_config").attr("required", "");
$("#assignment_config").removeAttr("disabled"); $("#assignment_config").removeAttr("disabled");
} }
else if (assignmentType === 'in-alphabetical-order') else if (assignmentType === 'in-alphabetical-order')
{ {
$('#chore-assignment-type-info').text(__t('This means the next execution of this chore will be assigned to the next one in alphabetical order')); $('#chore-assignment-type-info').attr("title", __t('This means the next execution of this chore will be assigned to the next one in alphabetical order'));
$("#assignment_config").attr("required", ""); $("#assignment_config").attr("required", "");
$("#assignment_config").removeAttr("disabled"); $("#assignment_config").removeAttr("disabled");
} }

View File

@@ -13,7 +13,14 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/locations'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/locations');
}
}); });
}, },
function(xhr) function(xhr)
@@ -30,7 +37,14 @@
{ {
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/locations'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/locations');
}
}); });
}, },
function(xhr) function(xhr)

View File

@@ -1,19 +1,58 @@
$('#save-product-button').on('click', function(e) function saveProductPicture(result, location, jsonData)
{
var productId = Grocy.EditObjectId || result.created_object_id;
Grocy.Components.UserfieldsForm.Save(() =>
{
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
{
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
(result) =>
{
var returnTo = GetUriParam('returnto');
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (returnTo !== undefined)
{
window.location.href = U(returnTo) + '?createdproduct=' + encodeURIComponent($('#name').val());
}
else
{
window.location.href = U(location + productId);
}
},
(xhr) =>
{
Grocy.FrontendHelpers.EndUiBusy("product-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
}
else
{
var returnTo = GetUriParam('returnto');
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (returnTo !== undefined)
{
window.location.href = U(returnTo) + '?createdproduct=' + encodeURIComponent($('#name').val());
}
else
{
window.location.href = U(location + productId);
}
}
});
}
$('.save-product-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
var redirectDestination = U('/products');
var returnTo = GetUriParam('returnto');
if (returnTo !== undefined)
{
redirectDestination = U(returnTo) + '?createdproduct=' + encodeURIComponent($('#name').val());
}
if (Grocy.ProductEditFormRedirectUri !== undefined)
{
redirectDestination = Grocy.ProductEditFormRedirectUri;
}
var jsonData = $('#product-form').serializeJSON({ checkboxUncheckedValue: "0" }); var jsonData = $('#product-form').serializeJSON({ checkboxUncheckedValue: "0" });
var parentProductId = jsonData.product_id; var parentProductId = jsonData.product_id;
delete jsonData.product_id; delete jsonData.product_id;
@@ -31,80 +70,23 @@
jsonData.picture_file_name = someRandomStuff + $("#product-picture")[0].files[0].name; jsonData.picture_file_name = someRandomStuff + $("#product-picture")[0].files[0].name;
} }
const location = $(e.currentTarget).attr('data-location') == 'return' ? '/products?product=' : '/product/';
if (Grocy.EditMode == 'create')
{
Grocy.Api.Post('objects/products', jsonData,
(result) => saveProductPicture(result, location, jsonData));
return;
}
if (Grocy.DeleteProductPictureOnSave) if (Grocy.DeleteProductPictureOnSave)
{ {
jsonData.picture_file_name = null; jsonData.picture_file_name = null;
}
if (Grocy.EditMode === 'create') Grocy.Api.DeleteFile(Grocy.ProductPictureFileName, 'productpictures', {},
{
Grocy.Api.Post('objects/products', jsonData,
function(result) function(result)
{ {
Grocy.EditObjectId = result.created_object_id; // Nothing to do
if (prefillBarcode !== undefined)
{
var jsonDataBarcode = {};
jsonDataBarcode.barcode = prefillBarcode;
jsonDataBarcode.product_id = result.created_object_id;
jsonDataBarcode.qu_factor_purchase_to_stock = jsonData.qu_factor_purchase_to_stock;
jsonDataBarcode.shopping_location_id = jsonData.shopping_location_id;
Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode,
function(result)
{
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("barcode-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
}
);
}
Grocy.Components.UserfieldsForm.Save(function()
{
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
{
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
function(result)
{
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (redirectDestination == "reload")
{
window.location.reload();
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);;
}
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("product-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
}
else
{
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (redirectDestination == "reload")
{
window.location.reload();
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);;
}
}
});
}, },
function(xhr) function(xhr)
{ {
@@ -113,77 +95,15 @@
} }
); );
} }
else
{ Grocy.Api.Put('objects/products/' + Grocy.EditObjectId, jsonData,
if (Grocy.DeleteProductPictureOnSave) (result) => saveProductPicture(result, location, jsonData),
function(xhr)
{ {
Grocy.Api.DeleteFile(Grocy.ProductPictureFileName, 'productpictures', {}, Grocy.FrontendHelpers.EndUiBusy("product-form");
function(result) console.error(xhr);
{ }
// Nothing to do );
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("product-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
};
Grocy.Api.Put('objects/products/' + Grocy.EditObjectId, jsonData,
function(result)
{
Grocy.Components.UserfieldsForm.Save(function()
{
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
{
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
function(result)
{
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (redirectDestination == "reload")
{
window.location.reload();
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);;
}
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("product-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
}
else
{
if (GetUriParam("closeAfterCreation") !== undefined)
{
window.close();
}
else if (redirectDestination == "reload")
{
window.location.reload();
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);;
}
}
});
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("product-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
}
}); });
Grocy.Api.Get('stock/products/' + Grocy.EditObjectId, Grocy.Api.Get('stock/products/' + Grocy.EditObjectId,
@@ -342,21 +262,23 @@ $("#allow_partial_units_in_stock").on("click", function()
Grocy.FrontendHelpers.ValidateForm("product-form"); Grocy.FrontendHelpers.ValidateForm("product-form");
}); });
$('#product-picture').change(function() $("#product-picture").on("change", function(e)
{ {
if ($(this).val()) $("#product-picture-label").removeClass("d-none");
{ $("#product-picture-label-none").addClass("d-none");
Grocy.DeleteProductPictureOnSave = false; $("#delete-current-product-picture-on-save-hint").addClass("d-none");
} $("#current-product-picture").addClass("d-none");
Grocy.DeleteProductPictureOnSave = false;
}); });
Grocy.DeleteProductPictureOnSave = false; Grocy.DeleteProductPictureOnSave = false;
$('#delete-current-product-picture-button').on('click', function(e) $("#delete-current-product-picture-button").on("click", function(e)
{ {
Grocy.DeleteProductPictureOnSave = true; Grocy.DeleteProductPictureOnSave = true;
$("#current-product-picture").addClass("d-none"); $("#current-product-picture").addClass("d-none");
$("#delete-current-product-picture-on-save-hint").removeClass("d-none"); $("#delete-current-product-picture-on-save-hint").removeClass("d-none");
$("#delete-current-product-picture-button").addClass("disabled"); $("#product-picture-label").addClass("d-none");
$("#product-picture-label-none").removeClass("d-none");
}); });
if (Grocy.EditMode === 'create') if (Grocy.EditMode === 'create')

View File

@@ -19,14 +19,62 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
if (typeof GetUriParam("qu-unit") !== "undefined") if ($("#create_inverse").is(":checked"))
{ {
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit")); jsonData.to_qu_id = inverse_to_qu_id;
jsonData.from_qu_id = inverse_from_qu_id;
jsonData.factor = 1 / jsonData.factor;
//Create Inverse
Grocy.Api.Post('objects/quantity_unit_conversions', jsonData,
function(result)
{
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function()
{
if (typeof GetUriParam("qu-unit") !== "undefined")
{
if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit"));
}
}
else
{
window.parent.postMessage(WindowMessageBag("ProductQUConversionChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
}
});
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("quconversion-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
} }
else else
{ {
window.parent.postMessage(WindowMessageBag("ProductQUConversionChanged"), U("/product/" + GetUriParam("product"))); if (typeof GetUriParam("qu-unit") !== "undefined")
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product"))); {
if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit"));
}
}
else
{
window.parent.postMessage(WindowMessageBag("ProductQUConversionChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
}
} }
}); });
}, },
@@ -36,37 +84,6 @@
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response) Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
} }
); );
if ($("#create_inverse").is(":checked"))
{
jsonData.to_qu_id = inverse_to_qu_id;
jsonData.from_qu_id = inverse_from_qu_id;
jsonData.factor = 1 / jsonData.factor;
//Create Inverse
Grocy.Api.Post('objects/quantity_unit_conversions', jsonData,
function(result)
{
Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function()
{
if (typeof GetUriParam("qu-unit") !== "undefined")
{
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit"));
}
else
{
window.parent.postMessage(WindowMessageBag("ProductQUConversionChanged"), U("/product/" + GetUriParam("product")));
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
}
});
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy("quconversion-form");
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
}
);
}
} }
else else
{ {
@@ -77,7 +94,14 @@
{ {
if (typeof GetUriParam("qu-unit") !== "undefined") if (typeof GetUriParam("qu-unit") !== "undefined")
{ {
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit")); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U("/quantityunit/" + GetUriParam("qu-unit"));
}
} }
else else
{ {
@@ -124,7 +148,7 @@ $("#create_inverse").on("change", function()
if (value) if (value)
{ {
$('#qu-conversion-inverse-info').removeClass('d-none'); $('#qu-conversion-inverse-info').removeClass('d-none');
} }
else else
{ {

View File

@@ -1,4 +1,4 @@
$('#save-quantityunit-button').on('click', function(e) $('.save-quantityunit-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
@@ -14,6 +14,11 @@
redirectDestination = U('/quantityunits'); redirectDestination = U('/quantityunits');
} }
if ($(e.currentTarget).attr('data-location') == "continue")
{
redirectDestination = "reload";
}
if (Grocy.EditMode === 'create') if (Grocy.EditMode === 'create')
{ {
Grocy.Api.Post('objects/quantity_units', jsonData, Grocy.Api.Post('objects/quantity_units', jsonData,
@@ -22,17 +27,25 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
if (redirectDestination == "reload") if (GetUriParam("embedded") !== undefined)
{ {
window.location.reload(); window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else if (redirectDestination == "stay")
{
// Do nothing
} }
else else
{ {
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);
if (redirectDestination == "reload")
{
window.location.href = U("/quantityunit/" + result.created_object_id.toString());
}
else if (redirectDestination == "stay")
{
// Do nothing
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);
}
} }
}); });
}, },
@@ -50,17 +63,25 @@
{ {
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
if (redirectDestination == "reload") if (GetUriParam("embedded") !== undefined)
{ {
window.location.reload(); window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else if (redirectDestination == "stay")
{
// Do nothing
} }
else else
{ {
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);
if (redirectDestination == "reload")
{
window.location.reload();
}
else if (redirectDestination == "stay")
{
// Do nothing
}
else
{
window.location.href = redirectDestination.replace("editobjectid", Grocy.EditObjectId);
}
} }
}); });
}, },
@@ -154,8 +175,7 @@ $(document).on('click', '.qu-conversion-delete-button', function(e)
Grocy.Api.Delete('objects/quantity_unit_conversions/' + objectId, {}, Grocy.Api.Delete('objects/quantity_unit_conversions/' + objectId, {},
function(result) function(result)
{ {
Grocy.QuantityUnitEditFormRedirectUri = "reload"; window.location.reload();
$('#save-quantityunit-button').click();
}, },
function(xhr) function(xhr)
{ {
@@ -167,19 +187,6 @@ $(document).on('click', '.qu-conversion-delete-button', function(e)
}); });
}); });
$(document).on('click', '.qu-conversion-edit-button', function(e)
{
var id = $(e.currentTarget).attr('data-qu-conversion-id');
Grocy.QuantityUnitEditFormRedirectUri = U("/quantityunitconversion/" + id.toString() + "?qu-unit=editobjectid");
$('#save-quantityunit-button').click();
});
$("#qu-conversion-add-button").on("click", function(e)
{
Grocy.QuantityUnitEditFormRedirectUri = U("/quantityunitconversion/new?qu-unit=editobjectid");
$('#save-quantityunit-button').click();
});
$("#test-quantityunit-plural-forms-button").on("click", function(e) $("#test-quantityunit-plural-forms-button").on("click", function(e)
{ {
e.preventDefault(); e.preventDefault();

View File

@@ -1,6 +1,6 @@
function saveRecipePicture(result, location, jsonData) function saveRecipePicture(result, location, jsonData)
{ {
$recipeId = Grocy.EditObjectId || result.created_object_id; var recipeId = Grocy.EditObjectId || result.created_object_id;
Grocy.Components.UserfieldsForm.Save(() => Grocy.Components.UserfieldsForm.Save(() =>
{ {
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteRecipePictureOnSave) if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteRecipePictureOnSave)
@@ -8,7 +8,7 @@
Grocy.Api.UploadFile($("#recipe-picture")[0].files[0], 'recipepictures', jsonData.picture_file_name, Grocy.Api.UploadFile($("#recipe-picture")[0].files[0], 'recipepictures', jsonData.picture_file_name,
(result) => (result) =>
{ {
window.location.href = U(location + $recipeId); window.location.href = U(location + recipeId);
}, },
(xhr) => (xhr) =>
{ {
@@ -19,7 +19,7 @@
} }
else else
{ {
window.location.href = U(location + $recipeId); window.location.href = U(location + recipeId);
} }
}); });
} }

View File

@@ -63,7 +63,6 @@ $("#search").on("keyup", Delay(function()
recipesTables.search(value).draw(); recipesTables.search(value).draw();
$(".recipe-gallery-item").removeClass("d-none"); $(".recipe-gallery-item").removeClass("d-none");
console.log($(".recipe-gallery-item .card-title:not(:contains_case_insensitive(" + value + "))"));
$(".recipe-gallery-item .card-title:not(:contains_case_insensitive(" + value + "))").parent().parent().parent().addClass("d-none"); $(".recipe-gallery-item .card-title:not(:contains_case_insensitive(" + value + "))").parent().parent().parent().addClass("d-none");
}, 200)); }, 200));

View File

@@ -13,7 +13,14 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/shoppinglocations'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/shoppinglocations');
}
}); });
}, },
function(xhr) function(xhr)
@@ -30,7 +37,14 @@
{ {
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/shoppinglocations'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/shoppinglocations');
}
}); });
}, },
function(xhr) function(xhr)

View File

@@ -13,7 +13,14 @@
Grocy.EditObjectId = result.created_object_id; Grocy.EditObjectId = result.created_object_id;
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/taskcategories'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/taskcategories');
}
}); });
}, },
function(xhr) function(xhr)
@@ -30,7 +37,14 @@
{ {
Grocy.Components.UserfieldsForm.Save(function() Grocy.Components.UserfieldsForm.Save(function()
{ {
window.location.href = U('/taskcategories'); if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = U('/taskcategories');
}
}); });
}, },
function(xhr) function(xhr)

View File

@@ -12,7 +12,14 @@
Grocy.Api.Post('objects/userentities', jsonData, Grocy.Api.Post('objects/userentities', jsonData,
function(result) function(result)
{ {
window.location.href = redirectUrl; if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = redirectUrl;
}
}, },
function(xhr) function(xhr)
{ {
@@ -26,7 +33,14 @@
Grocy.Api.Put('objects/userentities/' + Grocy.EditObjectId, jsonData, Grocy.Api.Put('objects/userentities/' + Grocy.EditObjectId, jsonData,
function(result) function(result)
{ {
window.location.href = redirectUrl; if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = redirectUrl;
}
}, },
function(xhr) function(xhr)
{ {

View File

@@ -16,7 +16,14 @@
Grocy.Api.Post('objects/userfields', jsonData, Grocy.Api.Post('objects/userfields', jsonData,
function(result) function(result)
{ {
window.location.href = redirectUrl; if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = redirectUrl;
}
}, },
function(xhr) function(xhr)
{ {
@@ -30,7 +37,14 @@
Grocy.Api.Put('objects/userfields/' + Grocy.EditObjectId, jsonData, Grocy.Api.Put('objects/userfields/' + Grocy.EditObjectId, jsonData,
function(result) function(result)
{ {
window.location.href = redirectUrl; if (GetUriParam("embedded") !== undefined)
{
window.parent.postMessage(WindowMessageBag("Reload"), Grocy.BaseUrl);
}
else
{
window.location.href = redirectUrl;
}
}, },
function(xhr) function(xhr)
{ {

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button permission-MASTER_DATA_EDIT m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-primary responsive-button permission-MASTER_DATA_EDIT m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
href="{{ $U('/battery/new') }}"> href="{{ $U('/battery/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
<a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right"
@@ -86,8 +86,8 @@
@foreach($batteries as $battery) @foreach($batteries as $battery)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm permission-MASTER_DATA_EDIT" <a class="btn btn-info btn-sm permission-MASTER_DATA_EDIT show-as-dialog-link"
href="{{ $U('/battery/') }}{{ $battery->id }}"> href="{{ $U('/battery/') }}{{ $battery->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm battery-delete-button permission-MASTER_DATA_EDIT" <a class="btn btn-danger btn-sm battery-delete-button permission-MASTER_DATA_EDIT"

View File

@@ -52,8 +52,10 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="period_type">{{ $__t('Period type') }} <span id="chore-period-type-info" <label for="period_type">{{ $__t('Period type') }}&nbsp;<i id="chore-period-type-info"
class="small text-muted"></span></label> class="fas fa-question-circle"
data-toggle="tooltip"
title=""></i></label>
<select required <select required
class="form-control input-group-chore-period-type" class="form-control input-group-chore-period-type"
id="period_type" id="period_type"
@@ -79,61 +81,61 @@
)) ))
<div class="form-group period-type-input period-type-weekly"> <div class="form-group period-type-input period-type-weekly">
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="monday" id="monday"
value="monday"> value="monday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="monday">{{ $__t('Monday') }}</label> for="monday">{{ $__t('Monday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="tuesday" id="tuesday"
value="tuesday"> value="tuesday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="tuesday">{{ $__t('Tuesday') }}</label> for="tuesday">{{ $__t('Tuesday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="wednesday" id="wednesday"
value="wednesday"> value="wednesday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="wednesday">{{ $__t('Wednesday') }}</label> for="wednesday">{{ $__t('Wednesday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="thursday" id="thursday"
value="thursday"> value="thursday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="thursday">{{ $__t('Thursday') }}</label> for="thursday">{{ $__t('Thursday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="friday" id="friday"
value="friday"> value="friday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="friday">{{ $__t('Friday') }}</label> for="friday">{{ $__t('Friday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="saturday" id="saturday"
value="saturday"> value="saturday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="saturday">{{ $__t('Saturday') }}</label> for="friday">{{ $__t('Saturday') }}</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="custom-control custom-checkbox custom-control-inline">
<input class="form-check-input input-group-chore-period-type" <input class="form-check-input custom-control-input input-group-chore-period-type"
type="checkbox" type="checkbox"
id="sunday" id="sunday"
value="sunday"> value="sunday">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="sunday">{{ $__t('Sunday') }}</label> for="friday">{{ $__t('Sunday') }}</label>
</div> </div>
</div> </div>
@@ -156,8 +158,10 @@
@if(GROCY_FEATURE_FLAG_CHORES_ASSIGNMENTS) @if(GROCY_FEATURE_FLAG_CHORES_ASSIGNMENTS)
<div class="form-group"> <div class="form-group">
<label for="assignment_type">{{ $__t('Assignment type') }} <span id="chore-assignment-type-info" <label for="assignment_type">{{ $__t('Assignment type') }} <i id="chore-assignment-type-info"
class="small text-muted"></span></label> class="fas fa-question-circle"
data-toggle="tooltip"
title=""></i></label>
<select required <select required
class="form-control input-group-chore-assignment-type" class="form-control input-group-chore-assignment-type"
id="assignment_type" id="assignment_type"
@@ -200,45 +204,49 @@
@endif @endif
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="track_date_only" name="track_date_only"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$chore->track_date_only == 1) checked @endif class="form-check-input" type="checkbox" id="track_date_only" name="track_date_only" value="1"> $chore->track_date_only == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="track_date_only" name="track_date_only" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="track_date_only">{{ $__t('Track date only') }} for="track_date_only">{{ $__t('Track date only') }}
<span class="text-muted small">{{ $__t('When enabled only the day of an execution is tracked, not the time') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('When enabled only the day of an execution is tracked, not the time') }}"></i>
</label> </label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="rollover" name="rollover"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$chore->rollover == 1) checked @endif class="form-check-input" type="checkbox" id="rollover" name="rollover" value="1"> $chore->rollover == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="rollover" name="rollover" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="rollover">{{ $__t('Due date rollover') }} for="rollover">{{ $__t('Due date rollover') }}
<span class="text-muted small">{{ $__t('When enabled the chore can never be overdue, the due date will shift forward each day when due') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('When enabled the chore can never be overdue, the due date will shift forward each day when due') }}"></i>
</label> </label>
</div> </div>
</div> </div>
@if(GROCY_FEATURE_FLAG_STOCK) @if(GROCY_FEATURE_FLAG_STOCK)
<div class="form-group mt-4 mb-1"> <div class="form-group mt-4 mb-1">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="consume_product_on_execution" name="consume_product_on_execution"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$chore->consume_product_on_execution == 1) checked @endif class="form-check-input" type="checkbox" id="consume_product_on_execution" name="consume_product_on_execution" value="1"> $chore->consume_product_on_execution == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="consume_product_on_execution" name="consume_product_on_execution" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="consume_product_on_execution">{{ $__t('Consume product on chore execution') }}</label> for="consume_product_on_execution">{{ $__t('Consume product on chore execution') }}</label>
</div> </div>
</div> </div>

View File

@@ -76,12 +76,12 @@
)) ))
@elseif($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_CHECKBOX) @elseif($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_CHECKBOX)
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input class="form-check-input userfield-input" <input class="form-check-input userfield-input custom-control-input"
type="checkbox" type="checkbox"
data-userfield-name="{{ $userfield->name }}" data-userfield-name="{{ $userfield->name }}"
value="1"> value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="{{ $userfield->name }}">{{ $userfield->caption }}</label> for="{{ $userfield->name }}">{{ $userfield->caption }}</label>
</div> </div>
</div> </div>

View File

@@ -53,16 +53,18 @@
@if(GROCY_FEATURE_FLAG_STOCK_PRODUCT_FREEZING) @if(GROCY_FEATURE_FLAG_STOCK_PRODUCT_FREEZING)
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="is_freezer" name="is_freezer"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$location->is_freezer == 1) checked @endif class="form-check-input" type="checkbox" id="is_freezer" name="is_freezer" value="1"> $location->is_freezer == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="is_freezer" name="is_freezer" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="is_freezer">{{ $__t('Is freezer') }} for="is_freezer">{{ $__t('Is freezer') }}
<span class="text-muted small">{{ $__t('When moving products from/to a freezer location, the products best before date is automatically adjusted according to the product settings') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('When moving products from/to a freezer location, the products best before date is automatically adjusted according to the product settings') }}"></i>
</label> </label>
</div> </div>
</div> </div>

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
href="{{ $U('/location/new') }}"> href="{{ $U('/location/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
<a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right"
@@ -84,8 +84,8 @@
@foreach($locations as $location) @foreach($locations as $location)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm" <a class="btn btn-info btn-sm show-as-dialog-link"
href="{{ $U('/location/') }}{{ $location->id }}"> href="{{ $U('/location/') }}{{ $location->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm location-delete-button" <a class="btn btn-danger btn-sm location-delete-button"

View File

@@ -11,7 +11,12 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h2 class="title">@yield('title')</h2> <div class="title-related-links">
<h2 class="title">@yield('title')</h2>
<h2>
<span class="text-muted small">{{ $__t('Barcode for product') }} <strong>{{ $product->name }}</strong></span>
</h2>
</div>
</div> </div>
</div> </div>
@@ -20,8 +25,6 @@
<div class="row"> <div class="row">
<div class="col-lg-6 col-xs-12"> <div class="col-lg-6 col-xs-12">
<h3 class="text-muted">{{ $__t('Barcode for product') }} <strong>{{ $product->name }}</strong></h3>
<script> <script>
Grocy.EditMode = '{{ $mode }}'; Grocy.EditMode = '{{ $mode }}';
</script> </script>

View File

@@ -63,7 +63,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="active" name="active"
value="1"> value="1">
@@ -72,8 +72,8 @@
checked checked
@elseif($mode=='edit' @elseif($mode=='edit'
&& &&
$product->active == 1) checked @endif class="form-check-input" type="checkbox" id="active" name="active" value="1"> $product->active == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="active" name="active" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="active">{{ $__t('Active') }}</label> for="active">{{ $__t('Active') }}</label>
</div> </div>
</div> </div>
@@ -152,16 +152,18 @@
)) ))
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="cumulate_min_stock_amount_of_sub_products" name="cumulate_min_stock_amount_of_sub_products"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$product->cumulate_min_stock_amount_of_sub_products == 1) checked @endif class="form-check-input" type="checkbox" id="cumulate_min_stock_amount_of_sub_products" name="cumulate_min_stock_amount_of_sub_products" value="1"> $product->cumulate_min_stock_amount_of_sub_products == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="cumulate_min_stock_amount_of_sub_products" name="cumulate_min_stock_amount_of_sub_products" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="cumulate_min_stock_amount_of_sub_products">{{ $__t('Accumulate sub products min. stock amount') }} for="cumulate_min_stock_amount_of_sub_products">{{ $__t('Accumulate sub products min. stock amount') }}
<span class="text-muted small">{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be "missing", only this product') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be "missing", only this product') }}"></i></span>
</label> </label>
</div> </div>
</div> </div>
@@ -257,29 +259,31 @@
)) ))
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="allow_partial_units_in_stock" name="allow_partial_units_in_stock"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$product->allow_partial_units_in_stock == 1) checked @endif class="form-check-input" type="checkbox" id="allow_partial_units_in_stock" name="allow_partial_units_in_stock" value="1"> $product->allow_partial_units_in_stock == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="allow_partial_units_in_stock" name="allow_partial_units_in_stock" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="allow_partial_units_in_stock">{{ $__t('Allow partial units in stock') }}</label> for="allow_partial_units_in_stock">{{ $__t('Allow partial units in stock') }}</label>
</div> </div>
</div> </div>
<div class="form-group mb-1"> <div class="form-group mb-1">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="enable_tare_weight_handling" name="enable_tare_weight_handling"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$product->enable_tare_weight_handling == 1) checked @endif class="form-check-input" type="checkbox" id="enable_tare_weight_handling" name="enable_tare_weight_handling" value="1"> $product->enable_tare_weight_handling == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="enable_tare_weight_handling" name="enable_tare_weight_handling" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="enable_tare_weight_handling">{{ $__t('Enable tare weight handling') }} for="enable_tare_weight_handling">{{ $__t('Enable tare weight handling') }}
<span class="text-muted small">{{ $__t('This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below') }}"></i>
</label> </label>
</div> </div>
</div> </div>
@@ -300,16 +304,18 @@
@if(GROCY_FEATURE_FLAG_RECIPES) @if(GROCY_FEATURE_FLAG_RECIPES)
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="not_check_stock_fulfillment_for_recipes" name="not_check_stock_fulfillment_for_recipes"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$product->not_check_stock_fulfillment_for_recipes == 1) checked @endif class="form-check-input" type="checkbox" id="not_check_stock_fulfillment_for_recipes" name="not_check_stock_fulfillment_for_recipes" value="1"> $product->not_check_stock_fulfillment_for_recipes == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="not_check_stock_fulfillment_for_recipes" name="not_check_stock_fulfillment_for_recipes" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="not_check_stock_fulfillment_for_recipes">{{ $__t('Disable stock fulfillment checking for this ingredient') }} for="not_check_stock_fulfillment_for_recipes">{{ $__t('Disable stock fulfillment checking for this ingredient') }}
<span class="text-muted small">{{ $__t('This will be used as the default setting when adding this product as a recipe ingredient') }}</span> &nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('This will be used as the default setting when adding this product as a recipe ingredient') }}"></i>
</label> </label>
</div> </div>
</div> </div>
@@ -356,167 +362,217 @@
value="0"> value="0">
@endif @endif
<div class="form-group">
<label for="product-picture">{{ $__t('Product picture') }}
<span class="text-muted small">{{ $__t('If you don\'t select a file, the current picture will not be altered') }}</span>
</label>
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="product-picture"
accept="image/*">
<label class="custom-file-label"
for="product-picture">{{ $__t('No file selected') }}</label>
</div>
</div>
@include('components.userfieldsform', array( @include('components.userfieldsform', array(
'userfields' => $userfields, 'userfields' => $userfields,
'entity' => 'products' 'entity' => 'products'
)) ))
<button id="save-product-button" <small class="my-2 form-text text-muted @if($mode == 'edit') d-none @endif">{{ $__t('Save & continue to add quantity unit conversions & barcodes') }}</small>
class="btn btn-info mb-2">{{ $__t('Save') }}</button>
<button class="save-product-button btn btn-success mb-2"
data-location="continue">{{ $__t('Save & continue') }}</button>
<button class="save-product-button btn btn-info mb-2"
data-location="return">{{ $__t('Save & return to products') }}</button>
</form> </form>
</div> </div>
<div class="col-lg-6 col-xs-12"> <div class="col-lg-6 col-xs-12 @if($mode == 'create') d-none @endif">
<h2> <div class="row">
{{ $__t('QU conversions') }} <div class="col">
<a class="btn btn-outline-dark show-as-dialog-link" <div class="title-related-links">
type="button" <h4>
href="{{ $U('/quantityunitconversion/new?embedded&product=' . $product->id ) }}"> {{ $__t('QU conversions') }}
<i class="fas fa-plus"></i> {{ $__t('Add') }} </h4>
</a> <button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3"
</h2> type="button"
<h5 id="qu-conversion-headline-info" data-toggle="collapse"
class="text-muted font-italic"></h5> data-target="#related-links">
<table id="qu-conversions-table" <i class="fas fa-ellipsis-v"></i>
class="table table-sm table-striped nowrap w-100"> </button>
<thead> <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
<tr> id="related-links">
<th class="border-right"></th> <a class="btn btn-outline-primary btn-sm m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
<th>{{ $__t('Factor') }}</th> href="{{ $U('/quantityunitconversion/new?embedded&product=' . $product->id ) }}">
<th>{{ $__t('Unit') }}</th> {{ $__t('Add') }}
<th class="d-none">Hidden group</th>
<th class="d-none">Hidden from_qu_id</th>
</tr>
</thead>
<tbody class="d-none">
@if($mode == "edit")
@foreach($quConversions as $quConversion)
@if($quConversion->product_id == $product->id || $quConversion->product_id == null)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info show-as-dialog-link @if($quConversion->product_id == null) disabled @endif"
href="{{ $U('/quantityunitconversion/' . $quConversion->id . '?embedded&product=' . $product->id ) }}">
<i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-sm btn-danger qu-conversion-delete-button @if($quConversion->product_id == null) disabled @endif" </div>
href="#" </div>
data-qu-conversion-id="{{ $quConversion->id }}">
<i class="fas fa-trash"></i>
</a>
</td>
<td>
<span class="locale-number locale-number-quantity-amount">{{ $quConversion->factor }}</span>
</td>
<td>
{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name }}
</td>
<td class="d-none">
@if($quConversion->product_id != null)
{{ $__t('Product overrides') }}
@else
{{ $__t('Default conversions') }}
@endif
</td>
<td class="d-none">
from_qu_id xx{{ $quConversion->from_qu_id }}xx
</td>
</tr>
@endif
@endforeach
@endif
</tbody>
</table>
<h2> <h5 id="qu-conversion-headline-info"
{{ $__t('Barcodes') }} class="text-muted font-italic"></h5>
<a class="btn btn-outline-dark show-as-dialog-link"
type="button"
href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id ) }}">
<i class="fas fa-plus"></i> {{ $__t('Add') }}
</a>
</h2>
<h5 id="barcode-headline-info"
class="text-muted font-italic"></h5>
<table id="barcode-table"
class="table table-sm table-striped nowrap w-100">
<thead>
<tr>
<th class="border-right"></th>
<th>{{ $__t('Barcode') }}</th>
<th>{{ $__t('Factor purchase to stock quantity unit') }}</th>
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
<th>{{ $__t('Store') }}</th>
@endif
</tr>
</thead>
<tbody class="d-none">
@if($mode == "edit")
@foreach($barcodes as $barcode)
@if($barcode->product_id == $product->id || $barcode->product_id == null)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info show-as-dialog-link @if($barcode->product_id == null) disabled @endif"
href="{{ $U('/productbarcodes/' . $barcode->id . '?embedded&product=' . $product->id ) }}">
<i class="fas fa-edit"></i>
</a>
<a class="btn btn-sm btn-danger barcode-delete-button @if($barcode->product_id == null) disabled @endif"
href="#"
data-barcode-id="{{ $barcode->id }}"
data-barcode="{{ $barcode->barcode }}"
data-product-barcode="{{ $product->barcode }}"
data-product-id="{{ $product->id }}">
<i class="fas fa-trash"></i>
</a>
</td>
<td>
{{ $barcode->barcode }}
</td>
<td>
<span class="locale-number locale-number-quantity-amount">{{ $barcode->qu_factor_purchase_to_stock }}</span>
</td>
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
<td id="barcode-shopping-location">
@if (FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id) !== null)
{{ FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id)->name }}
@endif
</td>
@endif
</tr>
@endif
@endforeach
@endif
</tbody>
</table>
<div class="pt-5"> <table id="qu-conversions-table"
<label class="mt-2">{{ $__t('Picture') }}</label> class="table table-sm table-striped nowrap w-100">
<button id="delete-current-product-picture-button" <thead>
class="btn btn-sm btn-danger @if(empty($product->picture_file_name)) disabled @endif"><i class="fas fa-trash"></i> {{ $__t('Delete') }}</button> <tr>
@if(!empty($product->picture_file_name)) <th class="border-right"></th>
<p><img id="current-product-picture" <th>{{ $__t('Factor') }}</th>
<th>{{ $__t('Unit') }}</th>
<th class="d-none">Hidden group</th>
<th class="d-none">Hidden from_qu_id</th>
</tr>
</thead>
<tbody class="d-none">
@if($mode == "edit")
@foreach($quConversions as $quConversion)
@if($quConversion->product_id == $product->id || $quConversion->product_id == null)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info show-as-dialog-link @if($quConversion->product_id == null) disabled @endif"
href="{{ $U('/quantityunitconversion/' . $quConversion->id . '?embedded&product=' . $product->id ) }}">
<i class="fas fa-edit"></i>
</a>
<a class="btn btn-sm btn-danger qu-conversion-delete-button @if($quConversion->product_id == null) disabled @endif"
href="#"
data-qu-conversion-id="{{ $quConversion->id }}">
<i class="fas fa-trash"></i>
</a>
</td>
<td>
<span class="locale-number locale-number-quantity-amount">{{ $quConversion->factor }}</span>
</td>
<td>
{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name }}
</td>
<td class="d-none">
@if($quConversion->product_id != null)
{{ $__t('Product overrides') }}
@else
{{ $__t('Default conversions') }}
@endif
</td>
<td class="d-none">
from_qu_id xx{{ $quConversion->from_qu_id }}xx
</td>
</tr>
@endif
@endforeach
@endif
</tbody>
</table>
</div>
</div>
<div class="row mt-5">
<div class="col">
<div class="title-related-links">
<h4>
{{ $__t('Barcodes') }}
</h4>
<button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3"
type="button"
data-toggle="collapse"
data-target="#related-links">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links">
<a class="btn btn-outline-primary btn-sm m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id ) }}">
{{ $__t('Add') }}
</a>
</div>
</div>
<h5 id="barcode-headline-info"
class="text-muted font-italic"></h5>
<table id="barcode-table"
class="table table-sm table-striped nowrap w-100">
<thead>
<tr>
<th class="border-right"></th>
<th>{{ $__t('Barcode') }}</th>
<th>{{ $__t('Factor purchase to stock quantity unit') }}</th>
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
<th>{{ $__t('Store') }}</th>
@endif
</tr>
</thead>
<tbody class="d-none">
@if($mode == "edit")
@foreach($barcodes as $barcode)
@if($barcode->product_id == $product->id || $barcode->product_id == null)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info show-as-dialog-link @if($barcode->product_id == null) disabled @endif"
href="{{ $U('/productbarcodes/' . $barcode->id . '?embedded&product=' . $product->id ) }}">
<i class="fas fa-edit"></i>
</a>
<a class="btn btn-sm btn-danger barcode-delete-button @if($barcode->product_id == null) disabled @endif"
href="#"
data-barcode-id="{{ $barcode->id }}"
data-barcode="{{ $barcode->barcode }}"
data-product-barcode="{{ $product->barcode }}"
data-product-id="{{ $product->id }}">
<i class="fas fa-trash"></i>
</a>
</td>
<td>
{{ $barcode->barcode }}
</td>
<td>
<span class="locale-number locale-number-quantity-amount">{{ $barcode->qu_factor_purchase_to_stock }}</span>
</td>
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
<td id="barcode-shopping-location">
@if (FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id) !== null)
{{ FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id)->name }}
@endif
</td>
@endif
</tr>
@endif
@endforeach
@endif
</tbody>
</table>
</div>
</div>
<div class="row mt-5">
<div class="col">
<div class="title-related-links">
<h4>
{{ $__t('Picture') }}
</h4>
<div class="form-group w-75 m-0">
<div class="input-group">
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="product-picture"
accept="image/*">
<label id="product-picture-label"
class="custom-file-label @if(empty($product->picture_file_name)) d-none @endif"
for="product-picture">
{{ $product->picture_file_name }}
</label>
<label id="product-picture-label-none"
class="custom-file-label @if(!empty($product->picture_file_name)) d-none @endif"
for="product-picture">
{{ $__t('No file selected') }}
</label>
</div>
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-trash"
id="delete-current-product-picture-button"></i></span>
</div>
</div>
</div>
</div>
@if(!empty($product->picture_file_name))
<img id="current-product-picture"
data-src="{{ $U('/api/files/productpictures/' . base64_encode($product->picture_file_name) . '?force_serve_as=picture&best_fit_width=400') }}" data-src="{{ $U('/api/files/productpictures/' . base64_encode($product->picture_file_name) . '?force_serve_as=picture&best_fit_width=400') }}"
class="img-fluid img-thumbnail mt-2 lazy"></p> class="img-fluid img-thumbnail mt-2 lazy mb-5">
<p id="delete-current-product-picture-on-save-hint" <p id="delete-current-product-picture-on-save-hint"
class="form-text text-muted font-italic d-none">{{ $__t('The current picture will be deleted when you save the product') }}</p> class="form-text text-muted font-italic d-none mb-5">{{ $__t('The current picture will be deleted when you save the product') }}</p>
@else @else
<p id="no-current-product-picture-hint" <p id="no-current-product-picture-hint"
class="form-text text-muted font-italic">{{ $__t('No picture available') }}</p> class="form-text text-muted font-italic mb-5">{{ $__t('No picture available') }}</p>
@endif @endif
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -11,7 +11,16 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h2 class="title">@yield('title')</h2> <div class="title-related-links">
<h2 class="title">@yield('title')</h2>
<h2>
@if($product != null)
<span class="text-muted small">{{ $__t('Override for product') }} <strong>{{ $product->name }}</strong></span>
@else
<span class="text-muted small">{{ $__t('Default for QU') }} <strong>{{ $defaultQuUnit->name }}</strong></span>
@endif
</h2>
</div>
</div> </div>
</div> </div>
@@ -20,12 +29,6 @@
<div class="row"> <div class="row">
<div class="col-lg-6 col-xs-12"> <div class="col-lg-6 col-xs-12">
@if($product != null)
<h3 class="text-muted">{{ $__t('Override for product') }} <strong>{{ $product->name }}</strong></h3>
@else
<h3 class="text-muted">{{ $__t('Default for QU') }} <strong>{{ $defaultQuUnit->name }}</strong></h3>
@endif
<script> <script>
Grocy.EditMode = '{{ $mode }}'; Grocy.EditMode = '{{ $mode }}';
</script> </script>
@@ -92,15 +95,19 @@
'additionalCssClasses' => 'input-group-qu' 'additionalCssClasses' => 'input-group-qu'
)) ))
<div class="checkbox @if($mode == 'edit') d-none @endif"> <div class="form-group @if($mode == 'edit') d-none @endif">
<label for="create_inverse"> <div class="custom-control custom-checkbox">
<input type="checkbox" <input type="hidden"
id="create_inverse"
name="create_inverse:skip" name="create_inverse:skip"
checked> {{ $__t('Create inverse QU conversion') }} value="0">
<input @if($mode=='edit'
&&
$product->create_inverse == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="create_inverse" name="create_inverse:skip" value="1">
<label class="form-check-label custom-control-label"
for="create_inverse">{{ $__t('Create inverse QU conversion') }}</label>
<span id="qu-conversion-inverse-info" <span id="qu-conversion-inverse-info"
class="form-text text-info d-none"></span> class="form-text text-info d-none"></span>
</label> </div>
</div> </div>
@include('components.userfieldsform', array( @include('components.userfieldsform', array(

View File

@@ -82,8 +82,12 @@
'entity' => 'quantity_units' 'entity' => 'quantity_units'
)) ))
<button id="save-quantityunit-button" <small class="my-2 form-text text-muted @if($mode == 'edit') d-none @endif">{{ $__t('Save & continue to add conversions') }}</small>
class="btn btn-success">{{ $__t('Save') }}</button>
<button class="save-quantityunit-button btn btn-success mb-2"
data-location="continue">{{ $__t('Save & continue') }}</button>
<button class="save-quantityunit-button btn btn-info mb-2"
data-location="return">{{ $__t('Save & return to quantity units') }}</button>
@if(intval($pluralCount) > 2) @if(intval($pluralCount) > 2)
<button id="test-quantityunit-plural-forms-button" <button id="test-quantityunit-plural-forms-button"
@@ -93,53 +97,69 @@
</form> </form>
</div> </div>
<div class="col-lg-6 col-xs-12"> <div class="col-lg-6 col-xs-12 @if($mode == 'create') d-none @endif">
<h2> <div class="row">
{{ $__t('Default conversions') }} <div class="col">
<a id="qu-conversion-add-button" <div class="title-related-links">
class="btn btn-outline-dark" <h4>
href="#"> {{ $__t('Default conversions') }}
<i class="fas fa-plus"></i> {{ $__t('Add') }} </h4>
</a> <button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3"
</h2> type="button"
<h5 id="qu-conversion-headline-info" data-toggle="collapse"
class="text-muted font-italic"></h5> data-target="#related-links">
<table id="qu-conversions-table" <i class="fas fa-ellipsis-v"></i>
class="table table-sm table-striped nowrap w-100"> </button>
<thead> <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
<tr> id="related-links">
<th class="border-right"></th> <a class="btn btn-outline-primary btn-sm m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
<th>{{ $__t('Factor') }}</th> href="{{ $U('/quantityunitconversion/new?embedded&qu-unit=' . $quantityUnit->id ) }}">
<th>{{ $__t('Unit') }}</th> {{ $__t('Add') }}
</tr>
</thead>
<tbody class="d-none">
@if($mode == "edit")
@foreach($defaultQuConversions as $defaultQuConversion)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info qu-conversion-edit-button"
href="#"
data-qu-conversion-id="{{ $defaultQuConversion->id }}">
<i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-sm btn-danger qu-conversion-delete-button" </div>
href="#" </div>
data-qu-conversion-id="{{ $defaultQuConversion->id }}">
<i class="fas fa-trash"></i> <h5 id="qu-conversion-headline-info"
</a> class="text-muted font-italic"></h5>
</td>
<td> <table id="qu-conversions-table"
{{ $defaultQuConversion->factor }} class="table table-sm table-striped nowrap w-100">
</td> <thead>
<td> <tr>
{{ FindObjectInArrayByPropertyValue($quantityUnits, 'id', $defaultQuConversion->to_qu_id)->name }} <th class="border-right"></th>
</td> <th>{{ $__t('Factor') }}</th>
</tr> <th>{{ $__t('Unit') }}</th>
@endforeach </tr>
@endif </thead>
</tbody> <tbody class="d-none">
</table> @if($mode == "edit")
@foreach($defaultQuConversions as $defaultQuConversion)
<tr>
<td class="fit-content border-right">
<a class="btn btn-sm btn-info show-as-dialog-link"
href="{{ $U('/quantityunitconversion/' . $defaultQuConversion->id . '?embedded&qu-unit=' . $quantityUnit->id ) }}"
data-qu-conversion-id="{{ $defaultQuConversion->id }}">
<i class="fas fa-edit"></i>
</a>
<a class="btn btn-sm btn-danger qu-conversion-delete-button"
href="#"
data-qu-conversion-id="{{ $defaultQuConversion->id }}">
<i class="fas fa-trash"></i>
</a>
</td>
<td>
{{ $defaultQuConversion->factor }}
</td>
<td>
{{ FindObjectInArrayByPropertyValue($quantityUnits, 'id', $defaultQuConversion->to_qu_id)->name }}
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
@stop @stop

View File

@@ -61,34 +61,6 @@
<div class="invalid-feedback">{{ $__t('A name is required') }}</div> <div class="invalid-feedback">{{ $__t('A name is required') }}</div>
</div> </div>
<div class="form-group">
<label for="recipe-picture">
{{ $__t('Picture') }}
</label>
<div class="input-group">
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="recipe-picture"
accept="image/*">
<label id="recipe-picture-label"
class="custom-file-label @if(empty($recipe->picture_file_name)) d-none @endif"
for="recipe-picture">
{{ $recipe->picture_file_name }}
</label>
<label id="recipe-picture-label-none"
class="custom-file-label @if(!empty($recipe->picture_file_name)) d-none @endif"
for="recipe-picture">
{{ $__t('No file selected') }}
</label>
</div>
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-trash"
id="delete-current-recipe-picture-button"></i></span>
</div>
</div>
</div>
@php if($mode == 'edit') { $value = $recipe->base_servings; } else { $value = 1; } @endphp @php if($mode == 'edit') { $value = $recipe->base_servings; } else { $value = 1; } @endphp
@include('components.numberpicker', array( @include('components.numberpicker', array(
'id' => 'base_servings', 'id' => 'base_servings',
@@ -113,7 +85,7 @@
{{ $__t('Do not check against the shopping list when adding missing items to it') }}&nbsp; {{ $__t('Do not check against the shopping list when adding missing items to it') }}&nbsp;
<i class="fas fa-question-circle" <i class="fas fa-question-circle"
data-toggle="tooltip" data-toggle="tooltip"
title="{{ $__t('By default the amount to be added to the shopping list is `needed amount - stock amount - shopping list amount` - when this is enabled, it is only checked against the stock amount, not against what is already on the shopping list') }}"></i> title="{{ $__t('By default the amount to be added to the shopping list is "needed amount - stock amount - shopping list amount" - when this is enabled, it is only checked against the stock amount, not against what is already on the shopping list') }}"></i>
</label> </label>
</div> </div>
</div> </div>
@@ -149,21 +121,6 @@
</div> </div>
<div class="col-xs-12 col-md-5 pb-3 @if($mode == 'create') d-none @endif"> <div class="col-xs-12 col-md-5 pb-3 @if($mode == 'create') d-none @endif">
<div class="row">
<div class="col">
@if(!empty($recipe->picture_file_name))
<img id="current-recipe-picture"
data-src="{{ $U('/api/files/recipepictures/' . base64_encode($recipe->picture_file_name) . '?force_serve_as=picture&best_fit_width=400') }}"
class="img-fluid img-thumbnail mt-2 lazy mb-5">
<p id="delete-current-recipe-picture-on-save-hint"
class="form-text text-muted font-italic d-none mb-5">{{ $__t('The current picture will be deleted when you save the recipe') }}</p>
@else
<p id="no-current-recipe-picture-hint"
class="form-text text-muted font-italic mb-5">{{ $__t('No picture available') }}</p>
@endif
</div>
</div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="title-related-links"> <div class="title-related-links">
@@ -325,6 +282,50 @@
</table> </table>
</div> </div>
</div> </div>
<div class="row mt-5">
<div class="col">
<div class="title-related-links">
<h4>
{{ $__t('Picture') }}
</h4>
<div class="form-group w-75 m-0">
<div class="input-group">
<div class="custom-file">
<input type="file"
class="custom-file-input"
id="recipe-picture"
accept="image/*">
<label id="recipe-picture-label"
class="custom-file-label @if(empty($recipe->picture_file_name)) d-none @endif"
for="recipe-picture">
{{ $recipe->picture_file_name }}
</label>
<label id="recipe-picture-label-none"
class="custom-file-label @if(!empty($recipe->picture_file_name)) d-none @endif"
for="recipe-picture">
{{ $__t('No file selected') }}
</label>
</div>
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-trash"
id="delete-current-recipe-picture-button"></i></span>
</div>
</div>
</div>
</div>
@if(!empty($recipe->picture_file_name))
<img id="current-recipe-picture"
data-src="{{ $U('/api/files/recipepictures/' . base64_encode($recipe->picture_file_name) . '?force_serve_as=picture&best_fit_width=400') }}"
class="img-fluid img-thumbnail mt-2 lazy mb-5">
<p id="delete-current-recipe-picture-on-save-hint"
class="form-text text-muted font-italic d-none mb-5">{{ $__t('The current picture will be deleted when you save the recipe') }}</p>
@else
<p id="no-current-recipe-picture-hint"
class="form-text text-muted font-italic mb-5">{{ $__t('No picture available') }}</p>
@endif
</div>
</div>
</div> </div>
</div> </div>

View File

@@ -11,7 +11,12 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h2 class="title">@yield('title')</h2> <div class="title-related-links">
<h2 class="title">@yield('title')</h2>
<h2>
<span class="text-muted small">{{ $__t('Recipe') }} <strong>{{ $recipe->name }}</strong></span>
</h2>
</div>
</div> </div>
</div> </div>
@@ -19,8 +24,6 @@
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-6 col-xl-5 pb-3"> <div class="col-xs-12 col-md-6 col-xl-5 pb-3">
<h3 class="text-muted">{{ $__t('Recipe') }} <strong>{{ $recipe->name }}</strong></h3>
<script> <script>
Grocy.EditMode = '{{ $mode }}'; Grocy.EditMode = '{{ $mode }}';
Grocy.EditObjectParentId = {{ $recipe->id }}; Grocy.EditObjectParentId = {{ $recipe->id }};
@@ -45,15 +48,17 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-check form-group mb-1"> <div class="form-group">
<input type="hidden" <div class="custom-control custom-checkbox">
name="only_check_single_unit_in_stock" <input type="hidden"
value="0"> name="only_check_single_unit_in_stock"
<input @if($mode=='edit' value="0">
&& <input @if($mode=='edit'
$recipePos->only_check_single_unit_in_stock == 1) checked @endif class="form-check-input" type="checkbox" id="only_check_single_unit_in_stock" name="only_check_single_unit_in_stock" value="1"> &&
<label class="form-check-label" $recipePos->only_check_single_unit_in_stock == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="only_check_single_unit_in_stock" name="only_check_single_unit_in_stock" value="1">
for="only_check_single_unit_in_stock">{{ $__t('Only check if a single unit is in stock (a different quantity can then be used above)') }}</label> <label class="form-check-label custom-control-label"
for="only_check_single_unit_in_stock">{{ $__t('Only check if a single unit is in stock (a different quantity can then be used below)') }}</label>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -67,7 +72,9 @@
)) ))
<div class="form-group"> <div class="form-group">
<label for="variable_amount">{{ $__t('Variable amount') }}&nbsp;&nbsp;<span class="small text-muted">{{ $__t('When this is not empty, it will be shown instead of the amount entered above while the amount there will still be used for stock fulfillment checking') }}</span></label> <label for="variable_amount">{{ $__t('Variable amount') }}&nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('When this is not empty, it will be shown instead of the amount entered above while the amount there will still be used for stock fulfillment checking') }}"></i></label>
<input type="text" <input type="text"
class="form-control" class="form-control"
id="variable_amount" id="variable_amount"
@@ -75,19 +82,23 @@
value="@if($mode == 'edit'){{ $recipePos->variable_amount }}@endif"> value="@if($mode == 'edit'){{ $recipePos->variable_amount }}@endif">
</div> </div>
<div class="form-check mb-3"> <div class="form-group">
<input type="hidden" <div class="custom-control custom-checkbox">
name="not_check_stock_fulfillment" <input type="hidden"
value="0"> name="not_check_stock_fulfillment"
<input @if($mode=='edit' value="0">
&& <input @if($mode=='edit'
($recipePos->not_check_stock_fulfillment == 1 || FindObjectInArrayByPropertyValue($products, 'id', $recipePos->product_id)->not_check_stock_fulfillment_for_recipes == 1)) checked @endif class="form-check-input" type="checkbox" id="not_check_stock_fulfillment" name="not_check_stock_fulfillment" value="1"> &&
<label class="form-check-label" ($recipePos->not_check_stock_fulfillment == 1 || FindObjectInArrayByPropertyValue($products, 'id', $recipePos->product_id)->not_check_stock_fulfillment_for_recipes == 1)) checked @endif class="form-check-input custom-control-input" type="checkbox" id="not_check_stock_fulfillment" name="not_check_stock_fulfillment" value="1">
for="not_check_stock_fulfillment">{{ $__t('Disable stock fulfillment checking for this ingredient') }}</label> <label class="form-check-label custom-control-label"
for="not_check_stock_fulfillment">{{ $__t('Disable stock fulfillment checking for this ingredient') }}</label>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ingredient_group">{{ $__t('Group') }}&nbsp;&nbsp;<span class="small text-muted">{{ $__t('This will be used as a headline to group ingredients together') }}</span></label> <label for="ingredient_group">{{ $__t('Group') }}&nbsp;<i class="fas fa-question-circle"
data-toggle="tooltip"
title="{{ $__t('This will be used as a headline to group ingredients together') }}"></i></label>
<input type="text" <input type="text"
class="form-control" class="form-control"
id="ingredient_group" id="ingredient_group"

View File

@@ -67,7 +67,7 @@
</div> </div>
<div class="col"> <div class="col">
<div class="float-right"> <div class="float-right mt-1">
<a id="clear-filter-button" <a id="clear-filter-button"
class="btn btn-sm btn-outline-info" class="btn btn-sm btn-outline-info"
href="#"> href="#">

View File

@@ -90,11 +90,12 @@
value="1"> value="1">
@endif @endif
</div> </div>
<div id="related-links" <div class="border-top border-bottom my-2 py-1">
class="border-top border-bottom my-2 py-1 collapse"> <div id="table-filter-row"
<div data-status-filter="belowminstockamount" data-status-filter="belowminstockamount"
class="normal-message status-filter-message responsive-button @if(!GROCY_FEATURE_FLAG_STOCK) d-none @endif"><span class="d-block d-md-none">{{count($missingProducts)}} <i class="fas fa-exclamation-circle"></i></span><span class="d-none d-md-block">{{ $__n(count($missingProducts), '%s product is below defined min. stock amount', '%s products are below defined min. stock amount') }}</span></div> class="collapse d-md-inline-block normal-message status-filter-message responsive-button @if(!GROCY_FEATURE_FLAG_STOCK) d-none @endif"><span class="d-block d-md-none">{{count($missingProducts)}} <i class="fas fa-exclamation-circle"></i></span><span class="d-none d-md-block">{{ $__n(count($missingProducts), '%s product is below defined min. stock amount', '%s products are below defined min. stock amount') }}</span></div>
<div class="float-right mt-2"> <div id="related-links"
class="float-right mt-2 collapse d-md-block">
<a class="btn btn-primary responsive-button btn-sm mb-1 show-as-dialog-link" <a class="btn btn-primary responsive-button btn-sm mb-1 show-as-dialog-link"
href="{{ $U('/shoppinglistitem/new?embedded&list=' . $selectedShoppingListId) }}"> href="{{ $U('/shoppinglistitem/new?embedded&list=' . $selectedShoppingListId) }}">
{{ $__t('Add item') }} {{ $__t('Add item') }}

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
href="{{ $U('/shoppinglocation/new') }}"> href="{{ $U('/shoppinglocation/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
<a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right"
@@ -84,8 +84,8 @@
@foreach($shoppinglocations as $shoppinglocation) @foreach($shoppinglocations as $shoppinglocation)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm" <a class="btn btn-info btn-sm show-as-dialog-link"
href="{{ $U('/shoppinglocation/') }}{{ $shoppinglocation->id }}"> href="{{ $U('/shoppinglocation/') }}{{ $shoppinglocation->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm shoppinglocation-delete-button" <a class="btn btn-danger btn-sm shoppinglocation-delete-button"

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right" <a class="btn btn-primary responsive-button m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
href="{{ $U('/taskcategory/new') }}"> href="{{ $U('/taskcategory/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
<a class="btn btn-outline-secondary" <a class="btn btn-outline-secondary"
@@ -84,8 +84,8 @@
@foreach($taskCategories as $taskCategory) @foreach($taskCategories as $taskCategory)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm" <a class="btn btn-info btn-sm show-as-dialog-link"
href="{{ $U('/taskcategory/') }}{{ $taskCategory->id }}"> href="{{ $U('/taskcategory/') }}{{ $taskCategory->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm task-category-delete-button" <a class="btn btn-danger btn-sm task-category-delete-button"

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button" <a class="btn btn-primary responsive-button show-as-dialog-link"
href="{{ $U('/userentity/new') }}"> href="{{ $U('/userentity/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
</div> </div>
@@ -75,8 +75,8 @@
@foreach($userentities as $userentity) @foreach($userentities as $userentity)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm" <a class="btn btn-info btn-sm show-as-dialog-link"
href="{{ $U('/userentity/') }}{{ $userentity->id }}"> href="{{ $U('/userentity/') }}{{ $userentity->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm userentity-delete-button" <a class="btn btn-danger btn-sm userentity-delete-button"

View File

@@ -68,14 +68,14 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="show_in_sidebar_menu" name="show_in_sidebar_menu"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$userentity->show_in_sidebar_menu == 1) checked @endif class="form-check-input" type="checkbox" id="show_in_sidebar_menu" name="show_in_sidebar_menu" value="1"> $userentity->show_in_sidebar_menu == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="show_in_sidebar_menu" name="show_in_sidebar_menu" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="show_in_sidebar_menu">{{ $__t('Show in sidebar menu') }}</label> for="show_in_sidebar_menu">{{ $__t('Show in sidebar menu') }}</label>
</div> </div>
</div> </div>

View File

@@ -97,14 +97,14 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input type="hidden" <input type="hidden"
name="show_as_column_in_tables" name="show_as_column_in_tables"
value="0"> value="0">
<input @if($mode=='edit' <input @if($mode=='edit'
&& &&
$userfield->show_as_column_in_tables == 1) checked @endif class="form-check-input" type="checkbox" id="show_as_column_in_tables" name="show_as_column_in_tables" value="1"> $userfield->show_as_column_in_tables == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="show_as_column_in_tables" name="show_as_column_in_tables" value="1">
<label class="form-check-label" <label class="form-check-label custom-control-label"
for="show_as_column_in_tables">{{ $__t('Show as column in tables') }}</label> for="show_as_column_in_tables">{{ $__t('Show as column in tables') }}</label>
</div> </div>
</div> </div>

View File

@@ -25,8 +25,8 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button" <a class="btn btn-primary responsive-button show-as-dialog-link"
href="{{ $U('/userfield/new') }}"> href="{{ $U('/userfield/new?embedded') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>
</div> </div>
@@ -91,8 +91,8 @@
@foreach($userfields as $userfield) @foreach($userfields as $userfield)
<tr> <tr>
<td class="fit-content border-right"> <td class="fit-content border-right">
<a class="btn btn-info btn-sm" <a class="btn btn-info btn-sm show-as-dialog-link"
href="{{ $U('/userfield/') }}{{ $userfield->id }}"> href="{{ $U('/userfield/') }}{{ $userfield->id }}?embedded">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm userfield-delete-button" <a class="btn btn-danger btn-sm userfield-delete-button"

View File

@@ -8,8 +8,10 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="title-related-links"> <div class="title-related-links">
<h2 class="title"> <h2 class="title mr-2 order-0">
@yield('title') @yield('title')
</h2>
<h2 class="mb-0 mr-auto order-3 order-md-1 width-xs-sm-100">
<span class="text-muted small">{{ $userentity->description }}</span> <span class="text-muted small">{{ $userentity->description }}</span>
</h2> </h2>
<div class="float-right"> <div class="float-right">
@@ -28,7 +30,7 @@
</div> </div>
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right" <div class="related-links collapse d-md-flex order-2 width-xs-sm-100 m-1 mt-md-0 mb-md-0 float-right"
id="related-links"> id="related-links">
<a class="btn btn-primary responsive-button" <a class="btn btn-primary responsive-button mr-1"
href="{{ $U('/userobject/' . $userentity->name . '/new') }}"> href="{{ $U('/userobject/' . $userentity->name . '/new') }}">
{{ $__t('Add') }} {{ $__t('Add') }}
</a> </a>