2019-07-06 14:48:46 +02:00
var firstRender = true ;
2019-07-06 20:19:21 +02:00
var firstDay = null ;
if ( ! Grocy . CalendarFirstDayOfWeek . isEmpty ( ) )
{
firstDay = parseInt ( Grocy . CalendarFirstDayOfWeek ) ;
}
2019-07-06 14:48:46 +02:00
var calendar = $ ( "#calendar" ) . fullCalendar ( {
2019-05-06 19:38:47 +02:00
"themeSystem" : "bootstrap4" ,
"header" : {
"left" : "title" ,
"center" : "" ,
"right" : "prev,today,next"
} ,
"weekNumbers" : false ,
"eventLimit" : true ,
"eventSources" : fullcalendarEventSources ,
2019-09-24 09:21:57 +02:00
"defaultView" : ( $ ( window ) . width ( ) < 768 ) ? "basicDay" : "basicWeek" ,
2019-07-06 20:19:21 +02:00
"firstDay" : firstDay ,
2019-05-06 19:38:47 +02:00
"viewRender" : function ( view )
{
2019-07-06 14:48:46 +02:00
if ( firstRender )
{
firstRender = false
}
else
{
UpdateUriParam ( "week" , view . start . format ( "YYYY-MM-DD" ) ) ;
}
2019-09-24 01:13:42 -05:00
2020-01-23 20:59:19 +01:00
$ ( ".fc-day-header" ) . prepend ( ' \
< div class = "btn-group mr-2 my-1" > \
< button type = "button" class = "btn btn-outline-dark btn-xs add-recipe-button" "><i class=" fas fa - plus " > < / i > < / a > < / b u t t o n > \
< button type = "button" class = "btn btn-outline-dark btn-xs dropdown-toggle dropdown-toggle-split" data - toggle = "dropdown" > < / b u t t o n > \
< div class = "dropdown-menu" > \
< a class = "dropdown-item add-note-button" href = "#" > ' + __t(' Add note ') + ' < / a > \
2020-01-25 11:51:00 +01:00
< a class = "dropdown-item add-product-button" href = "#" > ' + __t(' Add product ') + ' < / a > \
2020-01-23 20:59:19 +01:00
< / d i v > \
< / d i v > ' ) ;
2019-05-07 19:48:14 +02:00
2020-01-21 21:54:22 +01:00
var weekRecipeName = view . start . year ( ) . toString ( ) + "-" + ( ( view . start . week ( ) - 1 ) . toString ( ) . padStart ( 2 , "0" ) ) . toString ( ) ;
2019-05-07 19:48:14 +02:00
var weekRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , weekRecipeName ) ;
2020-01-21 21:54:22 +01:00
2019-05-07 19:48:14 +02:00
var weekCosts = 0 ;
var weekRecipeOrderMissingButtonHtml = "" ;
2019-07-06 20:02:40 +02:00
var weekRecipeConsumeButtonHtml = "" ;
2019-05-07 19:48:14 +02:00
if ( weekRecipe !== null )
{
2019-12-19 13:07:13 -06:00
var weekCostsHtml = "" ;
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
weekCosts = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , weekRecipe . id ) . costs ;
weekCostsHtml = _ _t ( "Week costs" ) + ': <span class="locale-number locale-number-currency">' + weekCosts . toString ( ) + "</span> " ;
}
2019-05-07 19:48:14 +02:00
var weekRecipeOrderMissingButtonDisabledClasses = "" ;
if ( FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , weekRecipe . id ) . need _fulfilled _with _shopping _list == 1 )
{
weekRecipeOrderMissingButtonDisabledClasses = "disabled" ;
}
2019-07-06 20:02:40 +02:00
var weekRecipeConsumeButtonDisabledClasses = "" ;
if ( FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , weekRecipe . id ) . need _fulfilled == 0 )
{
weekRecipeConsumeButtonDisabledClasses = "disabled" ;
}
2019-05-07 19:48:14 +02:00
weekRecipeOrderMissingButtonHtml = '<a class="ml-1 btn btn-outline-primary btn-xs recipe-order-missing-button ' + weekRecipeOrderMissingButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + _ _t ( "Put missing products on shopping list" ) + '" data-recipe-id="' + weekRecipe . id . toString ( ) + '" data-recipe-name="' + weekRecipe . name + '" data-recipe-type="' + weekRecipe . type + '"><i class="fas fa-cart-plus"></i></a>'
2019-07-06 20:02:40 +02:00
weekRecipeConsumeButtonHtml = '<a class="ml-1 btn btn-outline-success btn-xs recipe-consume-button ' + weekRecipeConsumeButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + _ _t ( "Consume all ingredients needed by this recipe" ) + '" data-recipe-id="' + weekRecipe . id . toString ( ) + '" data-recipe-name="' + weekRecipe . name + '" data-recipe-type="' + weekRecipe . type + '"><i class="fas fa-utensils"></i></a>'
2019-05-07 19:48:14 +02:00
}
2019-12-19 13:07:13 -06:00
$ ( ".fc-header-toolbar .fc-center" ) . html ( "<h4>" + weekCostsHtml + weekRecipeOrderMissingButtonHtml + weekRecipeConsumeButtonHtml + "</h4>" ) ;
2019-05-06 19:38:47 +02:00
} ,
"eventRender" : function ( event , element )
{
element . removeClass ( "fc-event" ) ;
element . addClass ( "text-center" ) ;
2020-01-23 21:57:47 +01:00
element . attr ( "data-meal-plan-entry" , event . mealPlanEntry ) ;
var mealPlanEntry = JSON . parse ( event . mealPlanEntry ) ;
2019-05-07 19:48:14 +02:00
2020-01-23 20:59:19 +01:00
if ( event . type == "recipe" )
2019-05-07 19:48:14 +02:00
{
2020-01-23 20:59:19 +01:00
var recipe = JSON . parse ( event . recipe ) ;
if ( recipe === null || recipe === undefined )
{
return false ;
}
2019-05-07 19:48:14 +02:00
2020-01-23 20:59:19 +01:00
var resolvedRecipe = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , recipe . id ) ;
2019-07-06 20:02:40 +02:00
2020-01-23 20:59:19 +01:00
element . attr ( "data-recipe" , event . recipe ) ;
2019-05-07 19:48:14 +02:00
2020-01-23 20:59:19 +01:00
var recipeOrderMissingButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled _with _shopping _list == 1 )
{
recipeOrderMissingButtonDisabledClasses = "disabled" ;
}
2019-09-24 01:13:42 -05:00
2020-01-23 20:59:19 +01:00
var recipeConsumeButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled == 0 )
{
recipeConsumeButtonDisabledClasses = "disabled" ;
}
var fulfillmentInfoHtml = _ _t ( 'Enough in stock' ) ;
var fulfillmentIconHtml = '<i class="fas fa-check text-success"></i>' ;
if ( resolvedRecipe . need _fulfilled != 1 )
{
fulfillmentInfoHtml = _ _t ( 'Not enough in stock' ) ;
var fulfillmentIconHtml = '<i class="fas fa-times text-danger"></i>' ;
}
var costsAndCaloriesPerServing = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
costsAndCaloriesPerServing = '<h5 class="small text-truncate"><span class="locale-number locale-number-currency">' + resolvedRecipe . costs + '</span> / <span class="locale-number locale-number-generic">' + resolvedRecipe . calories + '</span> kcal ' + _ _t ( 'per serving' ) + '<h5>' ;
}
else
{
costsAndCaloriesPerServing = '<h5 class="small text-truncate"><span class="locale-number locale-number-generic">' + resolvedRecipe . calories + '</span> kcal ' + _ _t ( 'per serving' ) + '<h5>' ;
}
element . html ( ' \
< div > \
< h5 class = "text-truncate" > ' + recipe.name + ' < h5 > \
2020-01-23 21:57:47 +01:00
< h5 class = "small text-truncate" > ' + __n(mealPlanEntry.recipe_servings, "%s serving", "%s servings") + ' < / h 5 > \
2020-01-23 20:59:19 +01:00
< h5 class = "small timeago-contextual text-truncate" > ' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + ' < / h 5 > \
' + costsAndCaloriesPerServing + ' \
< h5 > \
< a class = "ml-1 btn btn-outline-danger btn-xs remove-recipe-button" href = "#" > < i class = "fas fa-trash" > < / i > < / a > \
< a class = "ml-1 btn btn-outline-primary btn-xs recipe-order-missing-button ' + recipeOrderMissingButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Put missing products on shopping list ") + '" data - recipe - id = "' + recipe.id.toString() + '" data - recipe - name = "' + recipe.name + '" data - recipe - type = "' + recipe.type + '" > < i class = "fas fa-cart-plus" > < / i > < / a > \
< a class = "ml-1 btn btn-outline-success btn-xs recipe-consume-button ' + recipeConsumeButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Consume all ingredients needed by this recipe ") + '" data - recipe - id = "' + recipe.id.toString() + '" data - recipe - name = "' + recipe.name + '" data - recipe - type = "' + recipe.type + '" > < i class = "fas fa-utensils" > < / i > < / a > \
< a class = "ml-1 btn btn-outline-secondary btn-xs recipe-popup-button" href = "#" data - toggle = "tooltip" title = "' + __t(" Display recipe ") + '" data - recipe - id = "' + recipe.id.toString() + '" data - recipe - name = "' + recipe.name + '" data - recipe - type = "' + recipe.type + '" > < i class = "fas fa-eye" > < / i > < / a > \
< / h 5 > \
< / d i v > ' ) ;
2020-01-21 22:44:04 +01:00
2020-01-23 20:59:19 +01:00
if ( recipe . picture _file _name && ! recipe . picture _file _name . isEmpty ( ) )
2020-01-21 22:44:04 +01:00
{
2020-01-23 20:59:19 +01:00
element . html ( element . html ( ) + '<div class="mx-auto"><img data-src="' + U ( "/api/files/recipepictures/" ) + btoa ( recipe . picture _file _name ) + '?force_serve_as=picture&best_fit_width=400" class="img-fluid lazy"></div>' )
}
2020-01-21 22:44:04 +01:00
2020-01-23 20:59:19 +01:00
var dayRecipeName = event . start . format ( "YYYY-MM-DD" ) ;
if ( ! $ ( "#day-summary-" + dayRecipeName ) . length ) // This runs for every event/recipe, so maybe multiple times per day, so only add the day summary once
{
var dayRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , dayRecipeName ) ;
if ( dayRecipe != null )
2020-01-21 22:44:04 +01:00
{
2020-01-23 20:59:19 +01:00
var dayRecipeResolved = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , dayRecipe . id ) ;
var costsAndCaloriesPerDay = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-currency">' + dayRecipeResolved . costs + '</span> / <span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> kcal ' + _ _t ( 'per day' ) + '<h5>' ;
}
else
{
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> kcal ' + _ _t ( 'per day' ) + '<h5>' ;
}
$ ( ".fc-day-header[data-date='" + dayRecipeName + "']" ) . append ( '<h5 id="day-summary-' + dayRecipeName + '" class="small text-truncate border-top pt-1 pb-0">' + costsAndCaloriesPerDay + '</h5>' ) ;
2020-01-21 22:44:04 +01:00
}
}
}
2020-01-25 11:51:00 +01:00
if ( event . type == "product" )
{
var productDetails = JSON . parse ( event . productDetails ) ;
if ( productDetails === null || productDetails === undefined )
{
return false ;
}
if ( productDetails . last _price === null )
{
productDetails . last _price = 0 ;
}
element . attr ( "data-product-details" , event . productDetails ) ;
var productOrderMissingButtonDisabledClasses = "disabled" ;
if ( productDetails . stock _amount _aggregated < mealPlanEntry . product _amount )
{
productOrderMissingButtonDisabledClasses = "" ;
}
var productConsumeButtonDisabledClasses = "disabled" ;
if ( productDetails . stock _amount _aggregated >= mealPlanEntry . product _amount )
{
productConsumeButtonDisabledClasses = "" ;
}
var fulfillmentInfoHtml = _ _t ( 'Enough in stock' ) ;
var fulfillmentIconHtml = '<i class="fas fa-check text-success"></i>' ;
if ( productDetails . stock _amount _aggregated < mealPlanEntry . product _amount )
{
fulfillmentInfoHtml = _ _t ( 'Not enough in stock' ) ;
var fulfillmentIconHtml = '<i class="fas fa-times text-danger"></i>' ;
}
var costsAndCaloriesPerServing = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
costsAndCaloriesPerServing = '<h5 class="small text-truncate"><span class="locale-number locale-number-currency">' + productDetails . last _price * mealPlanEntry . product _amount + '</span> / <span class="locale-number locale-number-generic">' + productDetails . product . calories * mealPlanEntry . product _amount + '</span> kcal ' + '<h5>' ;
}
else
{
costsAndCaloriesPerServing = '<h5 class="small text-truncate"><span class="locale-number locale-number-generic">' + productDetails . product . calories * mealPlanEntry . product _amount + '</span> kcal ' + '<h5>' ;
}
element . html ( ' \
< div > \
< h5 class = "text-truncate" > ' + productDetails.product.name + ' < h5 > \
< h5 class = "small text-truncate" > < span class = "locale-number locale-number-quantity" ' + jsonData.product_amount + "</span>" + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_purchase.name, productDetails.quantity_unit_purchase.name_plural) + ' < / h 5 > \
< h5 class = "small timeago-contextual text-truncate" > ' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + ' < / h 5 > \
' + costsAndCaloriesPerServing + ' \
< h5 > \
< a class = "ml-1 btn btn-outline-danger btn-xs remove-product-button" href = "#" > < i class = "fas fa-trash" > < / i > < / a > \
<!-- TODO < a class = "ml-1 btn btn-outline-primary btn-xs product-order-missing-button ' + productOrderMissingButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Put missing products on shopping list ") + '" data - product - id = "' + productDetails.product.id.toString() + '" data - product - name = "' + productDetails.product.name + '" data - product - amount = "' + mealPlanEntry.product_amount + '" > < i class = "fas fa-cart-plus" > < / i > < / a > \
< a class = "ml-1 btn btn-outline-success btn-xs product-consume-button ' + productConsumeButtonDisabledClasses + '" href = "#" data - toggle = "tooltip" title = "' + __t(" Consume all ingredients needed by this recipe ") + '" data - product - id = "' + productDetails.product.id.toString() + '" data - product - name = "' + productDetails.product.name + '" data - product - amount = "' + mealPlanEntry.product_amount + '" > < i class = "fas fa-utensils" > < / i > < / a > \
-- > < / h 5 > \
< / d i v > ' ) ;
if ( productDetails . product . picture _file _name && ! productDetails . product . picture _file _name . isEmpty ( ) )
{
element . html ( element . html ( ) + '<div class="mx-auto"><img data-src="' + U ( "/api/files/productpictures/" ) + btoa ( productDetails . product . picture _file _name ) + '?force_serve_as=picture&best_fit_width=400" class="img-fluid lazy"></div>' )
}
var dayRecipeName = event . start . format ( "YYYY-MM-DD" ) ;
if ( ! $ ( "#day-summary-" + dayRecipeName ) . length ) // This runs for every event/recipe, so maybe multiple times per day, so only add the day summary once
{
var dayRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , dayRecipeName ) ;
if ( dayRecipe != null )
{
var dayRecipeResolved = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , dayRecipe . id ) ;
var costsAndCaloriesPerDay = ""
if ( Grocy . FeatureFlags . GROCY _FEATURE _FLAG _STOCK _PRICE _TRACKING )
{
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-currency">' + dayRecipeResolved . costs + '</span> / <span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> kcal ' + _ _t ( 'per day' ) + '<h5>' ;
}
else
{
costsAndCaloriesPerDay = '<h5 class="small text-truncate"><span class="locale-number locale-number-generic">' + dayRecipeResolved . calories + '</span> kcal ' + _ _t ( 'per day' ) + '<h5>' ;
}
$ ( ".fc-day-header[data-date='" + dayRecipeName + "']" ) . append ( '<h5 id="day-summary-' + dayRecipeName + '" class="small text-truncate border-top pt-1 pb-0">' + costsAndCaloriesPerDay + '</h5>' ) ;
}
}
}
2020-01-23 20:59:19 +01:00
else if ( event . type == "note" )
{
element . html ( ' \
< div > \
2020-01-23 21:57:47 +01:00
< h5 class = "text-truncate" > ' + mealPlanEntry.note + ' < h5 > \
2020-01-23 20:59:19 +01:00
< h5 > \
< a class = "ml-1 btn btn-outline-danger btn-xs remove-note-button" href = "#" > < i class = "fas fa-trash" > < / i > < / a > \
< / h 5 > \
< / d i v > ' ) ;
}
2019-05-07 19:48:14 +02:00
} ,
"eventAfterAllRender" : function ( view )
{
RefreshLocaleNumberDisplay ( ) ;
2019-09-18 13:59:37 +02:00
LoadImagesLazy ( ) ;
2019-09-26 13:14:24 +02:00
$ ( '[data-toggle="tooltip"]' ) . tooltip ( ) ;
2019-07-06 14:48:46 +02:00
if ( GetUriParam ( "week" ) !== undefined )
{
$ ( "#calendar" ) . fullCalendar ( "gotoDate" , GetUriParam ( "week" ) ) ;
}
2019-05-07 19:48:14 +02:00
} ,
2019-05-06 19:38:47 +02:00
} ) ;
$ ( document ) . on ( "click" , ".add-recipe-button" , function ( e )
{
2020-01-23 20:59:19 +01:00
var day = $ ( this ) . parent ( ) . parent ( ) . data ( "date" ) ;
2019-05-06 19:38:47 +02:00
$ ( "#add-recipe-modal-title" ) . text ( _ _t ( "Add recipe to %s" , day . toString ( ) ) ) ;
$ ( "#day" ) . val ( day . toString ( ) ) ;
Grocy . Components . RecipePicker . Clear ( ) ;
$ ( "#add-recipe-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-recipe-form" ) ;
} ) ;
2020-01-23 20:59:19 +01:00
$ ( document ) . on ( "click" , ".add-note-button" , function ( e )
{
var day = $ ( this ) . parent ( ) . parent ( ) . parent ( ) . data ( "date" ) ;
$ ( "#add-note-modal-title" ) . text ( _ _t ( "Add note to %s" , day . toString ( ) ) ) ;
$ ( "#day" ) . val ( day . toString ( ) ) ;
$ ( "#note" ) . val ( "" ) ;
$ ( "#add-note-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-note-form" ) ;
} ) ;
2020-01-25 11:51:00 +01:00
$ ( document ) . on ( "click" , ".add-product-button" , function ( e )
{
var day = $ ( this ) . parent ( ) . parent ( ) . parent ( ) . data ( "date" ) ;
$ ( "#add-product-modal-title" ) . text ( _ _t ( "Add product to %s" , day . toString ( ) ) ) ;
$ ( "#day" ) . val ( day . toString ( ) ) ;
Grocy . Components . ProductPicker . Clear ( ) ;
$ ( "#add-product-modal" ) . modal ( "show" ) ;
Grocy . FrontendHelpers . ValidateForm ( "add-product-form" ) ;
} ) ;
2019-05-06 19:38:47 +02:00
$ ( "#add-recipe-modal" ) . on ( "shown.bs.modal" , function ( e )
{
Grocy . Components . RecipePicker . GetInputElement ( ) . focus ( ) ;
} )
2020-01-23 20:59:19 +01:00
$ ( "#add-note-modal" ) . on ( "shown.bs.modal" , function ( e )
{
$ ( "#note" ) . focus ( ) ;
} )
2020-01-25 11:51:00 +01:00
$ ( "#add-product-modal" ) . on ( "shown.bs.modal" , function ( e )
{
Grocy . Components . ProductPicker . GetInputElement ( ) . focus ( ) ;
} )
$ ( document ) . on ( "click" , ".remove-recipe-button, .remove-note-button, .remove-product-button" , function ( e )
2019-05-06 19:38:47 +02:00
{
2019-06-09 09:10:29 +02:00
var mealPlanEntry = JSON . parse ( $ ( this ) . parents ( ".fc-h-event:first" ) . attr ( "data-meal-plan-entry" ) ) ;
2019-05-06 19:38:47 +02:00
Grocy . Api . Delete ( 'objects/meal_plan/' + mealPlanEntry . id . toString ( ) , { } ,
function ( result )
{
2019-07-06 13:55:29 +02:00
window . location . reload ( ) ;
2019-05-06 19:38:47 +02:00
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-recipe-button' ) . on ( 'click' , function ( e )
2020-01-23 20:59:19 +01:00
{
2020-01-25 11:51:00 +01:00
e . preventDefault ( ) ;
2020-01-23 20:59:19 +01:00
2020-01-25 11:51:00 +01:00
if ( document . getElementById ( "add-recipe-form" ) . checkValidity ( ) === false ) //There is at least one validation error
{
return false ;
}
Grocy . Api . Post ( 'objects/meal_plan' , $ ( '#add-recipe-form' ) . serializeJSON ( ) ,
2020-01-23 20:59:19 +01:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-note-button' ) . on ( 'click' , function ( e )
2019-05-06 19:38:47 +02:00
{
e . preventDefault ( ) ;
2020-01-25 11:51:00 +01:00
if ( document . getElementById ( "add-note-form" ) . checkValidity ( ) === false ) //There is at least one validation error
2019-05-06 19:38:47 +02:00
{
return false ;
}
2020-01-25 11:51:00 +01:00
var jsonData = $ ( '#add-note-form' ) . serializeJSON ( ) ;
jsonData . day = $ ( "#day" ) . val ( ) ;
Grocy . Api . Post ( 'objects/meal_plan' , jsonData ,
2019-05-06 19:38:47 +02:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2020-01-25 11:51:00 +01:00
$ ( '#save-add-product-button' ) . on ( 'click' , function ( e )
2020-01-23 20:59:19 +01:00
{
e . preventDefault ( ) ;
2020-01-25 11:51:00 +01:00
if ( document . getElementById ( "add-product-form" ) . checkValidity ( ) === false ) //There is at least one validation error
2020-01-23 20:59:19 +01:00
{
return false ;
}
2020-01-25 11:51:00 +01:00
var jsonData = $ ( '#add-product-form' ) . serializeJSON ( ) ;
2020-01-23 20:59:19 +01:00
jsonData . day = $ ( "#day" ) . val ( ) ;
2020-01-25 11:51:00 +01:00
delete jsonData . display _amount ;
jsonData . product _amount = jsonData . amount ;
delete jsonData . amount ;
jsonData . product _qu _id = jsonData . qu _id ;
delete jsonData . qu _id ;
2020-01-23 21:57:47 +01:00
Grocy . Api . Post ( 'objects/meal_plan' , jsonData ,
2020-01-23 20:59:19 +01:00
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
2019-05-06 19:38:47 +02:00
Grocy . Components . RecipePicker . GetInputElement ( ) . keydown ( function ( event )
{
if ( event . keyCode === 13 ) //Enter
{
event . preventDefault ( ) ;
if ( document . getElementById ( "add-recipe-form" ) . checkValidity ( ) === false ) //There is at least one validation error
{
return false ;
}
else
{
$ ( "#save-add-recipe-button" ) . click ( ) ;
}
}
} ) ;
2019-05-07 19:48:14 +02:00
$ ( document ) . on ( "keyodwn" , "#servings" , function ( e )
{
if ( event . keyCode === 13 ) //Enter
{
event . preventDefault ( ) ;
if ( document . getElementById ( "add-recipe-form" ) . checkValidity ( ) === false ) //There is at least one validation error
{
return false ;
}
else
{
$ ( "#save-add-recipe-button" ) . click ( ) ;
}
}
} ) ;
$ ( document ) . on ( 'click' , '.recipe-order-missing-button' , function ( e )
{
2019-09-26 13:14:24 +02:00
// Remove the focus from the current button
// to prevent that the tooltip stays until clicked anywhere else
document . activeElement . blur ( ) ;
2019-05-07 19:48:14 +02:00
var objectName = $ ( e . currentTarget ) . attr ( 'data-recipe-name' ) ;
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
var button = $ ( this ) ;
bootbox . confirm ( {
message : _ _t ( 'Are you sure to put all missing ingredients for recipe "%s" on the shopping list?' , objectName ) ,
2019-09-24 10:24:47 +02:00
closeButton : false ,
2019-05-07 19:48:14 +02:00
buttons : {
confirm : {
label : _ _t ( 'Yes' ) ,
className : 'btn-success'
} ,
cancel : {
label : _ _t ( 'No' ) ,
className : 'btn-danger'
}
} ,
callback : function ( result )
{
if ( result === true )
{
Grocy . FrontendHelpers . BeginUiBusy ( ) ;
Grocy . Api . Post ( 'recipes/' + objectId + '/add-not-fulfilled-products-to-shoppinglist' , { } ,
function ( result )
{
if ( button . attr ( "data-recipe-type" ) == "normal" )
{
button . addClass ( "disabled" ) ;
Grocy . FrontendHelpers . EndUiBusy ( ) ;
}
else
{
window . location . reload ( ) ;
}
} ,
function ( xhr )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
console . error ( xhr ) ;
}
) ;
}
}
} ) ;
} ) ;
2019-07-06 20:02:40 +02:00
$ ( document ) . on ( 'click' , '.recipe-consume-button' , function ( e )
{
2019-09-26 13:14:24 +02:00
// Remove the focus from the current button
// to prevent that the tooltip stays until clicked anywhere else
document . activeElement . blur ( ) ;
2019-07-06 20:02:40 +02:00
var objectName = $ ( e . currentTarget ) . attr ( 'data-recipe-name' ) ;
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
2019-09-24 01:13:42 -05:00
2019-07-06 20:02:40 +02:00
bootbox . confirm ( {
message : _ _t ( '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)?' , objectName ) ,
2019-09-24 10:24:47 +02:00
closeButton : false ,
2019-07-06 20:02:40 +02:00
buttons : {
confirm : {
label : _ _t ( 'Yes' ) ,
className : 'btn-success'
} ,
cancel : {
label : _ _t ( 'No' ) ,
className : 'btn-danger'
}
} ,
callback : function ( result )
{
if ( result === true )
{
Grocy . FrontendHelpers . BeginUiBusy ( ) ;
Grocy . Api . Post ( 'recipes/' + objectId + '/consume' , { } ,
function ( result )
{
Grocy . FrontendHelpers . EndUiBusy ( ) ;
toastr . success ( _ _t ( 'Removed all ingredients of recipe "%s" from stock' , objectName ) ) ;
} ,
function ( xhr )
{
toastr . warning ( _ _t ( 'Not all ingredients of recipe "%s" are in stock, nothing removed' , objectName ) ) ;
Grocy . FrontendHelpers . EndUiBusy ( ) ;
console . error ( xhr ) ;
}
) ;
}
}
} ) ;
} ) ;
2019-09-24 01:13:42 -05:00
$ ( document ) . on ( "click" , ".recipe-popup-button" , function ( e )
{
2019-09-26 13:14:24 +02:00
// Remove the focus from the current button
// to prevent that the tooltip stays until clicked anywhere else
document . activeElement . blur ( ) ;
2019-09-24 01:13:42 -05:00
var objectId = $ ( e . currentTarget ) . attr ( 'data-recipe-id' ) ;
bootbox . dialog ( {
2019-09-24 08:35:30 +02:00
message : '<iframe height="650px" class="embed-responsive" src="' + U ( "/recipes?embedded&recipe=" ) + objectId + '#fullscreen"></iframe>' ,
size : 'extra-large' ,
2019-09-24 01:13:42 -05:00
backdrop : true ,
closeButton : false ,
buttons : {
cancel : {
2019-09-24 08:35:30 +02:00
label : _ _t ( 'Close' ) ,
2019-09-24 01:13:42 -05:00
className : 'btn-secondary responsive-button' ,
callback : function ( )
{
bootbox . hideAll ( ) ;
}
}
}
} ) ;
} ) ;
2019-09-24 09:21:57 +02:00
$ ( window ) . on ( "resize" , function ( )
{
// Automatically switch the calendar to "basicDay" view on small screens
// and to "basicWeek" otherwise
if ( $ ( window ) . width ( ) < 768 )
{
calendar . fullCalendar ( "changeView" , "basicDay" ) ;
}
else
{
calendar . fullCalendar ( "changeView" , "basicWeek" ) ;
}
} ) ;
2020-01-25 11:51:00 +01:00
Grocy . Components . ProductPicker . GetPicker ( ) . on ( 'change' , function ( e )
{
var productId = $ ( e . target ) . val ( ) ;
if ( productId )
{
Grocy . Api . Get ( 'stock/products/' + productId ,
function ( productDetails )
{
Grocy . Components . ProductAmountPicker . Reload ( productDetails . product . id , productDetails . quantity _unit _stock . id , true ) ;
$ ( '#display_amount' ) . val ( 1 ) ;
$ ( '#display_amount' ) . focus ( ) ;
$ ( ".input-group-productamountpicker" ) . trigger ( "change" ) ;
Grocy . FrontendHelpers . ValidateForm ( 'add-product-form' ) ;
} ,
function ( xhr )
{
console . error ( xhr ) ;
}
) ;
}
} ) ;