Merge branch 'dev' into 'main'

Dev

See merge request bmcgonag/get_my!2
This commit is contained in:
Brian McGonagill 2024-07-31 14:31:41 +00:00
commit 6051bf7990
20 changed files with 366 additions and 32 deletions

View file

@ -6,7 +6,7 @@
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up List Items</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Lists</a>
<a class="btn waves-effect waves-light blue white-text modal-trigger" href="#cleanUpConfirm" id="cleanLists">Clean Lists</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-content">info</i>
<div id="tooltip-content" style="display: none;">To clean up old lists along with related list items, ensure any lists you no longer need or use are marked as 'Complete' by tapping or clicking the checkmark icon on the list entry.</div>
</div>
@ -16,9 +16,9 @@
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Menus</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Menus</a>
<a class="btn waves-effect waves-light blue white-text modal-trigger" href="#cleanUpConfirm" id="cleanMenus">Clean Menus</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-menus">info</i>
<div id="tooltip-menus" style="display: none;">This will clean up old Menus and items where all items are past the date, including items that have no date set.</div>
<div id="tooltip-menus" style="display: none;">This will clean up old Menus and items where all Menus where menu items are past the date, including items that have no date set.</div>
</div>
</div>
</div>
@ -26,7 +26,7 @@
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Products</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Products</a>
<a class="btn waves-effect waves-light blue white-text" id="cleanProducts">Clean Products</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-products">info</i>
<div id="tooltip-products" style="display: none;">This will help you clean up all products. This task takes a little more user interaction in order to identify duplicate and unique items.</div>
</div>
@ -36,13 +36,24 @@
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Tasks</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanLists">Clean Tasks</a>
<a class="btn waves-effect waves-light blue white-text" id="cleanTasks">Clean Tasks</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-tasks">info</i>
<div id="tooltip-tasks" style="display: none;">This will clean up all tasks where the date has past, or the task is marked completed. For completed tasks to be cleared, today must also be past the due date on the task.</div>
</div>
</div>
</div>
<div class="col s12 m6 l4">
<div class="card">
<div class="card-content">
<span class="card-title">Clean Up Stores</span>
<a class="btn waves-effect waves-light blue white-text" id="cleanStores">Clean Stores</a>
<i class="material-icons tooltipped right" data-html="true" data-position="top" data-tooltip-id="tooltip-stores">info</i>
<div id="tooltip-stores" style="display: none;">This will allow you to clean up Store entries if needed.</div>
</div>
</div>
</div>
</div>
{{> cleanUpModalConfirm}}
{{else}}
<p class="flow-text">You appear to have reached this page without having appropriate permissions to view the contents. If you believe this is a mistake, please contact your system admin for assistance.</p>
{{/if}}

View file

@ -1,12 +1,24 @@
import { M } from '../../lib/assets/materialize.js';
import { Lists } from '../../../imports/api/lists.js';
import { Menus } from '../../../imports/api/menu.js';
import { TaskItems } from '../../../imports/api/tasks.js';
import { Products } from '../../../imports/api/products.js';
import { Stores } from '../../../imports/api/stores.js';
Template.cleanUp.onCreated(function() {
this.subscribe("allLists");
this.subscribe("allMenus");
this.subscribe("allTasks");
this.subscribe("allProducts");
this.subscribe("allStores");
});
Template.cleanUp.onRendered(function() {
var elems = document.querySelectorAll('.tooltipped');
var instances = M.Tooltip.init(elems, {});
var elemsm = document.querySelectorAll('.modal');
var instancesm = M.Modal.init(elemsm, {});
});
Template.cleanUp.helpers({
@ -14,5 +26,24 @@ Template.cleanUp.helpers({
});
Template.cleanUp.events({
'click #cleanLists' (event) {
event.preventDefault();
Session.set("cleanWhat", "Lists");
},
'click #cleanMenus' (event) {
event.preventDefault();
Session.set("cleanWhat", "Menus");
},
'click #cleanProducts' (event) {
event.preventDefault();
Session.set("cleanWhat", "Products");
},
'click #cleanStores' (event) {
event.preventDefault();
Session.set("cleanWhat", "Stores");
},
'click #cleanTasks' (event) {
event.preventDefault();
Session.set("cleanWhat", "Tasks");
},
});

View file

@ -0,0 +1,20 @@
<template name="cleanUpModalConfirm">
<div class="modal" id="cleanUpConfirm">
<div class="modal-content">
<h4>Clean Up {{whatItems}}</h4>
<p class="flow-text">Please click the 'Confirm' button in order to continue with the {{whatItem}} clean up. Note: this action canno be undone once confirmed.</p>
</div>
<div class="modal-footer">
<div class="row">
<div class="col s6">
<a class="left btn waves-effect waves-light orange white-text cancelClean modal-close">Close</a>
</div>
<div class="col s6">
<a class="right btn waves-effect waves-light blue white-text confirmClean" id="confirmClean">Confirm</a>
</div>
</div>
</div>
</div>
{{> snackbar}}
</template>

View file

@ -0,0 +1,53 @@
import { M } from '../../../lib/assets/materialize.js';
import { Lists } from '../../../../imports/api/lists.js';
import { Menus } from '../../../../imports/api/menu';
import { TaskItems } from '../../../../imports/api/tasks';
import { Products } from '../../../../imports/api/products.js';
import { Stores } from '../../../../imports/api/stores.js';
Template.cleanUpModalConfirm.onCreated(function() {
});
Template.cleanUpModalConfirm.onRendered(function () {
});
Template.cleanUpModalConfirm.helpers({
whatItems: function() {
return Session.get("cleanWhat");
}
});
Template.cleanUpModalConfirm.events({
'click #confirmClean' (event) {
let whatItems = Session.get("cleanWhat");
switch(whatItems) {
case "Lists":
cleanUp("clean.Lists");
case "Menus":
cleanUp("clean.Menus");
case "Products":
// cleanUp("clean.Products");
case "Stores":
// cleanUp("clean.Stores");
case "Tasks":
// cleanUp("clean.Tasks");
default:
break;
}
}
});
cleanUp = function(methodName) {
Meteor.call(methodName, function(err, result) {
if (err) {
console.log(" ERROR cleaning lists: " + err)
} else {
showSnackbar("Lists have been cleaned up!", "green");
let confirmModal = document.getElementById('cleanUpConfirm');
M.Modal.getInstance(confirmModal).close();
}
});
}

View file

@ -1,7 +1,9 @@
<template name="listItemsForm">
<div class="row">
<div class="col s6 center">
{{#if Template.subscriptionsReady}}
<h5>{{selListName}}</h5>
{{/if}}
</div>
<div class="col s6">
<div class="row">

View file

@ -2,11 +2,13 @@ import { ListItems } from '../../imports/api/listItems.js'
import { Lists } from '../../imports/api/lists.js';
import { Products } from '../../imports/api/products.js';
import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js';
Template.listItemsForm.onCreated(function() {
this.subscribe("myListItems", Session.get("listId"));
this.subscribe("myLists");
this.subscribe("myProducts");
this.subscribe("userLastView");
});
Template.listItemsForm.onRendered(function() {
@ -28,9 +30,22 @@ Template.listItemsForm.onRendered(function() {
Template.listItemsForm.helpers({
selListName: function() {
let selListId = Session.get("listId");
let selListId = "";
if (Session.get("listId")) {
selListId = Session.get("listId");
} else {
selListInfo = UserLast.findOne({ view: "List" });
if (selListInfo) {
selListId = selListInfo.viewId;
Session.set("listId", selListId);
} else {
console.log("not finding any value for viewId.");
}
}
let listInfo = Lists.findOne({ _id: selListId });
if (listInfo) {
return listInfo.listName;
}
},
itemProdName: function() {
return Products.find({});

View file

@ -2,6 +2,7 @@
<div class="row">
<div class="col s12">
<ul class="collection">
{{#if Template.subscriptionsReady}}
{{#each thisListItems}}
<li class="collection-item">
<span>
@ -15,6 +16,7 @@
<i class="material-icons clickable markListItemReceived right">check</i>
</li>
{{/each}}
{{/if}}
</ul>
</div>
</div>

View file

@ -1,10 +1,12 @@
import { ListItems } from '../../imports/api/listItems.js';
import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js';
Template.listItemsTbl.onCreated(function() {
this.autorun( () => {
this.subscribe("myListItems", Session.get("listId"));
});
this.subscribe("userLastView");
});
Template.listItemsTbl.onRendered(function() {

View file

@ -23,14 +23,20 @@ Template.listsTbl.events({
if (sender.localName == "li" || sender.localName == "span") {
let listId = event.currentTarget.id;
if (listId == "addList") {
// $('#modalList').modal('open');
// opens the modal and allows you to add a new List
} else {
// console.log("listId is: " + listId);
Session.set("listId", listId);
Meteor.call('add.userLast', "List", listId, function(err, result) {
if (err) {
console.log(" ERROR setting user last list id in db: " + err);
} else {
Meteor.setTimeout(function() {
FlowRouter.go('/listitems');
}, 100);
}
});
}
}
},
'click i.markAsComplete' (event) {

View file

@ -1,6 +1,6 @@
<template name="addProdToListModal">
<div class="modal" id="addProdToList">
<div class="modal-content">
<div class="modal tall-modal" id="addProdToList">
<div class="modal-content tall-content">
<h2>Add Items to List</h2>
<form class="row" style="gap: 1em;">
<div class="col s12 input-field outlined" id="chooseListDiv">
@ -33,11 +33,11 @@
</div>
<div class="modal-footer">
<div class="row">
<div class="col s12 m6 l6">
<div class="col s6 m6 l6">
<a class="left btn waves-effect waves-light orange white-text modal-close">Cancel</a>
</div>
<div class="col s12 m6 l6">
<a class="btn waves-effect waves-light green white-text saveProdsToList" id="saveProdsToList">Save to List</a>
<div class="col s6 m6 l6">
<a class="right btn waves-effect waves-light green white-text saveProdsToList" id="saveProdsToList">Save to List</a>
</div>
</div>

View file

@ -30,7 +30,10 @@ Template.addProdToListModal.helpers({
return Lists.find({});
},
productToChoose: function() {
let prodLinkLIst = MenuProdLinks.find({ menuId: Session.get("menuItemId")});
let menuItemId = Session.get("menuItemId");
console.log("Menu Item Id received is: " + menuItemId);
let prodLinkLIst = MenuProdLinks.find({ menuItemId: menuItemId});
console.dir(prodLinkLIst);
if (typeof prodLinkLIst != 'undefined' && prodLinkLIst != "" && prodLinkLIst != null) {
return prodLinkLIst;
}

View file

@ -2,10 +2,12 @@ import { MenuItems } from '../../imports/api/menuItems.js';
import { Menus } from '../../imports/api/menu.js';
import moment from 'moment';
import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js';
Template.menuItemsForm.onCreated(function() {
this.subscribe("myMenus");
this.subscribe("allMenuItems", Session.get("menuId"));
this.subscribe("userLastView");
});
Template.menuItemsForm.onRendered(function() {
@ -29,10 +31,17 @@ Template.menuItemsForm.helpers({
return Session.get("menuItemErr");
},
menuName: function() {
let menuId = Session.get("menuId");
let menuId = "";
if (Session.get("menuId")) {
menuId = Session.get("menuId");
} else {
menuId = UserLast.findOne({ view: "Menu" }).viewId;
}
let menuInfo = Menus.findOne({ _id: menuId });
let menuName = menuInfo.menuName;
return menuName;
if (menuInfo) {
return menuInfo.menuName;
}
}
});

View file

@ -1,10 +1,12 @@
import { MenuItems } from '../../imports/api/menuItems.js';
import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js';
Template.menuItemsTbl.onCreated(function() {
this.autorun( () => {
this.subscribe("myMenuItems", Session.get("menuId"));
});
this.subscribe("userLastView");
});
Template.menuItemsTbl.onRendered(function() {
@ -22,7 +24,16 @@ Template.menuItemsTbl.onRendered(function() {
Template.menuItemsTbl.helpers({
thisMenuItems: function() {
return MenuItems.find({ menuId: Session.get("menuId") }, { sort: { serveDateActual: 1 }});
let menuId = "";
if (Session.get("menuId")) {
menuId = Session.get("menuId");
} else {
menuId = UserLast.findOne({ view: "Menu" }).viewId;
}
let menuInfo = MenuItems.find({ menuId: menuId }, { sort: { serveDateActual: 1 }});
if (menuInfo) {
return menuInfo
}
}
});
@ -40,6 +51,7 @@ Template.menuItemsTbl.events({
},
'click .addProdsToList' (event) {
event.preventDefault();
// console.log("Menu Iteme Id sent is: " + this._id);
Session.set("menuItemId", this._id);
}
});

View file

@ -1,6 +1,6 @@
<template name="modalLinkProducts">
<div id="modalLinkProducts" class="modal">
<div class="modal-content">
<div id="modalLinkProducts" class="modal tall-modal">
<div class="modal-content tall-content">
<p class="flow-text">Choose Product Items below that are used to make this menu item.</p>
<div class="col s12 input-field outlined" id="prouctsForMenudiv">
<select name="" id="prodForMenu" class="prodForMenu" multiple>

View file

@ -28,12 +28,18 @@ Template.mainMenuTbl.events({
if (menuId == "addMenu") {
// console.log("add menu clicked");
} else {
console.log("menuId is: " + menuId);
// console.log("menuId is: " + menuId);
Meteor.call('add.userLast', "Menu", menuId, function(err, result) {
if (err) {
console.log(" ERROR writing last menu viewed by user to db: " + err);
} else {
Session.set("menuId", menuId);
Meteor.setTimeout(function() {
FlowRouter.go('/menuitems');
}, 100);
}
});
}
} else if (sender.localName == "i") {
let menuId = this._id;
Meteor.call("markMenu.complete", menuId, function(err, result) {

View file

@ -29,3 +29,12 @@ strike {
.my-text {
font-size: 1.3em !important;
}
.tall-modal {
height: 75% !important;
}
.tall-content {
overflow-y: scroll !important;
height: 80% !important;
}

View file

@ -65,5 +65,12 @@ Meteor.methods({
completedOn: new Date()
}
});;
},
'clean.Lists' () {
if (!this.userId) {
throw new Meteor.Error('You are not allowed to clean up old lists. Make sure you are logged in with valid user credentials.');
}
return Lists.remove({ listComplete: true });
},
});

View file

@ -1,6 +1,9 @@
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
import { MenuItems } from './menuItems';
import moment from 'moment';
import { mark } from '@babel/runtime/regenerator';
export const Menus = new Mongo.Collection('menus');
@ -73,5 +76,50 @@ Meteor.methods({
menuComplete: false,
}
});
},
'clean.Menus' () {
if (!this.userId) {
throw new Meteor.Error('You are not allowed to clean up old Menus. Make sure you are logged in with valid user credentials.');
}
let removeMenuIds = [];
// let's find all the menus with menu items that are past their date.
let menuList = Menus.find({ menuComplete: false }).fetch();
for (i=0; i < menuList.length; i++) {
let removeMenu = true;
let items = MenuItems.find({ menuId: menuList[i]._id }).fetch();
for (j=0; j < items.length; j++) {
let srvDate = moment(items[j].serveDateActual);
let today = moment();
let expired = moment(today).isAfter(srvDate);
// console.log("Expired: " + expired);
if (expired != true) {
removeMenu = false;
}
if (j == items.length - 1) {
if (removeMenu == true) {
removeMenuIds.push(menuList[i]._id);
}
}
}
}
// next let's add the ids of any menus that are marked complete
let markedComplete = Menus.find({ menuComplete: true }).fetch();
// console.log("---- ---- ----");
// console.dir(markedComplete);
for (k = 0; k < markedComplete.length; k++) {
let menuId = markedComplete[k]._id;
removeMenuIds.push(menuId);
}
// console.log(" ----- Need to remove Menus: ");
console.dir(removeMenuIds);
for (l = 0; l < removeMenuIds.length; l++) {
Menus.remove({ _id: removeMenuIds[l] });
}
},
});

57
imports/api/userLast.js Normal file
View file

@ -0,0 +1,57 @@
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
export const UserLast = new Mongo.Collection('userLast');
UserLast.allow({
insert: function(userId, doc){
// if use id exists, allow insert
return !!userId;
},
});
Meteor.methods({
'add.userLast' (view, viewId) {
check(view, String);
check(viewId, String);
if (!this.userId) {
throw new Meteor.Error('Not able to change user view last setting. Make sure you are logged in with valid system administrator credentials.');
}
// first let's find out if there's an entry for this user and view, and if so
// we'll just edit that entry with updated information
let userListInfo = UserLast.findOne({ userId: this.userId, view: view });
if (typeof userListInfo != 'undefined' && userListInfo != "" && userListInfo != null) {
// entry exists, call the edit function instead
Meteor.call('edit.userLast', view, viewId, function(err, result) {
if (err) {
console.log(" ERROR moving user to edit for last view: " + err);
}
});
} else {
return UserLast.insert({
userId: this.userId,
view: view,
viewId: viewId,
dateAdded: Date(),
});
}
},
'edit.userLast' (view, viewId) {
check(view, String);
check(viewId, String);
if (!this.userId) {
throw new Meteor.Error('Not able to change user view last setting. Make sure you are logged in with valid system administrator credentials.');
}
return UserLast.update({ view: view, userId: this.userId }, {
$set: {
viewId: viewId,
dateLastUpdate: Date(),
}
});
}
});

View file

@ -10,6 +10,7 @@ import moment from 'moment';
import { TaskItems } from '../imports/api/tasks.js';
import { UserConfig } from '../imports/api/userConfig.js';
import { MenuProdLinks } from '../imports/api/menuProdLinks.js';
import { UserLast } from '../imports/api/userLast.js';
Meteor.publish("SystemConfig", function() {
try {
@ -31,6 +32,14 @@ Meteor.publish('userList', function() {
return Meteor.users.find({});
});
Meteor.publish("userLastView", function() {
try {
return UserLast.find({ userId: this.userId });
} catch (error) {
console.log(" ---- ERROR pulling user last info: " + error);
}
});
Meteor.publish("storeInfo", function() {
try {
return Stores.find({});
@ -113,6 +122,38 @@ Meteor.publish("allTasks", function() {
}
});
Meteor.publish("allProducts", function() {
try {
return Products.find({});
} catch (error) {
console.log(" ERROR pulling the task items: " + error);
}
});
Meteor.publish("allMenus", function() {
try {
return Menus.find({});
} catch (error) {
console.log(" ERROR pulling the task items: " + error);
}
});
Meteor.publish("allStores", function() {
try {
return Stores.find({});
} catch (error) {
console.log(" ERROR pulling the task items: " + error);
}
});
Meteor.publish("allLists", function() {
try {
return Lists.find({});
} catch (error) {
console.log(" ERROR pulling the task items: " + error);
}
});
Meteor.publish("myTasks", function() {
try {
return TaskItems.find({ assignedToId: this.userId });