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
2019-05-06 19:38:47 +02:00
$ ( ".fc-day-header" ) . append ( '<a class="ml-1 btn btn-outline-dark btn-xs my-1 add-recipe-button" href="#"><i class="fas fa-plus"></i></a>' ) ;
2019-05-07 19:48:14 +02:00
var weekRecipeName = view . start . year ( ) . toString ( ) + "-" + ( view . start . week ( ) - 1 ) . toString ( ) ;
var weekRecipe = FindObjectInArrayByPropertyValue ( internalRecipes , "name" , weekRecipeName ) ;
2019-09-24 01:13:42 -05: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 )
{
weekCosts = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , weekRecipe . id ) . costs ;
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-09-26 15:25:30 +02:00
$ ( ".fc-header-toolbar .fc-center" ) . html ( "<h4>" + _ _t ( "Week costs" ) + ': <span class="locale-number locale-number-currency">' + weekCosts . toString ( ) + "</span> " + weekRecipeOrderMissingButtonHtml + weekRecipeConsumeButtonHtml + "</h4>" ) ;
2019-05-06 19:38:47 +02:00
} ,
"eventRender" : function ( event , element )
{
var recipe = JSON . parse ( event . recipe ) ;
2019-09-21 09:18:40 +02:00
if ( recipe === null || recipe === undefined )
{
return false ;
}
2019-05-07 19:48:14 +02:00
var mealPlanEntry = JSON . parse ( event . mealPlanEntry ) ;
var resolvedRecipe = FindObjectInArrayByPropertyValue ( recipesResolved , "recipe_id" , recipe . id ) ;
2019-05-06 19:38:47 +02:00
element . removeClass ( "fc-event" ) ;
element . addClass ( "text-center" ) ;
2019-05-07 19:48:14 +02:00
2019-05-06 19:38:47 +02:00
element . attr ( "data-recipe" , event . recipe ) ;
element . attr ( "data-meal-plan-entry" , event . mealPlanEntry ) ;
2019-05-07 19:48:14 +02:00
var recipeOrderMissingButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled _with _shopping _list == 1 )
{
recipeOrderMissingButtonDisabledClasses = "disabled" ;
}
2019-07-06 20:02:40 +02:00
var recipeConsumeButtonDisabledClasses = "" ;
if ( resolvedRecipe . need _fulfilled == 0 )
{
recipeConsumeButtonDisabledClasses = "disabled" ;
}
2019-05-07 19:48:14 +02:00
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>' ;
}
element . html ( ' \
2019-09-24 09:21:57 +02:00
< div > \
< h5 class = "text-truncate" > ' + recipe.name + ' < h5 > \
< h5 class = "small text-truncate" > ' + __n(mealPlanEntry.servings, "%s serving", "%s servings") + ' < / h 5 > \
< h5 class = "small timeago-contextual text-truncate" > ' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + ' < / h 5 > \
2019-09-26 15:25:30 +02:00
< h5 class = "small text-truncate" > < span class = "locale-number locale-number-currency" > ' + resolvedRecipe.costs + ' < / s p a n > ' + _ _ t ( ' p e r s e r v i n g ' ) + ' < h 5 > \
2019-05-07 19:48:14 +02:00
< 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 > \
2019-07-06 20:02:40 +02:00
< 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 > \
2019-09-24 08:35:30 +02:00
< 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 > \
2019-05-07 19:48:14 +02:00
< / h 5 > \
< / d i v > ' ) ;
2019-09-24 01:13:42 -05:00
2019-05-06 19:38:47 +02:00
if ( recipe . picture _file _name && ! recipe . picture _file _name . isEmpty ( ) )
{
2019-09-24 09:21:57 +02: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>' )
2019-05-06 19:38:47 +02:00
}
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 )
{
var day = $ ( this ) . parent ( ) . data ( "date" ) ;
$ ( "#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" ) ;
} ) ;
$ ( "#add-recipe-modal" ) . on ( "shown.bs.modal" , function ( e )
{
Grocy . Components . RecipePicker . GetInputElement ( ) . focus ( ) ;
} )
$ ( document ) . on ( "click" , ".remove-recipe-button" , function ( e )
{
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 )
}
) ;
} ) ;
$ ( '#save-add-recipe-button' ) . on ( 'click' , function ( e )
{
e . preventDefault ( ) ;
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 ( ) ,
function ( result )
{
window . location . reload ( ) ;
} ,
function ( xhr )
{
Grocy . FrontendHelpers . ShowGenericError ( 'Error while saving, probably this item already exists' , xhr . response )
}
) ;
} ) ;
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" ) ;
}
} ) ;