Compare commits

...

45 commits

Author SHA1 Message Date
Brian McGonagill
76d3591d51 fix an issue with marking list items as received 2025-09-12 15:41:55 -05:00
Brian McGonagill
047befcae9 Adjusted layout and removed logging 2025-08-09 07:24:54 -05:00
Brian McGonagill
680f7c614d Fixing clean Up and added option to show which products arent used in a list 2025-08-09 07:21:46 -05:00
Brian McGonagill
c6c5951d16 tiny update to add console logging. 2025-08-02 19:22:37 -05:00
Brian McGonagill
aaddbf0b44 Fixed Menu Clean up. 2025-08-02 17:05:09 -05:00
Brian McGonagill
839390f820 attempting to make product load better in drop down 2025-08-02 15:45:34 -05:00
Brian McGonagill
9223f21e06 Updates to make Menu and lists work together again. 2025-07-30 07:11:50 -05:00
Brian McGonagill
b5d490c052 Just updated menu items to be added correctly in new version 2025-07-29 16:58:25 -05:00
Brian McGonagill
d25ef56591 Commenting out console logging. 2025-07-23 19:44:24 -05:00
Brian McGonagill
4687f27011 Update Dockerfile proper 2025-07-23 19:18:01 -05:00
Brian McGonagill
4de73528c4 Updated Dockerfile 2025-07-23 19:05:06 -05:00
c0ef44f16a Merge branch 'tasks-dev' into 'main'
Updates to Meteor3

See merge request bmcgonag/get_my!19
2025-07-22 14:37:33 -05:00
Brian McGonagill
706c5dc3ef Updates for async and await - still 2025-07-22 13:50:49 -05:00
Brian McGonagill
febb36d75f Fixing add task calls for async await 2025-07-22 08:34:24 -05:00
ca7bcb1a8f working on tasks for meteor 3 update 2025-06-24 13:16:42 -05:00
f12c6bb7c8 fixed adding menu items to the menu. 2025-06-21 13:24:24 -05:00
055d574dcc Fix helper return for registration 2025-06-21 13:04:47 -05:00
Brian McGonagill
cca29bc591 Updating framework to meteor 3 and later 2025-06-21 07:28:59 -05:00
Brian McGonagill
717994508a Small change to address a simple filter 2025-05-27 13:33:38 -05:00
Brian McGonagill
c9c96d214d Added ability to restore a completed lilst from List Management. #27 2025-05-26 16:22:58 -05:00
dcd0074b28 Merge branch 'dev' into 'main'
fix My Settings nav from slide out panel.

See merge request bmcgonag/get_my!18
2024-09-08 14:23:57 +00:00
0f9c4f4d5e fix My Settings nav from slide out panel. 2024-09-08 09:22:41 -05:00
c8c3aead80 Merge branch 'dev' into 'main'
Updated Readme to include initial YouTube video

See merge request bmcgonag/get_my!17
2024-09-04 15:46:23 +00:00
dba1a6978e Updated Readme to include initial YouTube video 2024-09-04 10:45:51 -05:00
de8f5bc096 Merge branch 'dev' into 'main'
Updated lists to group by store

See merge request bmcgonag/get_my!16
2024-08-24 16:11:02 +00:00
c733727829 Updated lists to group by store
Lists have been updated to group by store.

This feature adds a new tab to the List view. Users can now view their items on the general (un-ordered) list, or can see their items gouped by store(s) the product has been assigned.

If a product is on the list, and does not have an assigned store, it will not show on the new store grouped tab.

Updated the dashboard card for update available information to place the update release notes in a prettier format.
2024-08-24 10:50:20 -05:00
b245fde84c Merge branch 'dev' into 'main'
Adding new files.

See merge request bmcgonag/get_my!15
2024-08-21 13:45:25 +00:00
b992c9d67e Adding new files. 2024-08-21 07:11:11 -05:00
0b0678fc7e Merge branch 'dev' into 'main'
Multiple updates and additions

See merge request bmcgonag/get_my!14
2024-08-21 12:07:00 +00:00
c70f9bd74e Multiple updates and additions
- Added a permission to show or hide update version information on that dashboard as a card that will only show when new update info is available and not yet dismissed.
- Updated Lists so list items added will have their fist letter auto-capitalized
- Updated Lists so list items are searched against the products before being added to the list, so we have store info more commonly in lists
- Updated Products so new products will have their first letter capitalized automatically
- Updated the dashboard to show the Update Available card if this is enbaled in permissions.
    - The dashboard card only shows for System Admin roles.
    - The dashboard card is enabled by default
    - The dashboard card is pulled from the GitLab releases RSS feed.
    - The RSS Feed is only checked every 30 minutes using node-cron
- Updated System Configuration to have a toggle for the update available card
- Added a bell icon to the top and slide out navigation, shown when a new update is available, if update available is enabled in system configuration.
2024-08-21 07:01:36 -05:00
f02ea7d549 Putting a capital letter on the front of any product added. 2024-08-18 10:12:43 -05:00
c41857ab3e Made items list in alphabetical order 2024-08-18 09:59:58 -05:00
9fdb7e4b7d Set List of products in alphabetical order 2024-08-18 09:57:56 -05:00
a9da312a0e Merge branch 'dev' into 'main'
updated to send isLinked value

See merge request bmcgonag/get_my!13
2024-08-18 14:28:30 +00:00
d2f4ecf7ff updated to send isLinked value 2024-08-18 09:28:04 -05:00
36a4792579 Merge branch 'dev' into 'main'
update menu items method

See merge request bmcgonag/get_my!12
2024-08-18 13:51:55 +00:00
a139335a4c update menu items method 2024-08-18 08:51:31 -05:00
2c31422141 Merge branch 'dev' into 'main'
Update the items calls

See merge request bmcgonag/get_my!11
2024-08-18 13:41:37 +00:00
206cb65fa7 Update the items calls 2024-08-18 08:40:09 -05:00
e3da56e687 Merge branch 'dev' into 'main'
Fix bug with updating linked menu items and products.

See merge request bmcgonag/get_my!10
2024-08-16 17:33:58 +00:00
457004df3f Fix bug with updating linked menu items and products. 2024-08-16 12:33:27 -05:00
36152455d5 Merge branch 'dev' into 'main'
updating mScript file

See merge request bmcgonag/get_my!9
2024-08-15 23:57:52 +00:00
e10e234250 updating mScript file 2024-08-15 18:56:20 -05:00
4e157f47d8 Merge branch 'dev' into 'main'
Fix 2 bugs, fix update functions for new changes.

See merge request bmcgonag/get_my!8
2024-08-15 23:48:33 +00:00
6a771a6f11 Fix 2 bugs, fix update functions for new changes. 2024-08-15 18:47:26 -05:00
74 changed files with 3495 additions and 1785 deletions

View file

@ -4,29 +4,27 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.5.1 # Packages every Meteor app needs to have
mobile-experience@1.1.1 # Packages for a great mobile UX
mongo@1.16.10 # The database Meteor supports right now
meteor-base@1.5.2 # Packages every Meteor app needs to have
mobile-experience@1.1.2 # Packages for a great mobile UX
mongo@2.1.4 # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views
jquery # Wrapper package for npm-installed jquery
reactive-var@1.0.12 # Reactive variable for tracker
tracker@1.3.3 # Meteor's client-side reactive programming library
reactive-var@1.0.13 # Reactive variable for tracker
tracker@1.3.4 # Meteor's client-side reactive programming library
standard-minifier-css@1.9.2 # CSS minifier run for production mode
standard-minifier-js@2.8.1 # JS minifier run for production mode
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers
ecmascript@0.16.8 # Enable ECMAScript2015+ syntax in app code
typescript@4.9.5 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.5.0 # Server-side component of the `meteor shell` command
standard-minifier-css@1.9.3 # CSS minifier run for production mode
standard-minifier-js@3.1.1 # JS minifier run for production mode
es5-shim@4.8.1 # ECMAScript 5 compatibility for older browsers
ecmascript@0.16.13 # Enable ECMAScript2015+ syntax in app code
typescript@5.6.6 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.6.2 # Server-side component of the `meteor shell` command
hot-module-replacement@0.5.3 # Update code in development without reloading the page
hot-module-replacement@0.5.4 # Update code in development without reloading the page
blaze-hot # Update files using Blaze's API with HMR
alanning:roles@2.2.0
email@2.2.6
session@1.2.1
raix:handlebar-helpers
kadira:flow-router
kadira:blaze-layout
accounts-password@2.4.0
roles@1.0.1
session@1.2.2
email@3.1.2
arianjahiri:meteor-handlebars-helpers
ostrio:flow-router-extra
accounts-password@3.2.1

View file

@ -1 +1 @@
METEOR@2.16
METEOR@3.3.2

View file

@ -1,94 +1,94 @@
accounts-base@2.2.11
accounts-password@2.4.0
alanning:roles@2.2.0
allow-deny@1.1.1
autoupdate@1.8.0
babel-compiler@7.10.5
babel-runtime@1.5.1
base64@1.0.12
binary-heap@1.0.11
blaze@2.9.0
blaze-hot@1.1.2
blaze-html-templates@1.2.1
blaze-tools@1.1.4
boilerplate-generator@1.7.2
caching-compiler@1.2.2
caching-html-compiler@1.2.2
callback-hook@1.5.1
check@1.4.1
ddp@1.4.1
ddp-client@2.6.2
ddp-common@1.4.1
ddp-rate-limiter@1.2.1
ddp-server@2.7.1
deps@1.0.12
diff-sequence@1.1.2
dynamic-import@0.7.3
ecmascript@0.16.8
ecmascript-runtime@0.8.1
ecmascript-runtime-client@0.12.1
ecmascript-runtime-server@0.11.0
ejson@1.1.3
email@2.2.6
es5-shim@4.8.0
fetch@0.1.4
geojson-utils@1.0.11
hot-code-push@1.0.4
hot-module-replacement@0.5.3
html-tools@1.1.4
htmljs@1.2.1
id-map@1.1.1
inter-process-messaging@0.1.1
jquery@3.0.0
kadira:blaze-layout@2.0.1
kadira:flow-router@2.12.1
launch-screen@2.0.0
localstorage@1.2.0
logging@1.3.4
meteor@1.11.5
meteor-base@1.5.1
minifier-css@1.6.4
minifier-js@2.8.0
minimongo@1.9.4
mobile-experience@1.1.1
mobile-status-bar@1.1.0
modern-browsers@0.1.10
modules@0.20.0
modules-runtime@0.13.1
modules-runtime-hot@0.14.2
mongo@1.16.10
mongo-decimal@0.1.3
mongo-dev-server@1.1.0
mongo-id@1.0.8
npm-mongo@4.17.2
observe-sequence@1.0.22
ordered-dict@1.1.0
promise@0.12.2
raix:handlebar-helpers@0.2.5
random@1.2.1
rate-limit@1.1.1
react-fast-refresh@0.2.8
reactive-dict@1.3.1
reactive-var@1.0.12
reload@1.3.1
retry@1.1.0
routepolicy@1.1.1
session@1.2.1
sha@1.0.9
shell-server@0.5.0
socket-stream-client@0.5.2
spacebars@1.6.0
spacebars-compiler@1.3.2
standard-minifier-css@1.9.2
standard-minifier-js@2.8.1
templating@1.4.3
templating-compiler@1.4.2
templating-runtime@1.6.4
templating-tools@1.2.3
tracker@1.3.3
typescript@4.9.5
ui@1.0.13
underscore@1.6.2
url@1.3.2
webapp@1.13.8
webapp-hashing@1.1.1
accounts-base@3.1.2
accounts-password@3.2.1
allow-deny@2.1.0
arianjahiri:meteor-handlebars-helpers@0.0.1
autoupdate@2.0.1
babel-compiler@7.12.2
babel-runtime@1.5.2
base64@1.0.13
binary-heap@1.0.12
blaze@3.0.2
blaze-hot@2.0.0
blaze-html-templates@3.0.0
blaze-tools@2.0.0
boilerplate-generator@2.0.2
caching-compiler@2.0.1
caching-html-compiler@2.0.0
callback-hook@1.6.1
check@1.4.4
core-runtime@1.0.0
ddp@1.4.2
ddp-client@3.1.1
ddp-common@1.4.4
ddp-rate-limiter@1.2.2
ddp-server@3.1.2
deps@1.0.5-pre.1
diff-sequence@1.1.3
dynamic-import@0.7.4
ecmascript@0.16.13
ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.12.3
ecmascript-runtime-server@0.11.1
ejson@1.1.5
email@3.1.2
es5-shim@4.8.1
facts-base@1.0.2
fetch@0.1.6
geojson-utils@1.0.12
hot-code-push@1.0.5
hot-module-replacement@0.5.4
html-tools@2.0.0
htmljs@2.0.1
id-map@1.2.0
inter-process-messaging@0.1.2
jquery@3.0.2
launch-screen@2.0.1
localstorage@1.2.1
logging@1.3.6
meteor@2.1.1
meteor-base@1.5.2
minifier-css@2.0.1
minifier-js@3.0.4
minimongo@2.0.4
mobile-experience@1.1.2
mobile-status-bar@1.1.1
modern-browsers@0.2.3
modules@0.20.3
modules-runtime@0.13.2
modules-runtime-hot@0.14.3
mongo@2.1.4
mongo-decimal@0.2.0
mongo-dev-server@1.1.1
mongo-id@1.0.9
npm-mongo@6.16.1
observe-sequence@2.0.0
ordered-dict@1.2.0
ostrio:flow-router-extra@3.12.0
promise@1.0.0
random@1.2.2
rate-limit@1.1.2
react-fast-refresh@0.2.9
reactive-dict@1.3.2
reactive-var@1.0.13
reload@1.3.2
retry@1.1.1
roles@1.0.1
routepolicy@1.1.2
session@1.2.2
sha@1.0.10
shell-server@0.6.2
socket-stream-client@0.6.1
spacebars@2.0.0
spacebars-compiler@2.0.0
standard-minifier-css@1.9.3
standard-minifier-js@3.1.1
templating@1.4.4
templating-compiler@2.0.0
templating-runtime@2.0.1
templating-tools@2.0.0
tracker@1.3.4
typescript@5.6.6
underscore@1.6.4
url@1.3.5
webapp@2.0.7
webapp-hashing@1.1.2

View file

@ -1,8 +1,4 @@
FROM alpine:3.17
ENV NODE_VERSION=14.21.4
ENV NODE_URL="https://static.meteor.com/dev-bundle-node-os/unofficial-builds/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
ENV DIR_NODE=/usr/local
FROM node:22.16.0-alpine
RUN apk add --no-cache \
libstdc++ \
@ -20,13 +16,6 @@ RUN apk add --no-cache \
ccache \
xz
RUN echo $NODE_URL
RUN curl -sSL "$NODE_URL" | tar -xz -C /usr/local/ && mv $DIR_NODE/node-v${NODE_VERSION}-linux-x64 $DIR_NODE/v$NODE_VERSION
# add node and npm to path so the commands are available
ENV NODE_PATH $DIR_NODE/v$NODE_VERSION/lib/node_modules
ENV PATH $DIR_NODE/v$NODE_VERSION/bin:$PATH
# confirm installation
RUN node -v
RUN npm -v
@ -38,11 +27,11 @@ ENV MONGO_URL=mongodb://mongo:27017/get_my\
RUN mkdir -p /usr/src/get_my
WORKDIR /usr/src/get_my
COPY bundle/ /usr/src/get_my/
COPY ../bundle/ /usr/src/get_my/
RUN cd /usr/src/get_my/programs/server/ \
&& npm install
EXPOSE 3000
CMD [ "node", "main.js" ]
CMD [ "node", "main.js" ]

View file

@ -60,6 +60,8 @@ The documentation is being done in the amazing open source software [Bookstack](
If you'd like to contribute by writing some documentation, please contact me me with an, and I'll see about getting you access to contribute.
I have a video introduction on my YouTube channel here as well: https://youtu.be/hbGNTzU24hI?si=K5mcb8FuzSWNCueB
## Keeping it Simple
- Registration / Login System built in
- 1st user to register is the system admin by default.

View file

@ -1,4 +1,5 @@
import { SysConfig } from '../../../imports/api/systemConfig.js';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
Template.login.onCreated(function() {
this.subscribe("SystemConfig");
@ -25,7 +26,7 @@ Template.login.helpers({
Template.login.events({
'click #logmein' (event) {
event.preventDefault();
console.log("clicked login");
// console.log("clicked login");
let email = $("#email").val();
let pass = $("#password").val();

View file

@ -1,4 +1,5 @@
import { SysConfig } from "../../../imports/api/systemConfig.js";
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
Template.reg.onCreated(function() {
this.subscribe("SystemConfig");
@ -29,12 +30,16 @@ Template.reg.helpers({
return Session.get("missingReq");
},
allowReg: function() {
let conf = SysConfig.findOne();
if (typeof conf != 'undefined') {
return conf.allowReg;
} else {
return true
const sysConf = async() => {
let conf = await SysConfig.findOneAsync();
if (!conf) {
return true;
} else {
return conf.allowReg;
}
}
let sysConfig = sysConf();
return sysConfig;
}
});
@ -83,15 +88,17 @@ Template.reg.events({
});
let userId = Meteor.userId();
console.log("User ID: " + userId);
Meteor.call("addToRole", "user", function(err, result) {
if (err) {
console.log(" ERROR: ROLES - Error adding user to role: " + err);
// console.log("User ID: " + userId);
const addRole = async() => {
let result = await Meteor.callAsync("addToRole", "user");
if (!result) {
console.log(" ERROR: ROLES - Error adding user to role: ");
} else {
// console.log("User should be added to role - teacher.");
FlowRouter.go('/dashboard');
}
});
}
addRole();
}
}
},

View file

@ -15,7 +15,7 @@
<label for="newPassConf">Enter New Password</label>
{{#if $eq passMatch false}}<p class="red-text">Passwords do not match!</p>{{/if}}
</div>
<div class="col s12 m6 l6 input-field outlined">
<div class="col s12 m6 l6 input-field">
<select name="userRole" id="userRole" class="userRole {{#if $eq roleEmpty true}}red lighten-2 white-text{{/if}}">
<option value="{{userRole}}" selected>{{userRole}}</option>
<option value="admin">Admin</option>

View file

@ -16,10 +16,10 @@ Template.userInfoModal.onRendered(function() {
var elemse = document.querySelectorAll('select');
var instancese = M.FormSelect.init(elemse, {});
Meteor.setTimeout(() => {
instances = M.Modal.init(elems, {});
instancese = M.FormSelect.init(elemse, {});
}, 500);
// Meteor.setTimeout(() => {
// instances = M.Modal.init(elems, {});
// instancese = M.FormSelect.init(elemse, {});
// }, 500);
});
Template.userInfoModal.helpers({
@ -35,19 +35,34 @@ Template.userInfoModal.helpers({
userInfo: function() {
let usersId = Session.get("usersId");
if (usersId != "" && usersId != null) {
let usersInfo = Meteor.users.findOne({ _id: usersId });
// console.dir(usersInfo);
Session.set("usersInfo", usersInfo);
return usersInfo;
const uIn = async() => {
let usersInfo = await Meteor.users.findOneAsync({ _id: usersId });
if (!usersInfo) {
console.log("No information found for this user.");
return;
} else {
Session.set("usersInfo", usersInfo);
return usersInfo;
}
// console.dir(usersInfo);
}
uIn();
} else {
return;
}
},
userRole: function() {
let userRole = Roles.getRolesForUser( Session.get("usersId"));
Session.set("usersRole", userRole);
console.log(userRole);
return userRole;
const getRole = async() => {
let userRole = Roles.getRolesForUserAsync( Session.get("usersId"));
if (!userRole) {
return;
} else {
Session.set("usersRole", userRole);
console.log(userRole);
return userRole;
}
}
getRole();
},
rolesOptions: function() {
return Roles.find();
@ -121,36 +136,33 @@ Template.userInfoModal.events({
}
});
changePassword = function(userId, passwd) {
changePassword = async function(userId, passwd) {
console.log("would change password.");
Meteor.call('edit.userPass', userId, passwd, function(err, result) {
if (err) {
console.log(" ERROR changing user passwrod:" + err);
} else {
showSnackbar("Successfully Saved Changes!", "green");
console.log(" Password changed successfully!");
}
});
let result = await Meteor.callAsync('edit.userPass', userId, passwd);
if (!result) {
console.log(" ERROR changing user passwrod:");
} else {
showSnackbar("Successfully Saved Changes!", "green");
console.log(" Password changed successfully!");
}
}
changeUserEmail = function(usersId, usersEmail) {
changeUserEmail = async function(usersId, usersEmail) {
console.log("Would change user email");
Meteor.call('update.userEmail', usersId, usersEmail, function(err, result) {
if (err) {
console.log(" ERROR updating user email: " + err);
} else {
showSnackbar("Email updated successfully!", "green");
}
});
let result = await Meteor.callAsync('update.userEmail', usersId, usersEmail);
if (!result) {
console.log(" ERROR updating user email: " + err);
} else {
showSnackbar("Email updated successfully!", "green");
}
}
changeUserRole = function(userId, role) {
changeUserRole = async function(userId, role) {
console.log("Would change user Role.");
Meteor.call('edit.userRole', userId, role, function(err, result) {
if (err) {
console.log(" ERROR updating user role: " + err);
} else {
showSnackbar("Role Successfully Updated!", "green");
}
});
let result = await Meteor.callAsync('edit.userRole', userId, role);
if (!result) {
console.log(" ERROR updating user role: " + err);
} else {
showSnackbar("Role Successfully Updated!", "green");
}
}

View file

@ -23,7 +23,7 @@ Template.userMgmt.helpers({
return this.emails[0].address;
},
userRole: function() {
return Roles.getRolesForUser( this._id );
return Roles.getRolesForUserAsync( this._id );
}
});

View file

@ -29,7 +29,7 @@ Template.cleanUpModalConfirm.events({
case "Menus":
cleanUp("clean.Menus", whatItems);
case "Products":
// cleanUp("clean.Products", whatItems);
cleanUp("clean.Products", whatItems);
case "Stores":
// cleanUp("clean.Stores", whatItems);
case "Tasks":
@ -40,27 +40,34 @@ Template.cleanUpModalConfirm.events({
}
});
cleanUp = function(methodName, whatItems) {
Meteor.call(methodName, function(err, result) {
if (err) {
console.log(" ERROR cleaning " + whatItems + ": " + err);
} else {
showSnackbar(whatItems + " have been cleaned up!", "green");
let confirmModal = document.getElementById('cleanUpConfirm');
M.Modal.getInstance(confirmModal).close();
}
});
cleanUp = async function(methodName, whatItems) {
let result = Meteor.callAsync(methodName);
if (!result) {
console.log(" ERROR cleaning " + whatItems);
} else {
showSnackbar(whatItems + " have been cleaned up!", "green");
let confirmModal = document.getElementById('cleanUpConfirm');
M.Modal.getInstance(confirmModal).close();
}
}
cleanTasks = function(methodName, whatItems) {
cleanProducts = async function(methodName, whatItems) {
let result = await Meteor.call(methodName, whatItems);
if (!result) {
console.log(" ERROR cleaning " + whatItems);
} else {
showSnackbar(whatItems + " have been cleaned up.", "green");
}
}
cleanTasks = async function(methodName, whatItems) {
let timeFrame = Session.get("overdueVal");
Meteor.call(methodName, timeFrame, function(err, result) {
if (err) {
console.log(" ERROR cleaning " + whatItems + ": " + err);
} else {
showSnackbar(whatItems + " have been cleaned up!", "green");
let confirmModal = document.getElementById('cleanUpConfirm');
M.Modal.getInstance(confirmModal).close();
}
});
let result = await Meteor.call(methodName, timeFrame);
if (!result) {
console.log(" ERROR cleaning " + whatItems + ": " + err);
} else {
showSnackbar(whatItems + " have been cleaned up!", "green");
let confirmModal = document.getElementById('cleanUpConfirm');
M.Modal.getInstance(confirmModal).close();
}
}

View file

@ -2,11 +2,11 @@
<h4>Lists</h4>
<form action="submit" class="listAdd">
<div class="row">
<div class="col s8 m8 l10 input-field">
<div class="col s12 m8 l8 input-field">
<input type="text" class="listNameInp" style="{{#if $eq listNameErr true}}border: 2px solid red{{/if}}" id="listNameInp" />
<label for="listNameInp">List Name</label>
</div>
<div class="col s4 m4 l2 input-field">
<div class="col s12 m2 l2 input-field">
<p>
<label>
<input type="checkbox" id="isShared"/>
@ -14,6 +14,14 @@
</label>
</p>
</div>
<div class="col s12 m2 l2 input-field">
<p>
<label>
<input type="checkbox" id="isCompleted"/>
<span>Show Completed</span>
</label>
</p>
</div>
</div>
<div class="row">
<div class="col s12 m12 l12">

View file

@ -7,6 +7,7 @@ Template.listMgmtForm.onCreated(function() {
Template.listMgmtForm.onRendered(function() {
Session.set("listNameMiss", false);
Session.set("listNameEditMode", false);
Session.set("showCompletedLists", false);
});
Template.listMgmtForm.helpers({
@ -28,15 +29,7 @@ Template.listMgmtForm.events({
Session.set("listNameMiss", true);
return;
} else {
Meteor.call('add.list', listName, shared, function(err, result) {
if (err) {
// console.log(" ERROR adding list name: " + err);
} else {
// console.log(" SUCCESS adding list name.");
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
}
});
addList(listName, shared);
}
},
'click .renameListMgmt' (event) {
@ -49,16 +42,7 @@ Template.listMgmtForm.events({
Session.set("listNameMiss", true);
return;
} else {
Meteor.call('edit.list', listId, listName, shared, function(err, result) {
if (err) {
// console.log(" ERROR editing list name: " + err);
} else {
// console.log(" SUCCESS editing list name.");
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
Session.set("listNameEditMode", false);
}
});
editList(listId, listName, shared);
}
},
'submit .listAdd' (event) {
@ -73,27 +57,34 @@ Template.listMgmtForm.events({
return;
} else {
if (editMode == false) {
Meteor.call('add.list', listName, shared, function(err, result) {
if (err) {
// console.log(" ERROR adding list name: " + err);
} else {
// console.log(" SUCCESS adding list name.");
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
}
});
addList(listName, shared);
} else {
Meteor.call('edit.list', listId, listName, shared, function(err, result) {
if (err) {
// console.log(" ERROR editing list name: " + err);
} else {
// console.log(" SUCCESS editing list name.");
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
Session.set("listNameEditMode", false);
}
});
editList(listId, listName, shared);
}
}
},
'change #isCompleted' (event) {
Session.set("showCompletedLists", true);
},
});
const addList = async(listName, shared) => {
let result = await Meteor.callAsync('add.list', listName, shared);
if (!result) {
console.log("Nothing returned from method call add.list");
} else {
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
}
});
}
const editList = async(listId, listName, shared) => {
let result = await Meteor.callAsync('edit.list', listId, listName, shared);
if (!result) {
// console.log("Nothing returned from method call edit.list");
} else {
$("#listNameInp").val("");
$("#isShared").prop("checked", false);
Session.set("listNameEditMode", false);
}
}

View file

@ -8,6 +8,7 @@
<i class="material-icons clickable deleteListName tooltipped right modal-trigger" data-position="top" data-tooltip-id="deleteListIcon" data-target="modalDelete">delete</i>
<i class="material-icons clickable editListName tooltipped right" data-position="top" data-tooltip-id="editThisListIcon">edit</i>
<i class="material-icons clickable markListComplete tooltipped right" data-position="top" data-tooltip-id="markCompleteIcon">check</i>
<i class="material-icons clickable markListNotComplete tooltipped right" data-position="top" data-tooltip-id="markIncompleteIcon">refresh</i>
</li>
{{/each}}
</ul>
@ -21,6 +22,9 @@
<div id="markCompleteIcon" style="display: none;">
Mark list complete
</div>
<div id="markIncompleteIcon" style="display: none;">
Restore Completed List
</div>
</div>
{{> deleteConfirmationModal}}
</template>

View file

@ -2,7 +2,7 @@ import { Lists } from '../../../imports/api/lists.js';
import { M } from '../../lib/assets/materialize.js';
Template.listMgmtTbl.onCreated(function() {
this.subscribe("myLists");
this.subscribe("allLists");
});
Template.listMgmtTbl.onRendered(function() {
@ -14,7 +14,13 @@ Template.listMgmtTbl.onRendered(function() {
Template.listMgmtTbl.helpers({
lists: function() {
return Lists.find({});
let showComplete = Session.get("showCompletedLists");
// console.log("Show Complete Lists: " + showComplete);
if (showComplete) {
return Lists.find({});
} else {
return Lists.find({ listComplete: false });
}
}
});
@ -29,9 +35,14 @@ Template.listMgmtTbl.events({
},
'click .editListName' (event) {
event.preventDefault();
let listInfo = Lists.findOne({ _id: this._id });
let listName = listInfo.listName;
let listShared = listInfo.listShared;
const lInfo = async() => {
let listInfo = await Lists.findOneAsync({ _id: this._id });
return listInfo;
}
let listData = lInfo();
let listName = listData.listName;
let listShared = listData.listShared;
$("#listNameInp").val(listName);
if (listShared == true) {
$("#isShared").prop("checked", true);
@ -44,12 +55,27 @@ Template.listMgmtTbl.events({
'click .markListComplete' (event) {
event.preventDefault();
let listId = this._id;
Meteor.call('mark.complete', listId, function(err, result) {
if (err) {
// console.log(" ERROR marking complete: " + err);
const markComp = async() => {
let result = await Meteor.callAsync('mark.complete', listId);
if (!result) {
console.log(" ERROR marking complete.");
} else {
// console.log(" SUCCESS marking complete.");
}
});
}
markComp();
},
'click .markListNotComplete' (event) {
event.preventDefault();
let listId = this._id;
const markInc = async() => {
let result = await Meteor.callAsync('mark.incomplete', listId);
if (!result) {
console.log("Issue marking list incomplete.");
} else {
// console.log("List marked incomplete.");
}
}
markInc();
}
});

View file

@ -1,3 +1,5 @@
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
Template.mgmtPage.onCreated(function() {
});

View file

@ -2,14 +2,22 @@
<h4>Product Management</h4>
{{#if Template.subscriptionsReady}}
<form action="submit" class="row prodInputForm" style="gap: 1em;">
<div class="col s12">
<p>
<label>
<input type="checkbox" id="showNoStoreSet" />
<span>Show Products without Store Assigned</span>
</label>
</p>
</div>
<div class="col l4 m6 s12">
<p>
<label>
<input type="checkbox" id="showNoStoreSet" />
<span>Show Products without Store Assigned</span>
</label>
</p>
</div>
<div class="col l4 m6 s12">
<p>
<label>
<input type="checkbox" id="showNoList" />
<span>Show Products Never Used in a List</span>
</label>
</p>
</div>
<div class="col s12 m6 l6 input-field outlined">
<input type="text" class="prodName" style="{{#if $eq prodNameErr true}}border: 2px solid red;{{/if}}" id="prodName" />
<label for="prodName">Name*</label>

View file

@ -35,46 +35,65 @@ Template.prodMgmtForm.events({
'click .saveProdMgmt, click .editProdMgmt' (event) {
let name = $("#prodName").val();
let store = $("#prodStore").val();
let prodId = Session.get("prodEditId");
let prodEditMode = Session.get("prodEditMode");
if (store == null) {
store = "";
}
if (name == "" || name == null) {
Session.set("prodNameRed", true);
return;
} else {
if (prodEditMode == true) {
Meteor.call('edit.product', prodId, name, store, function(err, result) {
if (err) {
console.log(" ERROR: can't add product: " + err);
} else {
$("#prodName").val("");
showSnackbar("Successfully Edited Product!", "green");
}
});
editProd(prodId, name, store);
} else {
Meteor.call('add.product', name, store, function(err, result) {
if (err) {
console.log(" ERROR: can't add product: " + err);
} else {
$("#prodName").val("");
showSnackbar("Product Added Succssfully!", "green");
}
});
newProd(name, store);
}
}
},
'click #showNoStoreSet' (event) {
let noStoreSet = $("#showNoStoreSet").prop('checked');
console.log("Clicked: " + noStoreSet);
// console.log("Clicked: " + noStoreSet);
if (noStoreSet == true) {
Session.set("noStoreSet", true);
} else {
Session.set("noStoreSet", false);
}
}
},
'click #showNoList' (event) {
let notUsedInList = $("#showNoList").prop('checked');
if (notUsedInList == true) {
Session.set("noListUsed", true);
} else {
Session.set("noListUsed", false);
}
},
'submit .prodInputForm' (event) {
},
});
const newProd = async(name, store) => {
let result = await Meteor.callAsync('add.product', name, store);
try {
if (!result) {
// console.log("No result when trying to add a new product.");
showSnackbar("Unable to add new product.");
} else {
$("#prodName").val("");
showSnackbar("New Product Added!", "green");
}
} catch(error) {
console.log(" ERROR - couldn't add product: " + error);
}
}
const editProd = async(prodId, name, store) => {
let result = await Meteor.callAsync('edit.product', prodId, name, store);
if (!result) {
console.log(" ERROR: can't add product: " + err);
} else {
$("#prodName").val("");
showSnackbar("Successfully Edited Product!", "green");
}
}

View file

@ -1,14 +1,17 @@
import { Products } from '../../../imports/api/products.js';
import { ListItems } from '../../../imports/api/listItems.js';
import { M } from '../../lib/assets/materialize.js';
Template.prodMgmtTbl.onCreated(function() {
this.subscribe("myProducts");
this.subscribe("allListItems");
});
Template.prodMgmtTbl.onRendered(function() {
Session.set("searchProds", false);
Session.set("searchStore", false);
Session.set("noStoreSet", false);
Session.set("noListUsed", false);
});
Template.prodMgmtTbl.helpers({
@ -16,25 +19,37 @@ Template.prodMgmtTbl.helpers({
let searchProd = Session.get("searchProds");
let searchStore = Session.get("searchStore");
let noStoreSet = Session.get("noStoreSet");
let noListUsed = Session.get("noListUsed");
if (searchProd == true) {
let searchVal = Session.get("searchVal");
if (typeof searchVal == 'undefined' || searchVal.length == 0) {
return Products.find({});
} else {
return Products.find({ prodName: { $regex: searchVal + '.*', $options: 'i' } });
return Products.find({ prodName: { $regex: searchVal + '.*', $options: 'i' } }, { sort: { prodName: 1 }});
}
} else if (searchStore == true) {
let searchVal = Session.get("searchStoreVal");
if (typeof searchVal == 'undefined' || searchVal.length == 0) {
return Products.find({});
} else {
return Products.find({ prodStore: { $regex: searchVal + '.*', $options: 'i' } });
return Products.find({ prodStore: { $regex: searchVal + '.*', $options: 'i' } }, { sort: { prodName: 1 }});
}
} else if (noStoreSet == true) {
return Products.find({ prodStore: '' });
return Products.find({ prodStore: '' }, { sort: { prodName: 1 }});
} else if (noListUsed == true) {
let i;
let idList = [];
let idsInLists = ListItems.find({}).fetch();
for (i=0; i < idsInLists.length; i++) {
idList.push(idsInLists[i].prodId);
}
if (i > idsInLists.length - 1) {
let noProdsNot = Products.find({ _id: { $nin: idList }}).count();
return Products.find({ _id: { $nin: idList }}, { sort: { prodName: 1 }});
}
} else {
return Products.find({});
return Products.find({}, { sort: { prodName: 1 }});
}
},
searchProd: function() {
@ -57,10 +72,17 @@ Template.prodMgmtTbl.events({
event.preventDefault();
Session.set("prodEditMode", true);
Session.set("prodEditId", this._id);
let prodInfo = Products.findOne({ _id: this._id });
$("#prodName").val(prodInfo.prodName);
$("#prodStore").val(prodInfo.prodStore);
// $('select').formSelect();
const getProds = async() => {
let prodInfo = await Products.findOneAsync({ _id: this._id });
if (!prodInfo) {
// console.log("No Product Returned.");
} else {
$("#prodName").val(prodInfo.prodName);
$("#prodStore").val(prodInfo.prodStore);
}
}
getProds();
},
'click #filterProds' (event) {
event.preventDefault();

View file

@ -23,14 +23,7 @@ Template.storeMgmtForm.events({
Session.set("borderRed", true);
return;
} else {
Meteor.call("add.store", storeName, function(err, result) {
if (err) {
console.log("ERROR: Store add failed: " + err);
} else {
$("#storeName").val("");
showSnackbar("Store Added Successfully!", "green");
}
});
addStore(storeName);
}
},
'click .cancelStoreMgmt' (event) {
@ -38,51 +31,51 @@ Template.storeMgmtForm.events({
$("#storeName").val("");
Session.set("editModeStore", false);
},
// 'submit #storeForm' (event) {
// event.preventDefault();
// let editMode = Session.get("editModeStore");
// let storeName = $("#storeName").val();
// if (storeName == "" || storeName == null) {
// Session.set("borderRed", true);
// return;
// } else {
// if (editMode == false) {
// Meteor.call("add.store", storeName, function(err, result) {
// if (err) {
// console.log("ERROR: Store add failed: " + err);
// } else {
// $("#storeName").val("");
// }
// });
// } else {
// let storeId = Session.get("storeIdEdit");
// Meteor.call("edit.store", storeId, storeName, function(err, result) {
// if (err) {
// console.log("ERROR: Store add failed: " + err);
// } else {
// $("#storeName").val("");
// Session.set("editModeStore", false);
// }
// });
// }
// }
// },
'submit #storeForm' (event) {
event.preventDefault();
let editMode = Session.get("editModeStore");
let storeName = $("#storeName").val();
if (storeName == "" || storeName == null) {
Session.set("borderRed", true);
return;
} else {
if (editMode == false) {
addStore(storeName);
} else {
let storeId = Session.get("storeIdEdit");
editStore(storeId, storeName);
}
}
},
'click .editStoreMgmt' (event) {
let storeName = $("#storeName").val();
let storeId = Session.get("storeIdEdit");
if (storeName == "" || storeName == null) {
Session.set("borderRed", true);
return;
} else {
Meteor.call("edit.store", storeId, storeName, function(err, result) {
if (err) {
console.log("ERROR: Store add failed: " + err);
} else {
$("#storeName").val("");
Session.set("editModeStore", false);
showSnackbar("Store Updated Successfully!", "green");
}
});
} else {
editStore(storeId, storeName);
}
}
});
});
const addStore = async(storeName) => {
let result = await Meteor.callAsync("add.store", storeName);
if (!result) {
// console.log("ERROR: Store add failed.");
} else {
$("#storeName").val("");
showSnackbar("Store Added Successfully!", "green");
}
}
const editStore = async(storeId, storeName) => {
let result = await Meteor.callAsync("edit.store", storeId, storeName);
if (!result) {
// console.log("ERROR: Store add failed: " + err);
} else {
$("#storeName").val("");
Session.set("editModeStore", false);
showSnackbar("Store Updated Successfully!", "green");
}
}

View file

@ -1,7 +1,7 @@
<template name="systemAdmin">
<h2>System Administration</h2>
<div class="row">
<div class="col s12 m12 l6">
<div class="col s12">
<div class="card">
<div class="card-content">
<h4>Registration Settings</h4>
@ -18,11 +18,31 @@
<div class="col s12 m6 l6">
<div class="switch">
<label>
<input type="checkbox" class="currConfigs" id="allowGenReg">
<span class="lever"></span>
Allow Registration
<input type="checkbox" class="currConfigs" id="allowGenReg">
<span class="lever"></span>
Allow Registration
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<h4>Update Notifications</h4>
<p>This option requires the seerver to have an internet connection.</p>
<br>
<div class="row">
<div class="col s12 m12 l6">
<div class="switch">
<label>
<input type="checkbox" class="currConfigs" id="recvUpdateMsgs">
<span class="lever"></span>
System Admin will receive information on updates and new featres
</label>
</div>
</div>
</div>
</div>
@ -30,4 +50,4 @@
</div>
</div>
{{> snackbar}}
</template>
</template>

View file

@ -1,7 +1,9 @@
import { SysConfig } from '../../../imports/api/systemConfig.js';
import { M } from '../../lib/assets/materialize.js';
Template.systemAdmin.onCreated(function() {
this.subscribe("SystemConfig");
this.subscribe("rolesAvailable");
});
Template.systemAdmin.onRendered(function() {
@ -10,31 +12,49 @@ Template.systemAdmin.onRendered(function() {
if (typeof curr != 'undefined') {
$("#allowGenReg").prop('checked', curr.allowReg);
$("#allAdmReg").prop('checked', curr.SysAdminReg);
$("#recvUpdateMsgs").prop('checked', curr.allowUpdates);
} else {
console.log(" ---- unable to find current system configuration.");
// console.log(" ---- unable to find current system configuration.");
}
});
var elems = document.querySelectorAll('select');
setTimeout(function() {
var instances = M.FormSelect.init(elems, {});
}, 300);
});
Template.systemAdmin.helpers({
currConfigs: function() {
}
});
Template.systemAdmin.events({
'change #allowGenReg, change #allowAdmReg' (evnnt) {
let genReg = $("#allowGenReg").prop('checked');
let admReg = $("#allowAdmReg").prop('checked');
// console.log("General Reg set to: " + genReg);
Meteor.call("add.noSysAdminReg", admReg, genReg, function(err, result) {
if (err) {
console.log(" ERROR updating permission to allow general registration: " + err);
const addNoSysReg = async() => {
let result = await Meteor.callAsync("add.noSysAdminReg", admReg, genReg);
if (!result) {
showSnackbar("Registration Permission Change Failed.", "red");
} else {
console.log(" Successfully updated permission to allow general registration.");
showSnackbar("Registration Permission Successfully Changed.", "green")
}
});
}
});
}
addNoSysReg();
},
'change #recvUpdateMsgs' (event) {
let updSet = $("#recvUpdateMsgs").prop('checked');
const allowUpdateInfo = async() => {
let result = await Meteor.callAsync('allow.updateInfo', updSet);
if (!result) {
// console.log(" ERROR changing update setting.");
showSnackbar("Update Setting Change Failed.", "red");
} else {
showSnackbar("Update Setting Changed Successfully!", "green");
}
}
allowUpdateInfo();
},
});

View file

@ -3,7 +3,7 @@
<form class="row" style="gap: 1em;">
<div class="col s12 m6 l4 chips chips-placeholder" id="taskName">
</div>
<div class="col s12 m6 l4 input-field outlined">
<div class="col s12 m6 l4 input-field">
<select name="taskUser" id="taskUser" class="taskUser">
<option value="" disabled selected>Assign to user...</option>
{{#each taskUsers}}
@ -11,7 +11,7 @@
{{/each}}
</select>
</div>
<div class="col s12 m6 l4 input-field outlined">
<div class="col s12 m6 l4 input-field">
<input type="text" class="datepicker" id="taskDate" />
<label for="taskDate">Task Date (multiple entries)</label>
<div class="row">

View file

@ -50,7 +50,7 @@ Template.taskForm.events({
event.preventDefault();
let elemcc = document.getElementById('taskName');
let taskName = M.Chips.getInstance(elemcc).chipsData;
console.log(taskName);
// console.log(taskName);
},
'change #taskDate' (event) {
let taskDate = $("#taskDate").val();
@ -69,7 +69,6 @@ Template.taskForm.events({
let taskDateErr = false;
let userInfo;
let actDate = [];
// console.dir(taskNameArr);
if (taskNameArr == null || taskNameArr == []) {
taskNameErr = true;
@ -92,17 +91,19 @@ Template.taskForm.events({
}
if (taskUserErr == false && taskDateErr == false && taskNameErr == false) {
Meteor.call("add.task", taskNameArr, userInfo[0], userInfo[1], taskDateArr, actDate, function(err, result) {
if (err) {
console.log(" ERROR adding the new task: " + err);
const addTask = async() => {
let result = await Meteor.callAsync("add.task", taskNameArr, userInfo[0], userInfo[1], taskDateArr, actDate);
if (!result) {
// console.log(" ERROR adding the new task.");
} else {
console.log(" SUCCESS adding the new task.");
// console.log(" SUCCESS adding the new task.");
Session.set("taskDateArr", []);
$("#taskDate").val("");
$("#taskUser").val("");
$('select').formSelect();
}
});
}
addTask();
} else {
showSnackbar("ERROR: Missing Required Fields!", "red");
}
@ -113,7 +114,6 @@ Template.taskForm.events({
Session.set("hideCompletedTasks", true);
} else {
Session.set("hideCompletedTasks", false);
}
}
}
});

View file

@ -43,13 +43,15 @@ Template.taskTbl.events({
'click .markTaskComplete' (event) {
event.preventDefault();
let taskId = this._id;
Meteor.call("markTask.complete", taskId, function(err, result) {
if (err) {
console.log(" ERROR marking task completeL " + err);
const markComp = async() => {
let result = await Meteor.callAsync("markTask.complete", taskId);
if (!result) {
// console.log(" ERROR marking task completeL " + err);
showSnackbar("ERROR Marking Task Complete!", "red");
} else {
showSnackbar("Successfully Marked Task Complete!", "green");
}
});
}
markComp();
},
});

View file

@ -1,6 +1,45 @@
<template name="dashboard">
<h4>My Dashboard</h4>
<div class="row">
{{#if $eq currConfig.allowUpdates true}}
{{#if $eq updatesExist true}}
<div class="col s12">
<ul class="collapsible green darken-3 white-text">
<li>
<div class="collapsible-header"><strong>Update Available</strong></div>
<div class="collapsible-body">
<div class="row">
{{#each updates}}
<div class="col s12">
<div class="row">
<div class="col s12">
<h4>{{title}}</h4>
</div>
<div class="col s12">
Release Notes:
<p class="flow-text">{{{descriptionSinHTML}}}</p>
</div>
<div class="col s12">
Release Date:
<p class="flow-text">{{niceDate}}</p>
</div>
<div class="col s12">
<a href="{{releaseLink}}" target=”_blank”>Visit Release on Gitlab</a>
</div>
</div>
</div>
<div class="col s12">
<a class="btn waves-effect waves-light blue white-text readLink" id="{{_id}}">Mark Read</a>
</div>
<hr />
{{/each}}
</div>
</div>
</li>
</ul>
</div>
{{/if}}
{{/if}}
<div class="col s12 m6 l4">
<div class="card blue darken-3" id="taskInfoCard">
<div class="card-content white-text">

View file

@ -5,7 +5,10 @@ import { Menus } from '../../imports/api/menu.js';
import { MenuItems } from '../../imports/api/menuItems.js';
import moment from 'moment';
import { TaskItems } from "../../imports/api/tasks";
import { UpdateInfo } from '../../imports/api/updateInfo.js';
import { SysConfig } from '../../imports/api/systemConfig.js';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import { M } from '../lib/assets/materialize.js';
Template.dashboard.onCreated(function() {
this.subscribe("userList");
@ -17,10 +20,15 @@ Template.dashboard.onCreated(function() {
// this.subscribe("myMenus");
this.subscribe("todayMenuItems");
this.subscribe("myTasks");
this.subscribe("UpdateVersion");
this.subscribe("SystemConfig");
});
Template.dashboard.onRendered(function() {
setTimeout(function() {
var elems = document.querySelectorAll('.collapsible');
var instances = M.Collapsible.init(elems, {});
}, 200);
});
Template.dashboard.helpers({
@ -56,11 +64,64 @@ Template.dashboard.helpers({
let todayDate = moment(now).format("MMM DD, YYYY");
return todayDate;
},
updates: function() {
let updateAvail = UpdateInfo.find({});
try {
if (!updateAvail) {
// console.log("No update info found.");
return false;
} else {
// console.dir(updateAvail);
return updateAvail;
}
} catch(error) {
console.log(" ERROR trying to grab update info: " + error);
}
},
updatesExist: function() {
const ifUpdate = async() => {
let updateExists = await UpdateInfo.findOneAsync({ viewed: false });
if (!updateExists) {
// console.log("Update doesn't exist as false.");
return false;
} else {
// console.log("Update found with false.");
return true;
}
}
let updateAvail = ifUpdate();
return updateAvail;
},
currConfig: function() {
const getSys = async() => {
let currSys = SysConfig.findOneAsync({});
try {
if (!currSys) {
// console.log("No System Config found.")
} else {
return currSys;
}
} catch(error) {
console.log(" ERROR trying to fetch current system config: " + error);
}
}
let currConf = getSys();
return currConf;
},
descriptionSinHTML: function() {
let desc = this.description;
let sinH = $(desc).text();
return desc;
},
niceDate: function() {
let rDateNorm = this.date;
let rDate = moment(rDateNorm).format('LL');
return rDate;
}
});
Template.dashboard.events({
"click .cardLink" (event) {
event.preventDefault();
let link = event.currentTarget.id;
switch(link) {
case "userMgmtLink":
@ -86,7 +147,6 @@ Template.dashboard.events({
}
},
'click .card' (event) {
event.preventDefault();
let cardId = event.currentTarget.id;
switch(cardId) {
@ -111,5 +171,23 @@ Template.dashboard.events({
default:
break;
}
},
'click .readLink' (event) {
let eventId = event.currentTarget.id;
const markUpdate = async() => {
let result = await Meteor.callAsync('markUpdate.read', eventId);
try {
if (!result) {
// console.log(" Error marking this read.");
showSnackbar("Error Marking Read!", "red");
} else {
showSnackbar("Successfully Marked as Read.", "green");
}
} catch(error) {
console.log(" ERROR trying to mark this update as read: " + error);
}
}
markUpdate();
}
});

View file

@ -22,14 +22,16 @@ Template.deleteConfirmationModal.events({
let deleteId = Session.get("deleteId");
let method = Session.get("method");
Meteor.call(method, deleteId, function(err, result) {
if (err) {
const delItem = async() => {
let result = await Meteor.callAsync(method, deleteId);
if (!result) {
console.log(" ERROR deleting item from modal: " + err);
} else {
console.log(" SUCCESSFULLY deleted.");
// put the new modal open / close here
// $('#modalDelete').modal('close');
}
});
}
delItem();
},
});

View file

@ -11,11 +11,14 @@
<li><a href="#" id="mylists" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Lists</a></li>
<li><a href="#" id="mymenus" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Menus</a></li>
<li><a href="#" id="myTasks" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Tasks</a></li>
<li><a href="#" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}" id="mySettings">My Settings</a></li>
{{#if isInRole 'systemadmin'}}
<li><a href="#" id="mySettings" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Settings</a></li>
{{#if isInRole "systemadmin"}}
<li><a href="#" id="manage" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">Manage</a></li>
{{/if}}
<li class="signOut {{#if $eq myTheme 'dark'}}white-text{{/if}}"><a href="#" class="signOut">Log Out</a></li>
{{#if $eq updateExists true}}
<li><a href="#!"><i class="material-icons white-text navBtn" id='dashboard'>notifications</i></a></li>
{{/if}}
{{else}}
<li><a href="#!" id="login" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">Login</a></li>
{{/if}}
@ -27,9 +30,12 @@
<li><a href="#!" id="mylists" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Lists</a></li>
<li><a href="#!" id="mymenus" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Menus</a></li>
<li><a href="#!" id="myTasks" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Tasks</a></li>
<li><a href="#!" class="navBtn" id="mySettings {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Settings</a></li>
<li><a href="#!" id="mySettings" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">My Settings</a></li>
{{#if isInRole 'systemadmin'}}
<li><a href="#!" id="manage" class="navBtn {{#if $eq myTheme 'dark'}}white-text{{/if}}">Manage</a></li>
{{#if $eq updateExists true}}
<li><a href="#!"><i class="material-icons navBtn" id="dashboard">notifications</i></a></li>
{{/if}}
{{/if}}
<li><a href="#!" class="signOut {{#if $eq myTheme 'dark'}}white-text{{/if}}">Sign Out</a></li>
{{else}}

View file

@ -1,14 +1,38 @@
import { Meteor } from 'meteor/meteor';
import { M } from '../lib/assets/materialize';
import { UpdateInfo } from '../../imports/api/updateInfo.js';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import { Roles } from 'meteor/roles';
Template.headerBar.onCreated(function() {
this.subscribe("UpdateVersion");
this.subscribe("assignment");
});
Template.headerBar.onRendered(function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, {});
var elemd = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elemd, {});
var instances = M.Dropdown.init(elemd, {});
setTimeout(function() {
const getRoles = async() => {
let userId = Meteor.userId();
// let isRole = await Roles.userIsInRoleAsync(userId, "systemadmin");
let isRole = await Roles.getRolesForUserAsync(userId);
try {
if (!isRole) {
// console.log("SystemAdmin role for user not found: " + isRole);;
} else {
// console.log("Found role for the user: ");
// console.dir(isRole);
}
} catch(error) {
console.log(" ERROR getting role for user: " + error);
}
}
getRoles();
}, 1000);
});
Template.headerBar.helpers({
@ -17,7 +41,15 @@ Template.headerBar.helpers({
},
myTheme: function() {
return Session.get("myTheme");
}
},
updateExists: function() {
let update = UpdateInfo.find({ viewed: false }).fetch();
if (update.length > 0) {
return true;
} else {
return false;
}
},
});
Template.headerBar.events({

View file

@ -0,0 +1,27 @@
<template name="listItemTblByStore">
<div class="row">
<div class="col s12">
<span>Products with no assigned store, will not be displayed on this version of the list.</span>
<ul class="collection with-header">
{{#each stores}}
{{#if $eq storeInList true}}
<li class="collection-header"><h4>{{storeName}}</h4></li>
{{#each thisListItems}}
<li class="collection-item" id="{{_id}}-{{itemOrdered}}">
<span>
{{#if $eq itemOrdered true}}
<strike>{{itemName}}</strike>
{{else}}
{{itemName}}
{{/if}}
</span>
<i class="material-icons clickable deleteListItem right modal-trigger" href="#modalDelete">delete</i>
<i class="material-icons clickable markListItemReceived right">check</i>
</li>
{{/each}}
{{/if}}
{{/each}}
</ul>
</div>
</div>
</template>

View file

@ -0,0 +1,89 @@
import { ListItems } from '../../imports/api/listItems.js';
import { M } from '../lib/assets/materialize.js';
import { UserLast } from '../../imports/api/userLast.js';
import { Stores } from '../../imports/api/stores.js';
Template.listItemTblByStore.onCreated(function() {
this.autorun( () => {
this.subscribe("myListItems", Session.get("listId"));
});
this.subscribe("storeInfo");
this.subscribe("userLastView");
});
Template.listItemTblByStore.onRendered(function() {
Session.set("showReceivedItems", false);
Session.set("searchVal", "");
});
Template.listItemTblByStore.helpers({
stores: function() {
let storeList = Stores.find({});
return storeList;
},
thisListItems: function() {
let showReceived = Session.get("showReceivedItems");
let searchVal = Session.get("searchVal");
let store = this.storeName;
if (showReceived == false) {
if (typeof searchVal == 'undefined' || searchVal.length === 0) {
return ListItems.find({ itemStore: store, itemReceived: false });
} else {
return ListItems.find({ itemStore: store, itemReceived: false, itemName: { $regex: searchVal + '.*', $options: 'i' }})
}
} else {
if (typeof searchVal == 'undefined' || searchVal.length == 0) {
return ListItems.find({ itemStore: store });
} else {
return ListItems.find({ itemStore: store, itemName: { $regex: searchVal + '.*', $options: 'i' } });
}
}
},
storeInList: function() {
let noStoresInList = ListItems.find({ itemStore: this.storeName }).count();
if (noStoresInList > 0) {
return true;
} else {
return false;
}
},
});
Template.listItemTblByStore.events({
'click li' (event) {
let itemSel = (event.currentTarget.id).split('-');
let itemId = itemSel[0];
let itemOrder = itemSel[1];
if (typeof itemOrder == 'undefined' || itemOrder == "" || itemOrder == false) {
Meteor.call("setOrdered.listItem", itemId, function(err, result) {
if (err) {
// console.log(" ERROR updating order status to ordered: " + err);
}
});
} else {
Meteor.call("setNotOrdered.listItem", itemId, function(err, result) {
if (err) {
// console.log(" ERROR updating order status to unordered: " + err);
}
});
}
},
'click .markListItemReceived' (event) {
event.preventDefault();
Meteor.call('setReceived.listItem', this._id, function(err, result) {
if (err) {
// console.log(" ERROR setting item as received: " + err);
} else {
// console.log(" SUCCESS setting item received.");
}
});
},
'click .deleteListItem' (event) {
event.preventDefault();
Session.set("deleteId", this._id);
Session.set("method", "delete.listItem");
Session.set("item", this.itemName);
Session.set("view", "List Items");
},
});

View file

@ -37,7 +37,7 @@
</div>
{{else}}
<div class="row">
<div class="col s8 m9 l10 input-field">
<div class="col s8 m9 l10 input-field outlined">
<input type="text" class="autocomplete" id="findListItems" autocomplete="off" />
<label for="findListItems">Item...</label>
</div>
@ -46,4 +46,4 @@
</div>
</div>
{{/if}}
</template>
</template>

View file

@ -39,7 +39,7 @@ Template.listItemsForm.helpers({
selListId = selListInfo.viewId;
Session.set("listId", selListId);
} else {
console.log("not finding any value for viewId.");
// console.log("not finding any value for viewId.");
}
}
let listInfo = Lists.findOne({ _id: selListId });
@ -48,6 +48,7 @@ Template.listItemsForm.helpers({
}
},
itemProdName: function() {
return Products.find({});
},
editMode: function() {
@ -66,14 +67,7 @@ Template.listItemsForm.events({
if (item == null || item == "") {
Session.set("itemReqErr", true);
} else {
Meteor.call("add.listItem", item, listId, function(err, result) {
if (err) {
console.log(" ERROR adding item to list: " + err);
} else {
console.log(" SUCCESS adding item to list.");
$("#findListItems").val("");
}
});
addItem(item, listId);
}
},
'keydown #findListItems' (event) {
@ -83,14 +77,7 @@ Template.listItemsForm.events({
if (item == null || item == "") {
Session.set("itemReqErr", true);
} else {
Meteor.call("add.listItem", item, listId, function(err, result) {
if (err) {
console.log(" ERROR adding item to list: " + err);
} else {
console.log(" SUCCESS adding item to list.");
$("#findListItems").val("");
}
});
addItem(item, listId);
}
}
},
@ -110,24 +97,42 @@ Template.listItemsForm.events({
'keyup #findListItems' (event) {
if (event.which !== 13) {
let findItemVal = $("#findListItems").val();
// console.log(findItemVal);
let listItemInfo = Products.find({ prodName: {$regex: findItemVal + '.*', $options: 'i'}}).fetch();
if (typeof listItemInfo != 'undefined' && listItemInfo != "" && listItemInfo != null) {
if (!listItemInfo) {
// console.log("No data for key input.");
} else {
getDataList(listItemInfo);
}
}
},
'click #filterOn' (event) {
event.preventDefault();
Session.set("filtering", true);
},
'click #filterOff' (event) {
event.preventDefault();
// clear filter field
Session.set("searchVal", "");
$("#searchListItems").val("");
Session.set("filtering", false);
}
});
getDataList = function(listItemInfo) {
// console.log(listItemInfo);
let listItemObjArray = [];
listItemObjArray = listItemInfo.map(info => ({ id: info._id, text: info.prodName, store: info.prodStore }))
Session.set("findListItems", listItemObjArray);
}
}
const addItem = async(item, listId) => {
let result = await Meteor.callAsync("add.listItem", item, listId);
try {
if (!result) {
// console.log(" ISSUE adding list item. See logs.");
} else {
$("#findListItems").val("");
}
} catch(error) {
console.log(" ERROR adding list item: " + error);
}
}

View file

@ -1,5 +1,22 @@
<template name="listItemsMain">
{{> listItemsForm}}
<hr>
{{> listItemsTbl}}
</template>
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab col s6">
<a href="#listOnly" class='active'>List</a>
</li>
<li class="tab col s6">
<a href="#listByStore">List by Store</a>
</li>
</ul>
</div>
<div id="listOnly" class="col s12">
{{> listItemsTbl}}
</div>
<div id="listByStore" class="col s12">
{{> listItemTblByStore}}
</div>
</div>
</template>

View file

@ -1,9 +1,12 @@
import { M } from '../lib/assets/materialize.js';
Template.listItemsMain.onCreated(function() {
});
Template.listItemsMain.onRendered(function() {
var elems = document.querySelectorAll('.tabs');
var instance = M.Tabs.init(elems, {});
});
Template.listItemsMain.helpers({
@ -12,4 +15,4 @@ Template.listItemsMain.helpers({
Template.listItemsMain.events({
});
});

View file

@ -20,15 +20,15 @@ Template.listItemsTbl.onRendered(function() {
Template.listItemsTbl.helpers({
'thisListItems': function() {
let showRecvd = Session.get("showReceivedItems");
let searchVal = Session.get("searchVal");;
let searchVal = Session.get("searchVal");
if (showRecvd == false) {
if (typeof searchVal == 'undefined' || searchVal.length === 0) {
if (!searchVal) {
return ListItems.find({ itemReceived: false });
} else {
return ListItems.find({ itemReceived: false, itemName: { $regex: searchVal + '.*', $options: 'i' } });
}
} else {
if (typeof searchVal == 'undefined' || searchVal.length == 0) {
if (!searchVal) {
return ListItems.find({});
} else {
return ListItems.find({ itemName: { $regex: searchVal + '.*', $options: 'i' } });
@ -40,34 +40,37 @@ Template.listItemsTbl.helpers({
Template.listItemsTbl.events({
'click li' (event) {
event.preventDefault();
let itemInfo = ListItems.findOne({ _id: this._id });
if (itemInfo.itemOrdered == true) {
Meteor.call('setNotOrdered.listItem', this._id, function(err, result) {
if (err) {
console.log(" ERROR setting this item as NOT ordered: " + err);
const setOrd = async() => {
let itemInfo = await ListItems.findOneAsync({ _id: this._id });
if (itemInfo.itemOrdered == true) {
let result = await Meteor.callAsync('setNotOrdered.listItem', this._id);
if (!result) {
// console.log(" ERROR seeting item as not ordered.");
} else {
// console.log(" SUCCESS setting this item as NOT ordered.");
}
});
} else {
Meteor.call('setOrdered.listItem', this._id, function(err, result) {
if (err) {
console.log(" ERROR marking item ordered: " + err);
// console.log(" SUCCESS setting item as ordered.");
}
} else {
let result = Meteor.callAsync('setOrdered.listItem', this._id);
if (!result) {
// console.log(" ERROR marking item ordered: " + err);
} else {
// console.log(" SUCCESS marking this item ordered.");
}
});
}
}
setOrd();
},
'click .markListItemReceived' (event) {
event.preventDefault();
Meteor.call('setReceived.listItem', this._id, function(err, result) {
if (err) {
console.log(" ERROR setting item as received: " + err);
const setRcvd = async() => {
let result = await Meteor.callAsync('setReceived.listItem', this._id);
if (!result) {
// console.log("Item not marked properly - why?");
} else {
// console.log(" SUCCESS setting item received.");
// console.log("Item Marked Received.");
}
});
}
setRcvd();
},
'click .deleteListItem' (event) {
event.preventDefault();
@ -76,4 +79,4 @@ Template.listItemsTbl.events({
Session.set("item", this.itemName);
Session.set("view", "List Items");
},
});
});

View file

@ -1,5 +1,6 @@
import { Lists } from '../../imports/api/lists.js';
import { M } from '../lib/assets/materialize.js';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
Template.listsTbl.onCreated(function() {
this.subscribe("myLists");
@ -27,15 +28,17 @@ Template.listsTbl.events({
} 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);
const addUserLast = async() => {
let result = await Meteor.callAsync('add.userLast', "List", listId);
if (!result) {
// console.log(" ERROR setting user last list id in db: " + err);
} else {
Meteor.setTimeout(function() {
setTimeout(function() {
FlowRouter.go('/listitems');
}, 100);
}
});
}
addUserLast();
}
}
},
@ -47,15 +50,17 @@ Template.listsTbl.events({
let splitList = listFullId.split("_");
let listId = splitList[1];
// console.log("listId is " + listId);
Meteor.call("mark.complete", listId, function(err, result){
if (err) {
console.log(" ERROR marking list complete! " + err);
const markComp = async() => {
let result = await Meteor.callAsync("mark.complete", listId);
if (!result) {
// console.log(" ERROR marking list complete!");
showSnackbar("ERROR! List Not Makred Complete!", "red");
} else {
// console.log(" SUCCESS marking list complete.");
showSnackbar("List Marked Complete!", "green");
}
});
}
markComp();
}
}
});

View file

@ -7,20 +7,27 @@ Template.MainLayout.onCreated(function() {
Template.MainLayout.onRendered(function() {
this.autorun(() => {
let myId = Meteor.userId();
let myprefs = UserConfig.findOne({ user: myId });
if (typeof myprefs != 'undefined') {
if (myprefs.darkMode == "light") {
console.log("Found theme as light");
Session.set("myTheme", "light");
document.documentElement.setAttribute('theme', "light");
} else {
console.log("Found theme as dark");
Session.set("myTheme", "dark");
document.documentElement.setAttribute('theme', "dark");
}
} else {
console.log("User Prefs appear undefined.");
const getConfig = async() => {
let myprefs = await UserConfig.findOneAsync({ user: myId });
try {
if (!myprefs) {
// console.log("User Prefs appear undefined.");
} else {
if (myprefs.darkMode == "light") {
// console.log("Found theme as light");
Session.set("myTheme", "light");
document.documentElement.setAttribute('theme', "light");
} else {
// console.log("Found theme as dark");
Session.set("myTheme", "dark");
document.documentElement.setAttribute('theme', "dark");
}
}
} catch(error) {
console.log(" ERROR getting user preferences: " + error);
}
}
getConfig();
});
});

View file

@ -39,10 +39,9 @@
<a class="left btn waves-effect waves-light orange white-text modal-close">Cancel</a>
</div>
<div class="col s6 m6 l6">
<a class="right btn waves-effect waves-light green white-text saveProdsToList" id="saveProdsToList">Save to List</a>
<a class="right btn waves-effect waves-light green white-text saveProdsToList modal-close" id="saveProdsToList">Save to List</a>
</div>
</div>
</div>
</div>
</div>
{{> snackbar}}

View file

@ -31,9 +31,9 @@ Template.addProdToListModal.helpers({
},
productToChoose: function() {
let menuItemId = Session.get("menuItemId");
console.log("Menu Item Id received is: " + menuItemId);
// console.log("Menu Item Id received is: " + menuItemId);
let prodLinkLIst = MenuProdLinks.find({ menuItemId: menuItemId});
console.dir(prodLinkLIst);
// console.dir(prodLinkLIst);
if (typeof prodLinkLIst != 'undefined' && prodLinkLIst != "" && prodLinkLIst != null) {
return prodLinkLIst;
}
@ -44,24 +44,23 @@ Template.addProdToListModal.events({
'click .productListing' (event) {
let itemId = event.currentTarget.id;
let selected = Session.get("itemsSelected");
console.log("Item clicked: " + itemId);
// console.log("Item clicked: " + itemId);
selected.push(itemId);
console.dir(selected);
// console.dir(selected);
Session.set("itemsSelected", selected);
},
'click #saveProdsToList' (event) {
event.preventDefault();
let selectedItems = Session.get("itemsSelected");
let listId = $("#chooseList").val();
// console.log(" calling meteor method with items: ");
// console.dir(selectedItems);
// console.log(" and list id: "+ listId);
Meteor.call('add.itemsFromMenuItem', selectedItems, listId, function(err, result) {
if (err) {
console.log(" ERROR adding menu components to list: " + err);
const addItemsFromMenu = async() => {
let result = await Meteor.callAsync('add.itemsFromMenuItem', selectedItems, listId);
if (!result) {
console.log(" ERROR adding menu components to list: ");
} else {
showSnackbar("Items Added to List!", "green");
}
});
}
addItemsFromMenu();
}
});
});

View file

@ -38,13 +38,27 @@ Template.menuItemsForm.helpers({
if (Session.get("menuId")) {
menuId = Session.get("menuId");
} else {
menuId = UserLast.findOne({ view: "Menu" }).viewId;
const menuInfor = async() => {
let result = await UserLast.findOneAsync({ view: "Menu" }).viewId;
if (!result) {
} else {
return result;
}
}
let menuId = menuInfor();
}
let menuInfo = Menus.findOne({ _id: menuId });
if (menuInfo) {
return menuInfo.menuName;
const menuData = async() => {
let menuInfo = await Menus.findOneAsync({ _id: menuId });
if (!menuInfo) {
return;
} else {
return menuInfo.menuName;
}
}
let menuInformation = menuData();
return menuInformation;
}
});
@ -55,49 +69,77 @@ Template.menuItemsForm.events({
let dateSrv = $("#dateServed").val();
let menuId = Session.get("menuId");
if (menuId == null || menuId == "") {
console.log(" ---- NO MENU ID! ----");
}
let menuItemExists = MenuItems.findOne({ itemName: menuItem });
const mie = async() => {
let menuItemExists = await MenuItems.findOneAsync({ itemName: menuItem });
if (!menuItemExists) {
// call to add it
notExists();
} else {
// call to add it to the menu only
console.dir(menuItemExists);
itExists(menuItemExists);
}
}
mie();
if (typeof menuItemExists != 'undefined' && menuItemExists != null && menuItemExists != "") {
const notExists = async() => {
// add the item as new and add to the menu
if (menuItem == null || menuItem == "") {
Session.set("menuItemErr", true);
} else {
const addMenuItem = async() => {
let result = await Meteor.callAsync('add.menuItem', menuItem);
if (!result) {
// console.log(" ERROR adding menu item: " + err);
} else {
// console.log(" SUCCESS adding menu item. Result is: " + result);
return result;
}
}
let addedItem = await addMenuItem();
if (!addedItem) {
// console.log("Item was not added.");
} else {
// now add this item to the menu
// console.log("Added Item = " + addedItem);
const addToMenu = async() => {
let result2 = await Meteor.callAsync('addto.Menu', menuId, menuItem, addedItem, dateSrv, false);
if (!result2) {
// console.log(" ERROR adding menuitem to menu: " + error);
} else {
$("#menuItemInp").val("");
$("#dateServed").val("");
// console.log("Added item to menu - no problem.");
}
}
addToMenu();
}
}
}
const itExists = async(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);
const addToMenu = async() => {
let result = await Meteor.callAsync('addto.Menu', menuId, menuItem, menuItemId, dateSrv, isLinked);
if (!result) {
// console.log(" ERROR adding menuitem to menu: " + error);
} else {
// console.log("Added item to menu - no problem.");
$("#menuItemInp").val("");
$("#dateServed").val("");
}
});
}
} else {
// add the item as new and add to the menu
if (menuItem == null || menuItem == "") {
Session.set("menuItemErr", true);
} else {
Meteor.call('add.menuItem', menuItem, function(err, result) {
if (err) {
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.");
}
});
}
});
}
addToMenu();
}
}
},
@ -110,20 +152,25 @@ Template.menuItemsForm.events({
let menuItemId = menuInfo[i]._id;
let momentAddDay = moment(menuInfo[i].serveDate).add(1, 'day').format("MMM DD, YYYY");
// console.log(momentAddDay);
Meteor.call('shiftDate', menuItemId, momentAddDay, function(err,result) {
if (err) {
console.log(" ERROR shifting meal days: " + err);
const shiftDay = async() => {
let result = await Meteor.callAsync('shiftDate', menuItemId, momentAddDay);
if (!result) {
// console.log(" ERROR shifting meal days: " + err);
} else {
// console.log(" SUCCESS shifting meal date.");
showSnackbar("Items Shifted Out by 1 Calendar Day", "green");
}
});
}
}
},
'keyup #menuItemInp' (event) {
if (event.which != 13) {
let findMenuItem = $("#menuItemInp").val();
let menuItemInfo = MenuItems.find({ itemName: {$regex: findMenuItem + '.*', $options: 'i' }}).fetch();
if (typeof menuItemInfo != 'undefined' && menuItemInfo != '' && menuItemInfo != null) {
if (!menuItemInfo) {
console.log("Nothing found in menu items:");
console.dir(menuItemInfo);
} else {
console.dir(menuItemInfo)
getMenuItemList(menuItemInfo);
}
}

View file

@ -25,15 +25,14 @@
{{#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>
<i class="material-icons tooltipped modal-trigger deleteMenuItem clickable" href="#modalDelete" data-position="top" data-tooltip-id="deleteMenuTip">delete</i>
<i class="material-icons tooltipped modal-trigger linkToProducts clickable" href="#modalLinkProducts" data-position="top" data-tooltip-id="linkMenuTip">link</i>
<i class="material-icons modal-trigger deleteMenuItem clickable" href="#modalDelete">delete</i>
<i class="material-icons modal-trigger linkToProducts clickable" href="#modalLinkProducts">link</i>
<i class="material-icons modal-trigger clickable">arrow_forward</i>
</td>
</tr>
{{/each}}
{{/each}}
</table>
<div class="tooltip-content" style="display: none;" id="deleteMenuTip">Delete this menu item</div>
<div class="tooltip-content" style="display: none;" id="linkMenuTip">Link Products that make up this menu item</div>
</div>
</div>
{{> deleteConfirmationModal}}

View file

@ -30,11 +30,21 @@ Template.menuItemsTbl.helpers({
if (Session.get("menuId")) {
menuId = Session.get("menuId");
} else {
menuId = UserLast.findOne({ view: "Menu" }).viewId;
const menu = async() => {
let menId = await UserLast.findOneAsync({ view: "Menu" }).viewId;
if (!menId) {
} else {
return menId;
}
}
menuId = menu();
}
let menuInfo = Menus.find({ _id: menuId }, { sort: { serveDateActual: 1 }});
if (menuInfo) {
return menuInfo
if (menuId) {
let menuInfo = Menus.find({ _id: menuId }, { sort: { serveDateActual: 1 }});
if (menuInfo) {
return menuInfo;
}
}
}
});
@ -43,7 +53,7 @@ Template.menuItemsTbl.events({
'click .deleteMenuItem' (event) {
event.preventDefault();
let theseIds = Session.get("menuId") + "_" + this.menuItemId;
console.log("These Ids: " + theseIds);
// console.log("These Ids: " + theseIds);
Session.set("deleteId", theseIds);
Session.set("method", "delete.itemFromMenu");
Session.set("item", this.menuItemName);
@ -53,7 +63,7 @@ Template.menuItemsTbl.events({
event.preventDefault();
Session.set("menuItemId", this.menuItemId);
Session.set("menuItemName", this.menuItemName);
console.log("menu item name = " + this.menuItemName);
// console.log("menu item name = " + this.menuItemName);
},
'click .addProdsToList' (event) {
event.preventDefault();

View file

@ -20,4 +20,5 @@
</div>
</div>
</form>
{{> snackbar}}
</template>

View file

@ -18,17 +18,29 @@ Template.modalLinkProducts.onRendered(function() {
dropdownOptions: 4,
});
setTimeout(function() {
var instances = M.Modal.init(elems, {});
var instancese = M.FormSelect.init(elemse, {
dropdownOptions: 4,
});
}, 250);
this.autorun(() => {
if (this.subscriptionsReady()) {
// setTimeout(function() {
// var instances = M.Modal.init(elems, {});
var elemse = document.querySelectorAll('select');
var instancese = M.FormSelect.init(elemse, {
dropdownOptions: 4,
});
// }, 250);
}
});
});
Template.modalLinkProducts.helpers({
products: function() {
return Products.find({});
let prodInfo = Products.find({}, { sort: { prodName:1 }});
// return Products.find({}, {sort: { prodName:1 }});
if (!prodInfo) {
console.log("no product info yet.");
} else {
console.log("prod info found.");
return prodInfo;
}
}
});
@ -42,7 +54,7 @@ Template.modalLinkProducts.events({
let links = M.FormSelect.getInstance(linkSelect).getSelectedValues();
if (typeof links != undefined && links != [] && links != null) {
// let's split these links into their parts, and make an array of objects
for (i=0; i<links.length; i++) {
for (let i=0; i<links.length; i++) {
let linkArray = links[i].split('|');
let key = linkArray[0];
let value = linkArray[1];
@ -50,25 +62,33 @@ Template.modalLinkProducts.events({
linkObjArray.push(linkObj);
}
Meteor.call("add.menuProdLinks", menuItemId, menuItemName, linkObjArray, function(err, result) {
if (err) {
console.log(" ERROR adding product links to this menu item: " + err);
const addMenuProdLinks = async() => {
let result = await Meteor.callAsync("add.menuProdLinks", menuItemId, menuItemName, linkObjArray);
if (!result) {
// console.log(" ERROR adding product links to this menu item: " + err);
} else {
Meteor.call('update.menuItemLinked', menuItemId, true, function(err, result) {
if (err) {
console.log(" ERROR adding link to menu item: " + err);
} else {
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");
}
});
}
});
updMenuItemLinks();
}
});
}
addMenuProdLinks();
const updMenuItemLinks = async() => {
let result = await Meteor.callAsync('update.menuItemLinked', menuItemId, true);
if (!result) {
// console.log(" ERROR adding link to menu item: " + err);
} else {
linkInMenu();
}
}
const linkInMenu = async() => {
let result = await Meteor.callAsync('link.inMenu', menuItemId, true);
if (!result) {
console.log(" ERROR adding link to menu sub-item: " + error);
} else {
showSnackbar("Products added to Menu Item successfully!", "green");
}
}
}
}
});
});

View file

@ -27,14 +27,16 @@ Template.addMenuModal.events({
if (menuName == "" || menuName == null) {
Session.set("menuNameErr", true);
} else {
Meteor.call("add.menu", menuName, function(err, result) {
if (err) {
console.log(" ERROR adding menu: " + err);
const addMenu = async() => {
let result = await Meteor.callAsync("add.menu", menuName);
if (!result) {
// console.log(" ERROR adding menu: " + err);
} else {
console.log(" SUCCESS adding menu.");
// console.log(" SUCCESS adding menu.");
$("#menuNameInp").val("");
}
});
}
addMenu();
}
},
});

View file

@ -1,5 +1,6 @@
import { Menus } from '../../imports/api/menu.js';
import { M } from '../lib/assets/materialize.js';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
Template.mainMenuTbl.onCreated(function() {
this.subscribe("myMenus");
@ -21,7 +22,7 @@ Template.mainMenuTbl.events({
'click li.collection-item' (event) {
event.preventDefault();
let sender = event.target;
// console.log("Sender origination from: ");
// console.log("Sender originated from: ");
// console.log(sender.localName);
if (sender.localName == "li") {
let menuId = event.currentTarget.id;
@ -29,33 +30,38 @@ Template.mainMenuTbl.events({
// console.log("add menu clicked");
} else {
// 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);
const addUserLast = async() => {
Session.set("menuId", menuId);
let result = await Meteor.callAsync('add.userLast', "Menu", menuId);
if (!result) {
// console.log(" ERROR writing last menu viewed by user to db.");
} else {
Session.set("menuId", menuId);
Meteor.setTimeout(function() {
FlowRouter.go('/menuitems');
}, 100);
FlowRouter.go('/menuitems');
}
});
}
addUserLast();
}
} else if (sender.localName == "i") {
let menuId = this._id;
Meteor.call("markMenu.complete", menuId, function(err, result) {
if (err) {
console.log(" ERROR: can't mark menu complete: " + err);
const makrMenuComp = async() => {
let result = await Meteor.callAsync("markMenu.complete", menuId);
if (!result) {
// console.log(" ERROR: can't mark menu complete.");
} else {
console.log(" SUCCESS marking menu complete.");
Meteor.call('setAllMade.menuItem', menuId, function(err, result) {
if (err) {
console.log(" ERROR: cannot set all items as made: " + err);
} else {
console.log(" SUCCESS setting all items made.");
}
});
// console.log(" SUCCESS marking menu complete.");
setAllMade();
}
});
}
makrMenuComp();
const setAllMade = async() => {
let result = await Meteor.callAsync('setAllMade.menuItem', menuId);
if (!result) {
// console.log(" ERROR: cannot set all items as made.");
} else {
// console.log(" SUCCESS setting all items made.");
}
}
}
},
});

View file

@ -33,34 +33,26 @@ Template.myTasksForm.events({
let taskDateArray = Session.get("taskDateArr");
let actDate = [];
console.dir(taskNameArray);
console.dir(taskDateArray);
if (taskNameArray == null || taskNameArray == [] || taskNameArray == "") {
taskNameErr = true;
}
if (taskDateArray == null || taskDateArray == []|| taskDateArray == "") {
taskDateErr = true;
} else {
for (i = 0; i < taskDateArray.length; i++) {
// console.log(taskDateArray[i]);
let actDateTask = new Date(taskDateArray[i]);
actDate.push(actDateTask);
}
}
console.log("Date Error: " + taskDateErr + " - Name Error: " + taskNameErr);
// console.log("Date Error: " + taskDateErr + " - Name Error: " + taskNameErr);
if (taskDateErr == false && taskNameErr == false) {
Meteor.call("add.task", taskNameArray, "self", "selfId", taskDateArray, actDate, function(err, result) {
if (err) {
console.log(" ERROR adding task for self: " + err);
showSnackbar("ERROR adding task for self!", "red");
} else {
console.log(" SUCCESS adding task for self.");
Session.set("taskDateArr", []);
$("#myTaskName").val("");
$("#myTaskDate").val("");
showSnackbar("Added Tasks Successfully!", "green");
for (const task of taskNameArray) {
for (const date of taskDateArray) {
let actDate = new Date(date);
addTask(task.id, date, actDate);
}
});
}
} else {
showSnackbar("Error! Both Task & Date are Required!", "red");
}
@ -91,4 +83,18 @@ Template.myTasksForm.events({
taskDateArr.push(taskDate);
Session.set("taskDateArr", taskDateArr);
},
});
});
const addTask = async(task, date, actDate) => {
let result = await Meteor.callAsync("add.myTask", task, date, actDate);
if (!result) {
// console.log(" ERROR adding task for self: ");
showSnackbar("Error adding task for self!", "red");
} else {
// console.log(" SUCCESS adding task for self.");
// Session.set("taskDateArr", []);
// $("#myTaskName").val("");
// $("#myTaskDate").val("");
showSnackbar("Added Tasks Successfully!", "green");
}
}

View file

@ -55,19 +55,19 @@ Template.myTasksTbl.events({
'click .markMyTaskComplete' (event) {
event.preventDefault();
let taskId = this._id;
Meteor.call("markTask.complete", taskId, function(err, result) {
if (err) {
console.log(" ERROR marking task completeL " + err);
const makrTaskComp = async() => {
let result = await Meteor.callAsync("markTask.complete", taskId);
if (!result) {
// console.log(" ERROR marking task completeL " + err);
showSnackbar("ERROR Marking Task Complete!", "red");
} else {
showSnackbar("Successfully Marked Task Complete!", "green");
}
});
}
},
'click .deleteMyTask' (event) {
event.preventDefault();
console.log("detected click");
// console.log("detected click");
Session.set("deleteId", this._id);
Session.set("method", "delete.task");
Session.set("item", this.taskName);

View file

@ -5,15 +5,29 @@ Template.userConfig.onCreated(function() {
});
Template.userConfig.onRendered(function() {
let myConfig = UserConfig.findOne({ user: Meteor.userId() });
if (typeof myConfig != 'undefined') {
console.log("My Pref: " + myConfig.darkPref);
if (myConfig.darkMode == 'light') {
$("#darkMode").prop('checked', false);
} else {
$("#darkMode").prop('checked', true);
const getConfig = async() => {
// console.log("tried to get switch config.")
let myConfig = await UserConfig.findOneAsync({ user: Meteor.userId() });
try {
// console.dir(myConfig);
if (!myConfig) {
// console.log("config not found, setting to light mode.");
$("#darkMode").prop('checked', false);
} else {
// console.log("My Pref: " + myConfig.darkMode);
if (myConfig.darkMode == 'light') {
$("#darkMode").prop('checked', false);
} else {
// console.log("should be checked.")
$("#darkMode").prop('checked', true);
}
}
} catch(error) {
console.log(" ERROR getting dark theme for setting swtich: " + error);
}
}
getConfig();
});
Template.userConfig.helpers({
@ -22,23 +36,22 @@ Template.userConfig.helpers({
Template.userConfig.events({
'click #darkMode' (event) {
let darkModePref = $("#darkMode").prop('checked');
let darkModePref = $("#darkMode").prop('checked')
if (darkModePref == true) {
Meteor.call('update.darkModePref', 'dark', function(err, reuslt) {
if (err) {
console.log(" ERROR: could not set dark mode preference to dark: " + err);
} else {
showSnackbar("Dark Mode Preference Set to Dark", "green");
}
});
let mode = 'dark';
setDarkMode(mode);
} else {
Meteor.call('update.darkModePref', 'light', function(err, result) {
if (err) {
console.log(" ERROR: could not set dark mode preference to light: " + err);
} else {
showSnackbar("Dark Mode Preference Set to Light", "green");
}
});
let mode = 'light';
setDarkMode(mode);
}
},
});
});
const setDarkMode = async(mode) => {
let result = await Meteor.callAsync('update.darkModePref', mode);
if (!result) {
// console.log(" - Did not receive back a 'result' from the update.");
} else {
showSnackbar("Dark Mode Preference Set to " + mode, "green");
}
}

View file

@ -14,7 +14,7 @@ ListItems.allow({
});
Meteor.methods({
'add.listItem' (itemName, listId) {
async 'add.listItem' (itemName, listId) {
check(itemName, String);
check(listId, String);
@ -22,18 +22,24 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add items. Make sure you are logged in with valid user credentials.');
}
let iname = itemName.charAt(0).toUpperCase() + itemName.slice(1);
// look up the item from the Products collection
let prodInfo = Products.findOne({ prodName: itemName });
if (typeof prodInfo == "undefined") {
Meteor.call("add.product", itemName, "", "", "", function(err, result) {
if (err) {
console.log(" ERROR adding item to products: " + err);
let prodInfo = await Products.findOneAsync({ prodName: iname });
try {
if (!prodInfo) {
// add product info first
let added = await Meteor.callAsync("add.product", itemName, [""]);
if (!added) {
// console.log(" ERROR adding item to products: " + err);
} else {
// console.log(" SUCCESS adding item to Products.");
return ListItems.insert({
itemName: itemName,
return await ListItems.insertAsync({
itemName: iname,
listId: listId,
prodId: result,
prodId: added,
addedBy: this.userId,
itemStore: "",
itemOrdered: false,
@ -41,39 +47,9 @@ Meteor.methods({
dateAddedToList: new Date(),
});
}
});
} else {
return ListItems.insert({
itemName: itemName,
listId: listId,
prodId: prodInfo._id,
addedBy: this.userId,
itemStore: prodInfo.prodStore,
itemOrdered: false,
itemReceived: false,
dateAddedToList: new Date(),
});
}
},
'add.itemsFromMenuItem' (itemIds, listId) {
check(itemIds, [String]);
check(listId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add items from a menu. Make sure you are logged in with valid user credentials.');
}
console.dir(itemIds);
for (i=0; i < itemIds.length; i++) {
// let's check and make sure the product isn't already on the list
let onList = ListItems.find({ listId: listId, prodId: itemIds[i] }).count();
console.log("Number On List: " + onList);
if (onList == 0) {
// now pull the product
let prodInfo = Products.findOne({ _id: itemIds[i] });
ListItems.insert({
itemName: prodInfo.prodName,
} else {
return await ListItems.insertAsync({
itemName: iname,
listId: listId,
prodId: prodInfo._id,
addedBy: this.userId,
@ -82,52 +58,95 @@ Meteor.methods({
itemReceived: false,
dateAddedToList: new Date(),
});
}
} catch(error) {
console.log(" ERROR adding new product and item: " + error);
}
},
async 'add.itemsFromMenuItem' (itemIds, listId) {
check(itemIds, [String]);
check(listId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add items from a menu. Make sure you are logged in with valid user credentials.');
}
console.dir(itemIds);
let noitems = itemIds.length;
let i;
for (i=0; i < noitems; i++) {
// let's check and make sure the product isn't already on the list
let onList = await ListItems.find({ listId: listId, prodId: itemIds[i] }).countAsync();
// console.log("Number On List: " + onList);
if (onList == 0) {
// now pull the product
let prodInfo = await Products.findOneAsync({ _id: itemIds[i] });
if (!prodInfo) {
console.log("Unable to load product info.");
} else {
console.log("Run " + i);
ListItems.insertAsync({
itemName: prodInfo.prodName,
listId: listId,
prodId: prodInfo._id,
addedBy: this.userId,
itemStore: prodInfo.prodStore,
itemOrdered: false,
itemReceived: false,
dateAddedToList: new Date(),
});
}
} else {
// product exists on list, move on to next
console.log("Product Exists on Selected List.");
}
if (i == (noitems - 1)) {
console.log("Returning now.");
return true;
}
}
},
'setOrdered.listItem' (itemId) {
async 'setOrdered.listItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as ordered. Make sure you are logged in with valid user credentials.');
}
return ListItems.update({ _id: itemId }, {
return await ListItems.updateAsync({ _id: itemId }, {
$set: {
itemOrdered: true,
dateOrdered: new Date(),
}
});
},
'setAllOrdered.listItem' (shopListId) {
async 'setAllOrdered.listItem' (shopListId) {
// set all items that are not already set as ordered, or set as received to ordered on this list
},
'setNotOrdered.listItem' (itemId) {
async 'setNotOrdered.listItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as not ordered. Make sure you are logged in with valid user credentials.');
}
return ListItems.update({ _id: itemId }, {
return await ListItems.updateAsync({ _id: itemId }, {
$set: {
itemOrdered: false,
dateUnOrdered: new Date(),
}
});
},
'setReceived.listItem' (itemId) {
async 'setReceived.listItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as received. Make sure you are logged in with valid user credentials.');
}
return ListItems.update({ _id: itemId }, {
return await ListItems.updateAsync({ _id: itemId }, {
$set: {
itemReceived: true,
dateReceived: new Date(),
@ -135,25 +154,25 @@ Meteor.methods({
});
},
'setNotReceived.listItem' (shopListId) {
async 'setNotReceived.listItem' (shopListId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to set items as not received. Make sure you are logged in with valid user credentials.');
}
return ListItems.update({ _id: itemId }, {
return await ListItems.updateAsync({ _id: itemId }, {
$set: {
itemReceived: false,
dateNotReceived: new Date(),
}
});
},
'setAllReceived.listItem' () {
async 'setAllReceived.listItem' () {
// set all items that are not already listed as received to received on this list
},
'edit.listItem' (itemId, itemName) {
async 'edit.listItem' (itemId, itemName) {
check(itemId, String);
check(itemName, String);
@ -161,19 +180,19 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add items. Make sure you are logged in with valid user credentials.');
}
return ListItems.update({ _id: itemId }, {
return await ListItems.updateAsync({ _id: itemId }, {
$set: {
itemName: itemName,
}
});
},
'delete.listItem' (itemId) {
async 'delete.listItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete list items. Make sure you are logged in with valid user credentials.');
}
return ListItems.remove({ _id: itemId });
return await ListItems.removeAsync({ _id: itemId });
}
});
});

View file

@ -12,7 +12,7 @@ Lists.allow({
});
Meteor.methods({
'add.list' (listName, isShared) {
async 'add.list' (listName, isShared) {
check(listName, String);
check(isShared, Boolean);
@ -20,14 +20,14 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add lists. Make sure you are logged in with valid user credentials.');
}
return Lists.insert({
return await Lists.insertAsync({
listName: listName,
listShared: isShared,
listOwner: this.userId,
listComplete: false,
});
},
'edit.list' (listId, listName, isShared) {
async 'edit.list' (listId, listName, isShared) {
check(listId, String);
check(listName, String);
check(isShared, Boolean);
@ -36,41 +36,55 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit lists. Make sure you are logged in with valid user credentials.');
}
return Lists.update({ _id: listId }, {
return await Lists.updateAsync({ _id: listId }, {
$set: {
listName: listName,
listShared: isShared,
}
});
},
'delete.list' (listId) {
async 'delete.list' (listId) {
check(listId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete lists. Make sure you are logged in with valid user credentials.');
}
return Lists.remove({ _id: listId });
return await Lists.removeAsync({ _id: listId });
},
'mark.complete' (listId) {
async 'mark.complete' (listId) {
check(listId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark lists complete. Make sure you are logged in with valid user credentials.');
}
return Lists.update({ _id: listId }, {
return await Lists.updateAsync({ _id: listId }, {
$set: {
listComplete: true,
completedOn: new Date()
}
});;
});
},
'clean.Lists' () {
async 'mark.incomplete' (listId) {
check(listId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to restore completed lists. Make sure you are logged in with valid user credentials.');
}
return await Lists.updateAsync({ _id: listId }, {
$set: {
listComplete: false,
completedOn: new Date()
}
});
},
async '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 });
return await Lists.removeAsync({ listComplete: true });
},
});

24
imports/api/mScripts.js Normal file
View file

@ -0,0 +1,24 @@
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
export const MScripts = new Mongo.Collection('mScripts');
MScripts.allow({
insert: function(userId, doc){
// if use id exists, allow insert
return !!userId;
},
});
Meteor.methods({
async 'set.ScriptRun' (scriptName) {
check(scriptName, String);
return await MScripts.insertAsync({
scriptName: scriptName,
hasRun: true,
runOn: new Date(),
});
},
});

View file

@ -15,20 +15,20 @@ Menus.allow({
});
Meteor.methods({
'add.menu' (menuName) {
async 'add.menu' (menuName) {
check(menuName, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add menus. Make sure you are logged in with valid user credentials.');
}
return Menus.insert({
return await Menus.insertAsync({
menuName: menuName,
menuOwner: this.userId,
menuComplete: false,
});
},
'edit.menu' (menuId, menuName) {
async 'edit.menu' (menuId, menuName) {
check(menuId, String);
check(menuName, String);
@ -36,88 +36,55 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit menus. Make sure you are logged in with valid user credentials.');
}
return Menus.update({ _id: menuId }, {
return await Menus.updateAsync({ _id: menuId }, {
$set: {
menuName: menuName,
}
});
},
'delete.menu' (menuId) {
async 'delete.menu' (menuId) {
check(menuId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete menus. Make sure you are logged in with valid user credentials.');
}
return Menus.remove({ _id: menuId });
return await Menus.removeAsync({ _id: menuId });
},
'markMenu.complete' (menuId) {
async 'markMenu.complete' (menuId) {
check(menuId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark menus complete. Make sure you are logged in with valid user credentials.');
}
return Menus.update({ _id: menuId }, {
return await Menus.updateAsync({ _id: menuId }, {
$set: {
menuComplete: true,
}
});
},
'markMenu.notComplete' (menuId) {
async 'markMenu.notComplete' (menuId) {
check(menuId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark menus not complete. Make sure you are logged in with valid user credentials.');
}
return Menus.update({ _id: menuId }, {
return await Menus.updateAsync({ _id: menuId }, {
$set: {
menuComplete: false,
}
});
},
'clean.Menus' () {
async '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);
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();
for (k = 0; k < markedComplete.length; k++) {
let menuId = markedComplete[k]._id;
removeMenuIds.push(menuId);
}
// finally we'll cycle through the ids and remove the items we collected up.
for (l = 0; l < removeMenuIds.length; l++) {
Menus.remove({ _id: removeMenuIds[l] });
}
return await Menus.removeAsync({ menuComplete: true });
},
'addto.Menu' (menuId, menuItem, menuItemId, dateSrv, isLinked) {
async 'addto.Menu' (menuId, menuItem, menuItemId, dateSrv, isLinked) {
check(menuId, String);
check(menuItem, String);
check(menuItemId, String);
@ -128,9 +95,9 @@ Meteor.methods({
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);
let serveDateActual = new Date(dateSrv);
return Menus.update({ _id: menuId }, {
return await Menus.updateAsync({ _id: menuId }, {
$addToSet: {
menuItems:
{
@ -143,7 +110,7 @@ Meteor.methods({
}
});
},
'link.inMenu' (menuItemId, isLinked) {
async 'link.inMenu' (menuItemId, isLinked) {
check(menuItemId, String);
check(isLinked, Boolean);
@ -151,13 +118,13 @@ Meteor.methods({
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 }, {
return await Menus.updateAsync({ 'menuItems.menuItemId': menuItemId }, {
$set: {
"menuItems.$.isLinked": isLinked
}
});
},
'delete.itemFromMenu' (itemIds) {
async 'delete.itemFromMenu' (itemIds) {
check(itemIds, String);
if (!this.userId) {
@ -165,9 +132,9 @@ Meteor.methods({
}
let ids = itemIds.split('_');
console.log("item ids: " + ids[0] + " and " + ids[1]);
// console.log("item ids: " + ids[0] + " and " + ids[1]);
return Menus.update({ _id: ids[0] }, {
return await Menus.updateAsync({ _id: ids[0] }, {
$pull: {
menuItems: {
menuItemId: ids[1],

View file

@ -12,23 +12,21 @@ MenuItems.allow({
});
Meteor.methods({
'add.menuItem' (itemName) {
async 'add.menuItem' (itemName) {
check(itemName, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add items. Make sure you are logged in with valid user credentials.');
}
serveDateActual = new Date(serveDate);
return MenuItems.insert({
return await MenuItems.insertAsync({
itemName: itemName,
addedBy: this.userId,
dateAddedtoMenu: new Date(),
isLinked: false,
});
},
'update.menuItemLinked' (itemId, isLinked) {
async 'update.menuItemLinked' (itemId, isLinked) {
check(itemId, String);
check(isLinked, Boolean);
@ -36,38 +34,36 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to set this menu item as linked to products. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ _id: itemId }, {
return await MenuItems.updateAsync({ _id: itemId }, {
$set: {
isLinked: isLinked,
}
});
},
'edit.madeItem' (itemId, itemName, serveDate) {
async 'edit.madeItem' (itemId, itemName) {
check(itemId, String);
check(itemName, String);
check(serveDate, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to edit menu items. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ _id: itemId }, {
return await MenuItems.updateAsync({ _id: itemId }, {
$set: {
itemName: itemName,
serveDate: serveDate,
}
});
},
'delete.menuItem' (itemId) {
async 'delete.menuItem' (itemId) {
check(itemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete menu items. Make sure you are logged in with valid user credentials.');
}
return MenuItems.remove({ _id: itemId });
return await MenuItems.removeAsync({ _id: itemId });
},
'shiftDate' (itemId, momentAddDay) {
async 'shiftDate' (itemId, momentAddDay) {
check(itemId, String);
check(momentAddDay, String);
@ -75,7 +71,7 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to shift menu item dates. Make sure you are logged in with valid user credentials.');
}
return MenuItems.update({ _id: itemId }, {
return await MenuItems.updateAsync({ _id: itemId }, {
$set: {
serveDate: momentAddDay,
}

View file

@ -13,7 +13,7 @@ MenuProdLinks.allow({
});
Meteor.methods({
'add.menuProdLinks' (menuItemId, menuItemName, prodNameArray) {
async 'add.menuProdLinks' (menuItemId, menuItemName, prodNameArray) {
check(menuItemId, String);
check(menuItemName, String);
check(prodNameArray, [Object]);
@ -22,12 +22,43 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add menu and product links. Make sure you are logged in with valid user credentials.');
};
MenuProdLinks.insert({
menuItemId: menuItemId,
menuItemName: menuItemName,
products: prodNameArray,
dateCreated: Date(),
createdBy: this.userId
let linkExists = await MenuProdLinks.findOneAsync({ menuItemId: menuItemId });
if (linkExists) {
// console.log("sending to update method instead.");
await Meteor.callAsync('update.menuPordLInks', menuItemId, menuItemName, prodNameArray, function(err, result) {
if (err) {
// console.log(" ERROR moving to the update method: " + err);
} else {
// console.log("Successfully updated the menu prod links.")
}
});
} else {
return await MenuProdLinks.insertAsync({
menuItemId: menuItemId,
menuItemName: menuItemName,
products: prodNameArray,
dateCreated: Date(),
createdBy: this.userId
});
}
},
async 'update.menuPordLInks' (menuItemId, menuItemName, prodNameArray) {
check(menuItemId, String);
check(menuItemName, String);
check(prodNameArray, [Object]);
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.');
};
console.log(" ---- Doing an Update instead! ---- ");
return await MenuProdLinks.updateAsync({ menuItemId: menuItemId }, {
$set: {
products: prodNameArray,
dateUpdated: Date(),
updatedBy: this.userId
}
});
}
},
});

View file

@ -12,7 +12,7 @@ Products.allow({
});
Meteor.methods({
'add.product' (prodName, prodStore) {
async 'add.product' (prodName, prodStore) {
check(prodName, String);
check(prodStore, [String]);
@ -20,13 +20,24 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add products. Make sure you are logged in with valid user credentials.');
}
return Products.insert({
prodName: prodName,
prodOwner: this.userId,
prodStore: prodStore,
});
let pname = prodName.charAt(0).toUpperCase() + prodName.slice(1);
// first does this product already exist?
let prodExists = await Products.findOneAsync({ prodName: pname });
try {
if (!prodExists) {
return await Products.insertAsync({
prodName: pname,
prodOwner: this.userId,
prodStore: prodStore,
});
}
} catch(error) {
console.log(" ERROR adding Pdocut: " + error);
}
},
'edit.product' (prodId, prodName, prodStore) {
async 'edit.product' (prodId, prodName, prodStore) {
check(prodId, String);
check(prodName, String);
check(prodStore, [String]);
@ -35,20 +46,32 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit products. Make sure you are logged in with valid user credentials.');
}
return Products.update({ _id: prodId }, {
let pname = prodName.charAt(0).toUpperCase() + prodName.slice(1);
return await Products.updateAsync({ _id: prodId }, {
$set: {
prodName: prodName,
prodName: pname,
prodStore: prodStore,
}
});
},
'delete.product' (prodId) {
async 'delete.product' (prodId) {
check(prodId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete products. Make sure you are logged in with valid user credentials.');
}
return Products.remove({ _id: prodId });
return await Products.removeAsync({ _id: prodId });
},
async 'clean.Products' () {
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete products. Make sure you are logged in with valid user credentials.');
}
// first we need to find potential duplicate products
// next we need to see which of those are on incomplete lists
// Then we'll update those to use the main products ID instead
// finally we'll delete the duplicates
}
});

View file

@ -12,7 +12,7 @@ RecipeItems.allow({
});
Meteor.methods({
'add.recipeItem' (recipeId, recipeItemType, recipeItem) {
async 'add.recipeItem' (recipeId, recipeItemType, recipeItem) {
check(recipeId, String);
check(recipeItemType, String);
check(recipeItem, String);
@ -21,13 +21,13 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add recipe items. Make sure you are logged in with valid user credentials.');
}
return RecipeItems.insert({
return await RecipeItems.insertAsync({
recipeId: recipeId,
recipeItemType: recipeItemType,
recipeItem: recipeItem,
});
},
'edit.recipeItem' (recipeItemId, recipeId, recipeItemType, recipeItem) {
async 'edit.recipeItem' (recipeItemId, recipeId, recipeItemType, recipeItem) {
check(recipeItemId, String);
check(recipeId, String);
check(recipeItemType, String);
@ -37,7 +37,7 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit recipe items. Make sure you are logged in with valid user credentials.');
}
return RecipeItems.update({ _id: recipeItemId }, {
return await RecipeItems.updateAsync({ _id: recipeItemId }, {
$set: {
recipeId: recipeId,
recipeItemType: recipeItemType,
@ -45,13 +45,13 @@ Meteor.methods({
}
});
},
'delete.recipeItem' (recipeItemId) {
async 'delete.recipeItem' (recipeItemId) {
check(recipeItemId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete recipe items. Make sure you are logged in with valid user credentials.');
}
return RecipeItems.remove({ _id: recipeItemId });
return await RecipeItems.removeAsync({ _id: recipeItemId });
}
});

View file

@ -12,20 +12,20 @@ Recipes.allow({
});
Meteor.methods({
'add.recipe' (recipeName) {
async 'add.recipe' (recipeName) {
check(recipeName, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add recipes. Make sure you are logged in with valid user credentials.');
}
return Recipes.insert({
return await Recipes.insertAsync({
recipeName: recipeName,
addedBy: this.userId,
addedOn: new Date(),
});
},
'edit.recipe' (recipeId, recipeName) {
async 'edit.recipe' (recipeId, recipeName) {
check(recipeId, String);
check(recipeName, String);
@ -33,7 +33,7 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add recipes. Make sure you are logged in with valid user credentials.');
}
return Recipes.update({ _id: recipeId }, {
return await Recipes.updateAsync({ _id: recipeId }, {
$set: {
recipeName: recipeName,
updatedOn: new Date(),
@ -41,13 +41,13 @@ Meteor.methods({
}
});
},
'delete.recipe' (recipeId) {
async 'delete.recipe' (recipeId) {
check(recipeId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete recipes. Make sure you are logged in with valid user credentials.');
}
return Recipes.remove({ _id: recipeId });
return await Recipes.removeAsync({ _id: recipeId });
}
});

View file

@ -12,19 +12,19 @@ ShopLists.allow({
});
Meteor.methods({
'add.shopList' (shopName) {
async 'add.shopList' (shopName) {
check(shopName, Sring);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add shopping lists. Make sure you are logged in with valid user credentials.');
}
return ShopLists.insert({
return await ShopLists.insert({
shopName: shopName,
shopOwner: this.userId,
});
},
'edit.shopList' (shopId, shopName) {
async 'edit.shopList' (shopId, shopName) {
check(shopId, String);
check(shopName, String);
@ -32,19 +32,19 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit shopping lists. Make sure you are logged in with valid user credentials.');
}
return ShopLists.update({ _id: shopId }, {
return await ShopLists.update({ _id: shopId }, {
$set: {
shopName: shopName,
}
});
},
'delete.shopList' (shopId) {
async 'delete.shopList' (shopId) {
check(shopId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete shopping lists. Make sure you are logged in with valid user credentials.');
}
return ShopLists.remove({ _id: shopId });
return await ShopLists.remove({ _id: shopId });
},
});

View file

@ -12,19 +12,19 @@ Stores.allow({
});
Meteor.methods({
'add.store' (storeName) {
async 'add.store' (storeName) {
check(storeName, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add stores. Make sure you are logged in with valid user credentials.');
}
return Stores.insert({
return await Stores.insertAsync({
storeName: storeName,
owner: this.userId,
});
},
'edit.store' (storeId, storeName) {
async 'edit.store' (storeId, storeName) {
check(storeId, String);
check(storeName, String);
@ -32,19 +32,19 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit stores. Make sure you are logged in with valid user credentials.');
}
return Stores.update({ _id: storeId }, {
return await Stores.updateAsync({ _id: storeId }, {
$set: {
storeName: storeName,
}
});
},
'delete.store' (storeId) {
async 'delete.store' (storeId) {
check(storeId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete stores. Make sure you are logged in with valid user credentials.');
}
return Stores.remove({ _id: storeId });
return await Stores.removeAsync({ _id: storeId });
},
});

View file

@ -12,7 +12,7 @@ SysConfig.allow({
});
Meteor.methods({
'add.noSysAdminReg' (admReg, genReg) {
async 'add.noSysAdminReg' (admReg, genReg) {
check(admReg, Boolean);
check(genReg, Boolean);
@ -20,25 +20,39 @@ Meteor.methods({
throw new Meteor.Error('Not able to change registration setting. Make sure you are logged in with valid system administrator credentials.');
}
let curr = SysConfig.findOne({});
if (typeof curr != 'undefined') {
let configId = curr._id;
Meteor.call('edit.noSysAdminReg', configId, admReg, genReg, function(err, result) {
if (err) {
console.log(" ERROR updating sys admin reg: " + err);
} else {
console.log("Success updating sys admin reg.");
}
});
const currConfig = async() => {
let curr = await SysConfig.findOneAsync({});
if (!curr) {
try {
return await SysConfig.insertAsync({
SysAdminReg: admReg,
dateAdded: new Date(),
allowReg: genReg,
});
} catch(error) {
console.log(" ERROR trying to insert system config:");
console.log(error.message);
console.log(error.stack);
}
} else {
return SysConfig.insert({
SysAdminReg: admReg,
dateAdded: new Date(),
allowReg: genReg,
});
try {
let configId = curr._id;
const addNoSys = await Meteor.callAsync('edit.noSysAdminReg', configId, admReg, genReg);
if (!addNoSys) {
// console.log(" Couldn't edit the system config.");
} else {
// console.log("Success updating sys admin reg.");
}
} catch(error) {
console.log(" ERROR trying to pull current system config:");
console.log(error.message);
console.log(error.stack);
}
}
}
currConfig();
},
'edit.noSysAdminReg' (configId, canReg, genReg) {
async 'edit.noSysAdminReg' (configId, canReg, genReg) {
check(canReg, Boolean);
check(configId, String);
check(genReg, Boolean);
@ -47,7 +61,7 @@ Meteor.methods({
throw new Meteor.Error('Not able to change registration setting. Make sure you are logged in with valid system administrator credentials.');
}
return SysConfig.update({ _id: configId }, {
return await SysConfig.updateAsync({ _id: configId }, {
$set: {
SysAdminReg: canReg,
allowReg: genReg,
@ -55,4 +69,21 @@ Meteor.methods({
}
});
},
});
async 'allow.updateInfo' (allowUpdate) {
check(allowUpdate, Boolean);
if (!this.userId) {
throw new Meteor.Error('Not able to change system update notification settings. Make sure you are logged in with valid system administrator credentials.');
}
let curr = SysConfig.findOne({});
let configId = curr._id;
return await SysConfig.updateAsync({ _id: configId }, {
$set: {
allowUpdates: allowUpdate,
}
});
},
});

View file

@ -13,7 +13,7 @@ TaskItems.allow({
});
Meteor.methods({
'add.task' (taskNameArr, assignedTo, assignedToId, taskDateArr, actDate) {
async 'add.task' (taskNameArr, assignedTo, assignedToId, taskDateArr, actDate) {
check(taskNameArr, [Object]);
check(assignedTo, String);
check(taskDateArr, [String]);
@ -23,24 +23,14 @@ Meteor.methods({
if (!this.userId) {
throw new Meteor.Error('You are not allowed to add tasks. Make sure you are logged in with valid user credentials.');
}
let username;
if (assignedTo == "self") {
let userInfo = Meteor.users.findOne({ _id: this.userId });
username = userInfo.profile.fullname;
assignedToId = this.userId;
} else {
username = assignedTo;
}
for (i=0; i < taskDateArr.length; i++) {
for (j=0; j < taskNameArr.length; j++) {
TaskItems.insert({
for (let i=0; i < taskDateArr.length; i++) {
for (let j=0; j < taskNameArr.length; j++) {
await TaskItems.insertAsync({
taskName: taskNameArr[j].id,
taskDate: taskDateArr[i],
actualDate: actDate[i],
assignedTo: username,
assignedTo: assignedTo,
assignedToId: assignedToId,
isComplete: false,
completedOn: null,
@ -50,7 +40,7 @@ Meteor.methods({
}
}
},
'add.mytask' (taskName, assignedTo, assignedToId, taskDate, actDate) {
async 'add.myTask' (taskName, taskDate, actDate) {
check(taskName, String);
check(taskDate, String);
check(actDate, Date);
@ -59,29 +49,28 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to add tasks. Make sure you are logged in with valid user credentials.');
}
let username;
if (assignedTo == "self") {
let userInfo = Meteor.users.findOne({ _id: this.userId });
username = userInfo.profile.fullname;
assignedToId = this.userId;
let userInfo = await Meteor.users.findOneAsync({ _id: this.userId });
if (!userInfo) {
// console.log("No matching user info found.")
} else {
username = assignedTo;
try {
return await TaskItems.insertAsync({
taskName: taskName,
taskDate: taskDate,
actualDate: actDate,
assignedTo: userInfo.profile.fullname,
assignedToId: this.userId,
isComplete: false,
completedOn: null,
assignedOn: new Date(),
assignedBy: this.userId,
});
} catch(error) {
console.log(" ERROR adding tasksL " + error.message);
}
}
return TaskItems.insert({
taskName: taskName,
taskDate: taskDate,
actualDate: actDate,
assignedTo: username,
assignedToId: assignedToId,
isComplete: false,
completedOn: null,
assignedOn: new Date(),
assignedBy: this.userId,
});
},
'edit.task' (taskId, taskName, assignedTo, taskDate) {
async 'edit.task' (taskId, taskName, assignedTo, taskDate) {
check(taskId, String);
check(taskName, String);
check(assignedTo, String);
@ -91,7 +80,7 @@ Meteor.methods({
throw new Meteor.Error('You are not allowed to edit tasks. Make sure you are logged in with valid user credentials.');
}
return TaskItems.update({ _id: taskId }, {
return await TaskItems.updateAsync({ _id: taskId }, {
$set: {
taskName: taskName,
taskDate: taskDate,
@ -101,23 +90,23 @@ Meteor.methods({
}
});
},
'delete.task' (taskId) {
async 'delete.task' (taskId) {
check(taskId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to delete tasks. Make sure you are logged in with valid user credentials.');
}
return TaskItems.remove({ _id: taskId });
return await TaskItems.removeAsync({ _id: taskId });
},
'markTask.complete' (taskId) {
async 'markTask.complete' (taskId) {
check(taskId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark tasks complete. Make sure you are logged in with valid user credentials.');
}
return TaskItems.update({ _id: taskId }, {
return await TaskItems.updateAsync({ _id: taskId }, {
$set: {
isComplete: true,
completedOn: new Date(),
@ -125,14 +114,14 @@ Meteor.methods({
}
});
},
'markTask.notComplete' (taskId) {
async 'markTask.notComplete' (taskId) {
check(taskId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark tasks not complete. Make sure you are logged in with valid user credentials.');
}
return TaskItems.update({ _id: taskId }, {
return await TaskItems.updateAsync({ _id: taskId }, {
$set: {
isComplete: false,
markedUncomplteOn: new Date(),
@ -140,7 +129,7 @@ Meteor.methods({
}
});
},
'clean.Tasks' (timeFrame) {
async 'clean.Tasks' (timeFrame) {
check(timeFrame, String);
if (!this.userId) {
@ -151,29 +140,29 @@ Meteor.methods({
let upToDate = "";
switch(timeFrame) {
case "1-week":
console.log("1 Week");
// console.log("1 Week");
upToDate = 7 * 24 * 60 * 60 * 1000;
break;
case "2-weeks":
console.log("2 Week");
// console.log("2 Week");
upToDate = 14 * 24 * 60 * 60 * 1000;
break;
case '1-month':
console.log("1 month");
// console.log("1 month");
upToDate = 30 * 24 * 60 * 60 * 1000;
break;
case '3-months':
console.log("3 months");
// console.log("3 months");
upToDate = 90 * 24 * 60 * 60 * 1000;
break;
case 'all':
console.log("all");
// console.log("all");
upToDate = 1 * 24 * 60 * 60 * 1000;
break;
default:
break;
}
return TaskItems.remove({ actualDate: { $lt: new Date((new Date()) - upToDate )}});
return await TaskItems.removeAsync({ actualDate: { $lt: new Date((new Date()) - upToDate )}});
}
});

38
imports/api/updateInfo.js Normal file
View file

@ -0,0 +1,38 @@
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
export const UpdateInfo = new Mongo.Collection('updateInfo');
UpdateInfo.allow({
insert: function(userId, doc){
// if use id exists, allow insert
return !!userId;
},
});
Meteor.methods({
async 'add.updateInfo' (updateObject) {
check(updateObject, Object);
return await UpdateInfo.insertAsync({
title: updateObject.title,
description: updateObject.description,
dateRelease: updateObject.date,
releaseLink: updateObject.link
});
},
async 'markUpdate.read' (updateId) {
check(updateId, String);
if (!this.userId) {
throw new Meteor.Error('You are not allowed to mark updates as read. Make sure you are logged in with valid user credentials.');
}
return await UpdateInfo.updateAsync({ _id: updateId }, {
$set: {
viewed: true
}
});
}
});

View file

@ -9,43 +9,38 @@ UserConfig.allow({
// if use id exists, allow insert
return !!userId;
},
update: function(userId, doc){
// if use id exists, allow insert
return !!userId;
},
});
Meteor.methods({
'add.darkModePref' (pref) {
async 'add.darkModePref' (pref) {
check(pref, String);
if (!this.userId) {
throw new Meteor.Error('Not able to change registration setting. Make sure you are logged in with valid system administrator credentials.');
throw new Meteor.Error('Not able to change theme setting. Make sure you are logged in with valid system administrator credentials.');
}
return UserConfig.insert({
return await UserConfig.insertAsync({
user: this.userId,
darkMode: pref,
dateAdded: Date()
});
},
'update.darkModePref' (pref) {
async 'update.darkModePref' (pref) {
check(pref, String);
if (!this.userId) {
throw new Meteor.Error('Not able to change registration setting. Make sure you are logged in with valid system administrator credentials.');
throw new Meteor.Error('Not able to change theme setting. Make sure you are logged in with valid system administrator credentials.');
}
let myConfig = UserConfig.findOne({ user: this.userId });
if (typeof myConfig == 'undefined') {
Meteor.call('add.darkModePref', pref, function(err, result) {
if (err) {
console.log(" ERROR calling the add functioin for dark mode: " + err);
}
});
} else {
return UserConfig.update({ user: this.userId }, {
$set: {
darkMode: pref,
dateUpdate: Date()
}
});
}
return await UserConfig.updateAsync({ user: this.userId }, {
$set: {
darkMode: pref,
dateUpdate: Date()
}
});
}
});

View file

@ -12,10 +12,10 @@ UserConfigOptions.allow({
});
Meteor.methods({
'change.userPass' (usersId, password) {
async 'change.userPass' (usersId, password) {
check(usersId, String);
check(password, String);
return Accounts.setPassword(usersId, password);
return await Accounts.setPasswordAsync(usersId, password);
},
});

View file

@ -12,7 +12,7 @@ UserLast.allow({
});
Meteor.methods({
'add.userLast' (view, viewId) {
async 'add.userLast' (view, viewId) {
check(view, String);
check(viewId, String);
@ -22,24 +22,33 @@ Meteor.methods({
// 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({
let userListInfo = await UserLast.findOneAsync({ userId: this.userId, view: view });
if (!userListInfo) {
// console.log("Adding new user last item.");
return await UserLast.insertAsync({
userId: this.userId,
view: view,
viewId: viewId,
dateAdded: Date(),
});
} else {
// console.log("Editing existing user last itme.");
// entry exists, call the edit function instead
let result = await Meteor.callAsync('edit.userLast', view, viewId);
if (!result) {
try {
// console.log("Issue editing existing entry in userLast. Check the logs.");
} catch(error) {
console.log(" ERROR adding userLast item: " + error);
console.log(error.message);
console.log(error.stack);
}
} else {
return true;
}
}
},
'edit.userLast' (view, viewId) {
async 'edit.userLast' (view, viewId) {
check(view, String);
check(viewId, String);
@ -47,7 +56,8 @@ Meteor.methods({
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 }, {
// console.log("Edit in progress.");
return await UserLast.updateAsync({ view: view, userId: this.userId }, {
$set: {
viewId: viewId,
dateLastUpdate: Date(),

View file

@ -1,132 +1,134 @@
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
FlowRouter.route('/dashboard', {
name: 'home',
action() {
BlazeLayout.render('MainLayout', { main: "dashboard" });
this.render('MainLayout', { main: "dashboard" });
}
});
FlowRouter.route('/', {
name: 'homeNoRoute',
action() {
BlazeLayout.render('MainLayout', { main: "dashboard" });
this.render('MainLayout', { main: "dashboard" });
}
});
FlowRouter.route('/', {
name: 'homeNotLoggedIn',
action() {
BlazeLayout.render('MainLayout', { notLoggedIn: "login" });
this.render('MainLayout', { notLoggedIn: "login" });
}
});
FlowRouter.route('/login', {
name: 'login',
action() {
BlazeLayout.render('MainLayout', { notLoggedIn: "login" });
this.render('MainLayout', { notLoggedIn: "login" });
}
});
FlowRouter.route('/reg', {
name: 'reg',
action() {
BlazeLayout.render('MainLayout', { notLoggedIn: "reg" });
this.render('MainLayout', { notLoggedIn: "reg" });
}
});
FlowRouter.route('/userMgmt', {
name: 'userMgmt',
action() {
BlazeLayout.render('MainLayout', { main: 'userMgmt' });
this.render('MainLayout', { main: 'userMgmt' });
}
});
FlowRouter.route('/manageStore', {
name: 'storeMgmt',
action() {
BlazeLayout.render('MainLayout', { main: 'storeMgmt' });
this.render('MainLayout', { main: 'storeMgmt' });
}
});
FlowRouter.route('/manage', {
name: 'mgmtPage',
action() {
BlazeLayout.render('MainLayout', { main: 'mgmtPage' });
this.render('MainLayout', { main: 'mgmtPage' });
}
});
FlowRouter.route('/manageProduct', {
name: 'manageProduct',
action() {
BlazeLayout.render('MainLayout', { main: 'prodMgmt' });
this.render('MainLayout', { main: 'prodMgmt' });
}
});
FlowRouter.route('/manageLists', {
name: 'manageLists',
action() {
BlazeLayout.render('MainLayout', { main: 'listMgmt' });
this.render('MainLayout', { main: 'listMgmt' });
}
});
FlowRouter.route('/mylists', {
name: 'mylists',
action() {
BlazeLayout.render('MainLayout', { main: 'listsMain' });
this.render('MainLayout', { main: 'listsMain' });
}
});
FlowRouter.route('/listItems', {
name: 'listItems',
action() {
BlazeLayout.render('MainLayout', { main: 'listItemsMain' });
this.render('MainLayout', { main: 'listItemsMain' });
}
});
FlowRouter.route('/mymenus', {
name: 'mymenus',
action() {
BlazeLayout.render('MainLayout', { main: 'mainMenu' });
this.render('MainLayout', { main: 'mainMenu' });
}
});
FlowRouter.route('/menuItems', {
name: 'menuItems',
action() {
BlazeLayout.render('MainLayout', { main: 'menuItems' });
this.render('MainLayout', { main: 'menuItems' });
}
});
FlowRouter.route('/taskHome', {
name: 'taskHome',
action() {
BlazeLayout.render('MainLayout', { main: 'taskHome' });
this.render('MainLayout', { main: 'taskHome' });
}
});
FlowRouter.route('/myTasks', {
name: 'myTasks',
action() {
BlazeLayout.render('MainLayout', { main: 'myTasks' });
this.render('MainLayout', { main: 'myTasks' });
}
});
FlowRouter.route('/systemAdmin', {
name: 'systemAdmin',
action() {
BlazeLayout.render('MainLayout', { main: 'systemAdmin' });
this.render('MainLayout', { main: 'systemAdmin' });
}
});
FlowRouter.route('/cleanUp', {
name: 'cleanUp',
action() {
BlazeLayout.render('MainLayout', { main: 'cleanUp'});
this.render('MainLayout', { main: 'cleanUp'});
}
});
FlowRouter.route('/mySettings', {
name: 'mySettings',
action() {
BlazeLayout.render('MainLayout', { main: 'userConfig'});
this.render('MainLayout', { main: 'userConfig'});
}
});

2373
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
{
"name": "pPickup",
"name": "get-my",
"private": true,
"scripts": {
"start": "meteor run",
@ -12,6 +12,8 @@
"jquery": "^3.6.0",
"meteor-node-stubs": "^1.2.5",
"moment": "^2.29.4",
"node-cron": "^3.0.3",
"rss-url-parser": "^3.0.0",
"typeahead-standalone": "^5.2.0"
}
}

View file

@ -1,69 +1,239 @@
// this file has been converted for meteor 3 and later
import { Meteor } from 'meteor/meteor';
import { SysConfig } from '../imports/api/systemConfig';
import { MenuItems } from '../imports/api/menuItems';
import { Products } from '../imports/api/products.js';
import { Menus } from '../imports/api/menu.js';
import { MScripts } from '../imports/api/mScripts.js';
import { UpdateInfo } from '../imports/api/updateInfo.js';
import { Roles } from 'meteor/roles';
Meteor.startup(() => {
Meteor.startup(async() => {
// code to run on server at startup
Roles.createRole("user", {unlessExists: true});
Roles.createRole("admin", {unlessExists: true});
Roles.createRole("systemadmin", {unlessExists: true});
Roles.createRoleAsync("user", {unlessExists: true});
Roles.createRoleAsync("admin", {unlessExists: true});
Roles.createRoleAsync("systemadmin", {unlessExists: true});
// set the systemconfig defaults for registration
let regPolicy = SysConfig.findOne({});
if (typeof regPolicy == 'undefined') {
return SysConfig.insert({
SysAdminReg: false,
dateAdded: new Date(),
allowReg: true,
});
} else {
// console.log("Registration policy already set.");
}
// check if the isLInked item exists on menuitems, and if not, add it (data cleanup task)
let itemInfoNoLink = MenuItems.find({ isLinked: { $exists: false } }).fetch();
// console.log("No Ites with isLinked not set: " + itemInfoNoLink.length);
if (itemInfoNoLink.length > 0) {
// console.log("found items with isLinked not set.");
// console.dir(itemInfoNoLink);
let infoLength = itemInfoNoLink.length;
for (i=0; i < infoLength; i++) {
MenuItems.update({ _id: itemInfoNoLink[i]._id }, {
$set: {
isLinked: false,
// check if this has already been run
let regPolRun = await MScripts.findOneAsync({ scriptName: "DefaultRegPolicy", scriptRun: true });
if (!regPolRun) {
try {
let regPolicy = await SysConfig.findOneAsync({});
if (!regPolicy) {
SysConfig.insertAsync({
SysAdminReg: false,
dateAdded: new Date(),
allowReg: true,
allowUpdates: true,
});
markScriptRun("DefaultRegPolicy");
} else {
// console.log("Registration policy already set.");
markScriptRun("DefaultRegPolicy");
}
});
} catch(error) {
console.log(" ERROR trying to check if registration policy was set.");
console.log(error.message);
console.log(error.stack);
}
}
// check if the isLInked item exists on menuitems, and if not, add it (data cleanup task)
// see if already updated
let linkUpdateRun = await MScripts.findOneAsync({ scriptName: "updateMenuItemLinks", scriptRun: true });
try {
if (!linkUpdateRun) {
let itemInfoNoLink = MenuItems.find({ isLinked: { $exists: false } }).fetch();
// console.log("No Ites with isLinked not set: " + itemInfoNoLink.length);
if (itemInfoNoLink.length > 0) {
// console.log("Found items with isLinked not set. Updating...");
// console.dir(itemInfoNoLink);
let infoLength = itemInfoNoLink.length;
for (i=0; i < infoLength; i++) {
MenuItems.updateAsync({ _id: itemInfoNoLink[i]._id }, {
$set: {
isLinked: false,
}
});
if (i == (infoLength -1)) {
markScriptRun("updateMenuItemLinks");
}
}
} else {
// this will show if all items are found to have isLInked set.
// console.log("No items with isLinked not set.");
markScriptRun("updateMenuItemLinks");
}
}
} else {
// this will show if all items are found to have isLInked set.
console.log("No itesm with isLinked not set.");
} catch(error) {
console.log(" ERROR running check for isLinked items.");
console.log(error.message);
console.log(error.stack);
}
// update Products to be able to have multiple stores in the document
let prodInfo = Products.find({}).fetch();
let prodCount = prodInfo.length;
console.log("Updating Products to allow multiple store assocation for " + prodCount + " products.");
for (j = 0; j < prodCount; j++) {
if (typeof prodInfo[j].prodStore == 'object') {
// console.log(typeof prodInfo[j].prodStore);
// console.log("Is Array already");
} else {
let prodStoreArray = [];
// console.log("---- ---- ----");
// console.log(typeof prodInfo[j].prodStore);
// console.log("---- Is Not Array.");
let prodStore = prodInfo[j].prodStore;
// check if update already run
let prodStoreArrayRun = await MScripts.findOneAsync({ scriptName: "changeProdStoreToArray", scriptRun: true });
if (!prodStoreArrayRun) {
try {
let prodInfo = Products.find({}).fetch();
let prodCount = prodInfo.length;
// console.log("Updating Products to allow multiple store assocation for " + prodCount + " products.");
for (let j = 0; j < prodCount; j++) {
if (typeof prodInfo[j].prodStore == 'object') {
// console.log(typeof prodInfo[j].prodStore);
// console.log("Is Array already");
} else {
let prodStoreArray = [];
// console.log("---- ---- ----");
// console.log(typeof prodInfo[j].prodStore);
// console.log("---- Is Not Array.");
let prodStore = prodInfo[j].prodStore;
prodStoreArray.push(prodStore);
// console.dir(prodStoreArray);
Products.update({ _id: prodInfo[j]._id }, {
$set: {
prodStore: prodStoreArray,
prodStoreArray.push(prodStore);
// console.dir(prodStoreArray);
Products.update({ _id: prodInfo[j]._id }, {
$set: {
prodStore: prodStoreArray,
}
});
}
});
}
if (j == (prodCount -1)) {
markScriptRun("changeProdStoreToArray");
}
}
} catch(error) {
console.log("Script to update product stores couldn't run.");
console.log(error.message);
console.log(error.stack);
}
}
// update menu items to new format so they get the linked products
// check if this update has run
let menuItemUpdRun = await MScripts.findOneAsync({ scriptName: "updateMenuProdLinks", scriptRun: true });
if (!menuItemUpdRun) {
try {
let openMenus = Menus.find({ menuComplete: false }).fetch();
let openMenuCount = openMenus.length;
// console.log("Open Menu count is: " + openMenuCount);
for (let k = 0; k < openMenuCount; k++) {
if (typeof openMenus.menuItems == 'object') {
// console.log(openMenus.menuName + " appears to be converted.");
markScriptRun("updateMenuProdLinks");
} else {
let menuId = openMenus[k]._id;
let thisMenuItems = MenuItems.find({ menuId: menuId }).fetch();
let itemCount = thisMenuItems.length;
for (l = 0; l < itemCount; l++) {
Menus.update({ _id: menuId }, {
$addToSet: {
menuItems:
{
menuItemId: thisMenuItems[l]._id,
menuItemName: thisMenuItems[l].itemName,
serveDate: thisMenuItems[l].serveDate,
serveDateActual: thisMenuItems[l].serveDateActual,
isLinked: thisMenuItems[l].isLinked
},
}
});
}
}
if (k == (openMenuCount - 1)) {
markScriptRun("updateMenuProdLinks");
}
}
} catch(error) {
console.log(" ERROR updating the menu product links: ");
console.log(error.message);
console.log(error.stack);
}
} else {
// console.log("Menu Item updates have already been run.");
}
// get update available information if enabled in system confiuration
let currConfig = await SysConfig.findOneAsync({});
if (!currConfig) {
// console.log("No Current Config found.")
} else {
try {
let feedurl = "https://gitlab.com/bmcgonag/get_my/-/releases.atom"
if (currConfig.allowUpdates == true) {
// console.log("Allow Updates is true");
startCronForUpdates(feedurl);
} else if (typeof currConfig.allowUpdates == 'undefined' || currConfig.allowUpdates == null) {
SysConfig.update({ _id: currConfig._id }, { $set: {
allowUpdates: true,
}});
startCronForUpdates(feedurl);
}
} catch(error) {
console.log(" ERROR checking current config for updates: " + error);
console.log(error.message);
console.log(error.stack);
}
}
});
var startCronForUpdates = function(feedurl) {
var cron = require('node-cron');
cron.schedule('*/30 * * * *', () => {
getUpdateInfoNow(feedurl);
});
}
var markScriptRun = async function(scriptName) {
// check if this is already set
let scriptRun = await MScripts.findOneAsync({ scriptName: scriptName });
if (!scriptRun) {
try {
return MScripts.insertAsync({
scriptName: scriptName,
scriptRun: true,
runOn: new Date()
});
} catch(error) {
console.log(" ERROR inserting the script run log: " + error);
console.log(error.message);
console.log(error.stack);
}
} else {
// console.log(scriptName + " already set as run on " + scriptRun.runOn);
}
}
var getUpdateInfoNow = async function(feedurl) {
const parser = require('rss-url-parser')
const data = await parser(feedurl)
let dataLength = data.length;
// console.dir(data[0].title);
// check if this title already exists in db
let updatesExist = await UpdateInfo.findOneAsync({ title: data[0].title });
try {
if (!updatesExist) {
UpdateInfo.insertAsync({
title: data[0].title,
description: data[0].description,
dateRelease: data[0].date,
releaseLink: data[0].link,
viewed: false
});
} else {
console.log("No new updates available at this time.");
}
} catch(error) {
console.log(" ERROR checking for update: " + error);
console.log(error.message);
console.log(error.stack);
}
}

View file

@ -2,61 +2,67 @@ import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
import { TaskItems } from '../imports/api/tasks';
import { SysConfig } from '../imports/api/systemConfig';
import { Roles } from 'meteor/roles';
Meteor.methods({
'addToRole' (role) {
let countOfUsers = Meteor.users.find().count();
// if users = 1 - set to role passed in function call
if (countOfUsers > 1) {
console.log("User id for role: " + Meteor.userId() );
let userId = Meteor.userId();
Roles.addUsersToRoles(userId, role);
Meteor.call('add.darkModePref', "light", function(err, result) {
if (err) {
console.log(" ERROR: can't set user dark mode preference: " + err);
async 'addToRole' (role) {
try {
let countOfUsers = await Meteor.users.find().countAsync();
const user = await Meteor.userAsync();
if (user) {
let userId = user._id;
if (countOfUsers > 1) {
await Roles.addUsersToRolesAsync(userId, role);
const result = await Meteor.callAsync('add.darkModePref', "light");
if (!result) {
console.log(" ERROR: can't set user dark mode preference: " + err);
} else {
// console.log(" SUCCESSFULLY set user dark mode preference.");
}
} else if (countOfUsers == 1) {
await Roles.addUsersToRolesAsync(userId, "systemadmin");
const result = await Meteor.callAsync('add.darkModePref', "light");
if (!result) {
console.log(" ERROR: can't set user dark mode preference: " + err);
} else {
console.log(" SUCCESSFULLY set user dark mode preference.");
}
} else {
// console.log(" SUCCESSFULLY set user dark mode preference.");
console.log("The count of users didn't seem to work when adding a new user.");
}
});
} else if (countOfUsers == 1) {
console.log("Creating first system admin user: " + Meteor.userId() );
let userId = Meteor.userId();
Roles.addUsersToRoles(userId, "systemadmin");
Meteor.call('add.darkModePref', "light", function(err, result) {
if (err) {
console.log(" ERROR: can't set user dark mode preference: " + err);
} else {
// console.log(" SUCCESSFULLY set user dark mode preference.");
}
});
} else {
console.log(" ---- No user info found.")
}
} catch(error) {
console.log(" ERROR getting user info on server: " + error);
}
},
'edit.userPass' (userId, newPassword) {
async 'edit.userPass' (userId, newPassword) {
check(userId, String);
check(newPassword, String);
return Accounts.setPassword(userId, newPassword);
return await Accounts.setPasswordAsync(userId, newPassword);
},
'delete.userFromSys' (userId) {
async 'delete.userFromSys' (userId) {
check(userId, String);
return Meteor.users.remove({ _id: userId });
return await Meteor.users.removeAsync({ _id: userId });
},
'update.userEmail' (userId, email) {
async 'update.userEmail' (userId, email) {
check(userId, String);
check(email, String);
return Meteor.users.update({ _id: userId }, {
return await Meteor.users.updateAsync({ _id: userId }, {
$set: {
'emails.0.address': email,
}
});
},
'edit.userRole' (userId, role) {
async 'edit.userRole' (userId, role) {
check(userId, String);
check(role, String);
return Roles.setUserRoles(userId, role);
return await Roles.setUserRolesAsync(userId, role);
},
});

View file

@ -11,6 +11,14 @@ 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';
import { UpdateInfo } from '../imports/api/updateInfo.js';
Meteor.publish(null, function () {
if (this.userId) {
return Meteor.roleAssignment.find({ "user._id": this.userId });
}
this.ready();
});
Meteor.publish("SystemConfig", function() {
try {
@ -22,12 +30,20 @@ Meteor.publish("SystemConfig", function() {
Meteor.publish("UserConfigPrefs", function() {
try {
return UserConfig.find({});
return UserConfig.find({ user: this.userId });
} catch (error) {
console.log(" ERROR: Error accessing user config: " + error);
}
});
Meteor.publish("UpdateVersion", function() {
try {
return UpdateInfo.find({ viewed: false });
} catch(error) {
console.log(" ERROR pulling updated version info: " + error);
}
})
Meteor.publish('userList', function() {
return Meteor.users.find({});
});
@ -80,6 +96,28 @@ Meteor.publish("myListItems", function(listId) {
}
});
Meteor.publish("allListItems", function() {
try {
return ListItems.find({});
} catch (error) {
console.log(" ERROR pulling all list items.");
}
});
Meteor.publish("myStoreListItems", function(listId) {
try {
let stores = Store.find({});
if (stores) {
for (i=0; i<stores.length; i++) {
let items = ListItems.find({ prodStore: store[i], listId: listId }).fetch();
}
}
} catch (error) {
console.log(" ERROR pulling items or stores: " + error);
}
});
Meteor.publish("myMenus", function() {
try {
return Menus.find({ menuComplete: false });