Merge branch 'dev' into 'main'

Updated menus to work better with list item linking

See merge request bmcgonag/get_my!6
This commit is contained in:
Brian McGonagill 2024-08-14 16:39:35 +00:00
commit 685fdebc8e
13 changed files with 216 additions and 149 deletions

View file

@ -41,9 +41,13 @@
<div class="card-content white-text"> <div class="card-content white-text">
<span class="card-title"><h4>{{todayDate}}</h4></span> <span class="card-title"><h4>{{todayDate}}</h4></span>
{{#each todayMenuItem}} {{#each todayMenuItem}}
<div class="row"> {{#each menuItems}}
<div class="col s12"><h4><i class="medium material-icons">local_dining</i> <span class="right">{{itemName}}</span></h4></div> {{#if $eq todayDate serveDate}}
</div> <div class="row">
<div class="col s12"><h4><i class="medium material-icons">local_dining</i> <span class="right">{{menuItemName}}</span></h4></div>
</div>
{{/if}}
{{/each}}
{{else}} {{else}}
<div class="row"> <div class="row">
<div class="col s12"><h4><i class="medium material-icons">local_dining</i><span clas="right">No Menu Today</span></h4></div> <div class="col s12"><h4><i class="medium material-icons">local_dining</i><span clas="right">No Menu Today</span></h4></div>

View file

@ -14,7 +14,7 @@ Template.dashboard.onCreated(function() {
this.subscribe("storeInfo"); this.subscribe("storeInfo");
this.subscribe("myProducts"); this.subscribe("myProducts");
this.subscribe("myLocations"); this.subscribe("myLocations");
this.subscribe("myMenus"); // this.subscribe("myMenus");
this.subscribe("todayMenuItems"); this.subscribe("todayMenuItems");
this.subscribe("myTasks"); this.subscribe("myTasks");
}); });
@ -47,7 +47,9 @@ Template.dashboard.helpers({
return TaskItems.find({ isComplete: false, taskDate: today }); return TaskItems.find({ isComplete: false, taskDate: today });
}, },
todayMenuItem: function() { todayMenuItem: function() {
return MenuItems.find({}); let myMenus = Menus.find({}).fetch();
console.dir(myMenus);
return myMenus;
}, },
todayDate: function() { todayDate: function() {
let now = new Date(); let now = new Date();

View file

@ -16,16 +16,18 @@
<h4>Products to Add</h4> <h4>Products to Add</h4>
</li> </li>
{{#each productToChoose}} {{#each productToChoose}}
<li class="collection-item" id="{{prodId}}"> {{#each products}}
<div> <li class="collection-item">
<p> <div>
<label> <p>
<input type="checkbox" class="productListing" id="{{prodId}}" /> <label>
<span class="my-text">{{prodName}}</span> <input type="checkbox" class="productListing" id="{{prodId}}" />
</label> <span class="my-text">{{prodName}}</span>
</p> </label>
</div> </p>
</li> </div>
</li>
{{/each}}
{{/each}} {{/each}}
</ul> </ul>
</div> </div>

View file

@ -17,6 +17,9 @@ Template.menuItemsForm.onRendered(function() {
Session.set("menuItemErr", false); Session.set("menuItemErr", false);
Session.set("menuListItems", {}); Session.set("menuListItems", {});
var elemt = document.querySelectorAll('.tooltipped');
var instancet = M.Tooltip.init(elemt, {});
this.autorun(() => { this.autorun(() => {
var elema = document.querySelectorAll('.autocomplete'); var elema = document.querySelectorAll('.autocomplete');
var instancea = M.Autocomplete.init(elema, { var instancea = M.Autocomplete.init(elema, {
@ -52,18 +55,50 @@ Template.menuItemsForm.events({
let dateSrv = $("#dateServed").val(); let dateSrv = $("#dateServed").val();
let menuId = Session.get("menuId"); let menuId = Session.get("menuId");
if (menuItem == null || menuItem == "") {
Session.set("menuItemErr", true); let menuItemExists = MenuItems.findOne({ itemName: menuItem });
if (typeof menuItemExists != 'undefined' && menuItemExists != null && menuItemExists != "") {
// use the existing item on the menu
let menuItemId = menuItemExists._id;
let isLinked = menuItemExists.isLinked;
if (menuItem == null || menuItem == "") {
Session.set("menuItemErr", true);
} else {
Meteor.call('addto.Menu', menuId, menuItem, menuItemId, dateSrv, isLinked, function(error, nresult) {
if (error) {
console.log(" ERROR adding menuitem to menu: " + error);
} else {
// console.log("Added item to menu - no problem.");
$("#menuItemInp").val("");
$("#dateServed").val("");
}
});
}
} else { } else {
Meteor.call('add.menuItem', menuItem, dateSrv, menuId, function(err, result) { // add the item as new and add to the menu
if (err) { if (menuItem == null || menuItem == "") {
console.log(" ERROR adding menu item: " + err); Session.set("menuItemErr", true);
} else { } else {
console.log(" SUCCESS adding menu item."); Meteor.call('add.menuItem', menuItem, function(err, result) {
$("#menuItemInp").val(""); if (err) {
$("#dateServed").val(""); console.log(" ERROR adding menu item: " + err);
} } else {
}); // console.log(" SUCCESS adding menu item.");
$("#menuItemInp").val("");
$("#dateServed").val("");
// now add this item to the menu
Meteor.call('addto.Menu', menuId, menuItem, result, dateSrv, function(error, nresult) {
if (error) {
console.log(" ERROR adding menuitem to menu: " + error);
} else {
// console.log("Added item to menu - no problem.");
}
});
}
});
}
} }
}, },
'click .shiftOneDay' (event) { 'click .shiftOneDay' (event) {
@ -77,7 +112,7 @@ Template.menuItemsForm.events({
// console.log(momentAddDay); // console.log(momentAddDay);
Meteor.call('shiftDate', menuItemId, momentAddDay, function(err,result) { Meteor.call('shiftDate', menuItemId, momentAddDay, function(err,result) {
if (err) { if (err) {
// console.log(" ERROR shifting meal days: " + err); console.log(" ERROR shifting meal days: " + err);
} else { } else {
// console.log(" SUCCESS shifting meal date."); // console.log(" SUCCESS shifting meal date.");
} }

View file

@ -11,27 +11,25 @@
</tr> </tr>
</thead> </thead>
{{#each thisMenuItems}} {{#each thisMenuItems}}
<tr> {{#each menuItems}}
<td> <tr>
<span> <td>
{{#if $eq itemMade true}} <span>
<strike>{{itemName}}</strike> {{menuItemName}}
{{else}} </span>
{{itemName}} </td>
{{/if}} <td>
</span> {{serveDate}}
</td> </td>
<td> <td>
{{serveDate}} {{#if $eq isLinked true}}<a class="waves-effect waves-light blue darken-3 white-text btn addProdsToList modal-trigger" href="#addProdToList">+ Shopping List</a>{{/if}}
</td> </td>
<td> <td>
{{#if $eq isLinked true}}<a class="waves-effect waves-light blue darken-3 white-text btn addProdsToList modal-trigger" href="#addProdToList">+ Shopping List</a>{{/if}} <i class="material-icons tooltipped modal-trigger deleteMenuItem clickable" href="#modalDelete" data-position="top" data-tooltip-id="deleteMenuTip">delete</i>
</td> <i class="material-icons tooltipped modal-trigger linkToProducts clickable" href="#modalLinkProducts" data-position="top" data-tooltip-id="linkMenuTip">link</i>
<td> </td>
<i class="material-icons tooltipped modal-trigger deleteMenuItem clickable" href="#modalDelete" data-position="top" data-tooltip-id="deleteMenuTip">delete</i> </tr>
<i class="material-icons tooltipped modal-trigger linkToProducts clickable" href="#modalLinkProducts" data-position="top" data-tooltip-id="linkMenuTip">link</i> {{/each}}
</td>
</tr>
{{/each}} {{/each}}
</table> </table>
<div class="tooltip-content" style="display: none;" id="deleteMenuTip">Delete this menu item</div> <div class="tooltip-content" style="display: none;" id="deleteMenuTip">Delete this menu item</div>

View file

@ -1,11 +1,13 @@
import { MenuItems } from '../../imports/api/menuItems.js'; import { MenuItems } from '../../imports/api/menuItems.js';
import { M } from '../lib/assets/materialize.js'; import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js'; import { UserLast } from '../../imports/api/userLast.js';
import { Menus } from '../../imports/api/menu.js';
Template.menuItemsTbl.onCreated(function() { Template.menuItemsTbl.onCreated(function() {
this.autorun( () => { this.autorun( () => {
this.subscribe("myMenuItems", Session.get("menuId")); this.subscribe("myMenuItems", Session.get("menuId"));
}); });
this.subscribe("menuItems");
this.subscribe("userLastView"); this.subscribe("userLastView");
}); });
@ -30,7 +32,7 @@ Template.menuItemsTbl.helpers({
} else { } else {
menuId = UserLast.findOne({ view: "Menu" }).viewId; menuId = UserLast.findOne({ view: "Menu" }).viewId;
} }
let menuInfo = MenuItems.find({ menuId: menuId }, { sort: { serveDateActual: 1 }}); let menuInfo = Menus.find({ _id: menuId }, { sort: { serveDateActual: 1 }});
if (menuInfo) { if (menuInfo) {
return menuInfo return menuInfo
} }
@ -40,18 +42,22 @@ Template.menuItemsTbl.helpers({
Template.menuItemsTbl.events({ Template.menuItemsTbl.events({
'click .deleteMenuItem' (event) { 'click .deleteMenuItem' (event) {
event.preventDefault(); event.preventDefault();
Session.set("deleteId", this._id); let theseIds = Session.get("menuId") + "_" + this.menuItemId;
Session.set("method", "delete.menuItem"); console.log("These Ids: " + theseIds);
Session.set("item", this.itemName); Session.set("deleteId", theseIds);
Session.set("method", "delete.itemFromMenu");
Session.set("item", this.menuItemName);
Session.set("view", "Menu Items"); Session.set("view", "Menu Items");
}, },
'click .linkToProducts' (event) { 'click .linkToProducts' (event) {
event.preventDefault(); event.preventDefault();
Session.set("menuItemId", this._id); Session.set("menuItemId", this.menuItemId);
Session.set("menuItemName", this.menuItemName);
console.log("menu item name = " + this.menuItemName);
}, },
'click .addProdsToList' (event) { 'click .addProdsToList' (event) {
event.preventDefault(); event.preventDefault();
// console.log("Menu Iteme Id sent is: " + this._id); // console.log("Menu Iteme Id sent is: " + this._id);
Session.set("menuItemId", this._id); Session.set("menuItemId", this.menuItemId);
} }
}); });

View file

@ -2,11 +2,8 @@
<h5>{{menuName}}</h5> <h5>{{menuName}}</h5>
<form class="menuItemFrm row" style="gap: 1em;" id="menuItemFrm"> <form class="menuItemFrm row" style="gap: 1em;" id="menuItemFrm">
<div class="col s12 m6 l9 input-field outlined"> <div class="col s12 m6 l9 input-field outlined">
<input type="text" class="autocomplete" id="menuItemInp" autocomplete="off" /> <input type="text" class="autocomplete tooltipped" id="menuItemInp" autocomplete="off" data-position="top" data-tooltip="Start typing, and select previous menu items if desired." />
<label for="menuItemInp">Item</label> <label for="menuItemInp">Item</label>
<!-- <input type="text" class="menuItemInp" style="{{#if $eq menuItemErr true}}border: 2px solid red{{/if}}" id="menuItemInp" />
<label for="menuItemInp">Add Menu Item</label> -->
</div> </div>
<div class="col s12 m6 l3 input-field outlined"> <div class="col s12 m6 l3 input-field outlined">
<input type="text" class="datepicker" id="dateServed" /> <input type="text" class="datepicker" id="dateServed" />

View file

@ -6,7 +6,7 @@
<select name="" id="prodForMenu" class="prodForMenu" multiple> <select name="" id="prodForMenu" class="prodForMenu" multiple>
<option value="" disabled>Choose...</option> <option value="" disabled>Choose...</option>
{{#each products}} {{#each products}}
<option value="{{prodName}}">{{prodName}}</option> <option value="{{_id}}|{{prodName}}">{{prodName}}</option>
{{/each}} {{/each}}
</select> </select>
</div> </div>

View file

@ -36,18 +36,35 @@ Template.modalLinkProducts.events({
'click #saveLink' (event) { 'click #saveLink' (event) {
event.preventDefault(); event.preventDefault();
let menuItemId = Session.get("menuItemId"); let menuItemId = Session.get("menuItemId");
let menuItemName = Session.get("menuItemName");
let linkSelect = document.getElementById('prodForMenu'); let linkSelect = document.getElementById('prodForMenu');
let linkObjArray = [];
let links = M.FormSelect.getInstance(linkSelect).getSelectedValues(); let links = M.FormSelect.getInstance(linkSelect).getSelectedValues();
if (typeof links != undefined && links != [] && links != null) { if (typeof links != undefined && links != [] && links != null) {
Meteor.call("add.menuProdLinks", menuItemId, links, function(err, result) { // let's split these links into their parts, and make an array of objects
for (i=0; i<links.length; i++) {
let linkArray = links[i].split('|');
let key = linkArray[0];
let value = linkArray[1];
let linkObj = { prodId: key, prodName: value };
linkObjArray.push(linkObj);
}
Meteor.call("add.menuProdLinks", menuItemId, menuItemName, linkObjArray, function(err, result) {
if (err) { if (err) {
console.log(" ERROR adding product links to this menu item: " + err); console.log(" ERROR adding product links to this menu item: " + err);
} else { } else {
Meteor.call('update.menuItemLinked', menuItemId, true, function(err, result) { Meteor.call('update.menuItemLinked', menuItemId, true, function(err, result) {
if (err) { if (err) {
console.log(" ERROR adding link exists to menu item: " + err); console.log(" ERROR adding link to menu item: " + err);
} else { } else {
showSnackbar("Products added to Menu Item successfully!", "green"); Meteor.call('link.inMenu', menuItemId, true, function(error, nresult) {
if (error) {
console.log(" ERROR adding link to menu sub-item: " + error);
} else {
showSnackbar("Products added to Menu Item successfully!", "green");
}
});
} }
}); });
} }

View file

@ -117,4 +117,62 @@ Meteor.methods({
Menus.remove({ _id: removeMenuIds[l] }); Menus.remove({ _id: removeMenuIds[l] });
} }
}, },
'addto.Menu' (menuId, menuItem, menuItemId, dateSrv, isLinked) {
check(menuId, String);
check(menuItem, String);
check(menuItemId, String);
check(dateSrv, String);
check(isLinked, Boolean);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add items to menus. Make sure you are logged in with valid user credentials.');
}
serveDateActual = new Date(dateSrv);
return Menus.update({ _id: menuId }, {
$addToSet: {
menuItems:
{
menuItemId: menuItemId,
menuItemName: menuItem,
serveDate: dateSrv,
serveDateActual: serveDateActual,
isLinked: isLinked
},
}
});
},
'link.inMenu' (menuItemId, isLinked) {
check(menuItemId, String);
check(isLinked, Boolean);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to link menu items to products. Make sure you are logged in with valid user credentials.');
}
return Menus.update({ 'menuItems.menuItemId': menuItemId }, {
$set: {
"menuItems.$.isLinked": isLinked
}
});
},
'delete.itemFromMenu' (itemIds) {
check(itemIds, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete items from a menu. Make sure you are logged in with valid user credentials.');
}
let ids = itemIds.split('_');
console.log("item ids: " + ids[0] + " and " + ids[1]);
return Menus.update({ _id: ids[0] }, {
$pull: {
menuItems: {
menuItemId: ids[1],
},
}
});
}
}); });

View file

@ -12,10 +12,8 @@ MenuItems.allow({
}); });
Meteor.methods({ Meteor.methods({
'add.menuItem' (itemName, serveDate, menuId) { 'add.menuItem' (itemName) {
check(itemName, String); check(itemName, String);
check(serveDate, String);
check(menuId, String);
if (!this.userId) { if (!this.userId) {
throw new Meteor.Error('You are not allowed to add items. Make sure you are logged in with valid user credentials.'); throw new Meteor.Error('You are not allowed to add items. Make sure you are logged in with valid user credentials.');
@ -25,11 +23,7 @@ Meteor.methods({
return MenuItems.insert({ return MenuItems.insert({
itemName: itemName, itemName: itemName,
serveDate: serveDate,
serveDateActual: serveDateActual,
menuId: menuId,
addedBy: this.userId, addedBy: this.userId,
itemMade: false,
dateAddedtoMenu: new Date(), dateAddedtoMenu: new Date(),
isLinked: false, isLinked: false,
}); });
@ -48,49 +42,6 @@ Meteor.methods({
} }
}); });
}, },
'setMade.menuItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as made. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ _id: itemId }, {
$set: {
itemMade: true,
dateMade: new Date(),
}
});
},
'setAllMade.menuItem' (menuId) {
check(menuId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set all items as made. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ menuId: menuId }, {
$set: {
itemMade: true,
}
}, {
multi: true
});
},
'setNotMade.menuItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as not made. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ _id: itemId }, {
$set: {
itemMade: false,
dateUnMade: new Date(),
}
});
},
'edit.madeItem' (itemId, itemName, serveDate) { 'edit.madeItem' (itemId, itemName, serveDate) {
check(itemId, String); check(itemId, String);
check(itemName, String); check(itemName, String);

View file

@ -13,32 +13,21 @@ MenuProdLinks.allow({
}); });
Meteor.methods({ Meteor.methods({
'add.menuProdLinks' (menuItemId, prodNameArray) { 'add.menuProdLinks' (menuItemId, menuItemName, prodNameArray) {
check(menuItemId, String); check(menuItemId, String);
check(prodNameArray, [String]); check(menuItemName, String);
check(prodNameArray, [Object]);
if (!this.userId) { if (!this.userId) {
throw new Meteor.Error('You are not allowed to add menu and product links. Make sure you are logged in with valid user credentials.'); throw new Meteor.Error('You are not allowed to add menu and product links. Make sure you are logged in with valid user credentials.');
} };
let productObj = {}; MenuProdLinks.insert({
menuItemId: menuItemId,
let prodNameLength = prodNameArray.length; menuItemName: menuItemName,
products: prodNameArray,
for (i=0; i<prodNameLength; i++) { dateCreated: Date(),
let product = Products.findOne({ prodName: prodNameArray[i] }); createdBy: this.userId
if (typeof product != 'undefined' && product != null && product != "") { });
let prodId = product._id;
MenuProdLinks.insert({
menuItemId: menuItemId,
prodName: prodNameArray[i],
prodId: prodId,
dateCreated: Date(),
createdBy: this.userId
});
} else {
console.log(" ERROR - unable to find a matching product by name: " + prodName[i] + ".");
}
}
} }
}); });

View file

@ -88,9 +88,17 @@ Meteor.publish("myMenus", function() {
} }
}); });
Meteor.publish("menuItems", function() {
try {
return MenuItems.find({});
} catch (error) {
console.log(" ERROR pulling menuItem data: " + error);
}
});
Meteor.publish("myMenuItems", function(menuId) { Meteor.publish("myMenuItems", function(menuId) {
try { try {
return MenuItems.find({ menuId: menuId }); return Menus.find({ menuId: menuId });
} catch (error) { } catch (error) {
console.log(" ERROR pulling menu items for this list: " + error); console.log(" ERROR pulling menu items for this list: " + error);
} }
@ -108,7 +116,7 @@ Meteor.publish("todayMenuItems", function() {
try { try {
let todayDate = new Date(); let todayDate = new Date();
let todaysDate = moment(todayDate).format("MMM DD, YYYY"); let todaysDate = moment(todayDate).format("MMM DD, YYYY");
return MenuItems.find({ serveDate: todaysDate, itemMade: false }); return Menus.find({ 'menuItems.serveDate': todaysDate });
} catch (error) { } catch (error) {
console.log(" ERROR pulling today's menu items: " + error); console.log(" ERROR pulling today's menu items: " + error);
} }