Compare commits

1 Commits

Author SHA1 Message Date
3775522265 Initial cut - untested. 2025-09-25 09:31:02 -07:00
33 changed files with 351 additions and 346 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectTasksOptions"> <component name="ProjectTasksOptions">
<TaskOptions isEnabled="true"> <TaskOptions isEnabled="false">
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" /> <option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" />
<option name="checkSyntaxErrors" value="true" /> <option name="checkSyntaxErrors" value="true" />
<option name="description" /> <option name="description" />

View File

@@ -4,27 +4,28 @@
# 'meteor add' and 'meteor remove' will edit this file for you, # 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand. # but you can also edit it by hand.
meteor-base@1.5.1 # Packages every Meteor app needs to have meteor-base # Packages every Meteor app needs to have
mobile-experience@1.1.0 # Packages for a great mobile UX mobile-experience # Packages for a great mobile UX
mongo@1.16.6 # The database Meteor supports right now mongo # The database Meteor supports right now
jquery # Wrapper package for npm-installed jquery jquery # Wrapper package for npm-installed jquery
reactive-var@1.0.12 # Reactive variable for tracker reactive-var # Reactive variable for tracker
standard-minifier-css@1.9.2 # CSS minifier run for production mode standard-minifier-css # CSS minifier run for production mode
standard-minifier-js@2.8.1 # JS minifier run for production mode standard-minifier-js # JS minifier run for production mode
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers es5-shim # ECMAScript 5 compatibility for older browsers
ecmascript@0.16.7 # Enable ECMAScript2015+ syntax in app code ecmascript # Enable ECMAScript2015+ syntax in app code
typescript@4.9.4 # Enable TypeScript syntax in .ts and .tsx modules typescript # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.5.0 # Server-side component of the `meteor shell` command shell-server # Server-side component of the `meteor shell` command
static-html@1.3.2 # Define static page content in .html files static-html # Define static page content in .html files
react-meteor-data # React higher-order component for reactively tracking Meteor data react-meteor-data # React higher-order component for reactively tracking Meteor data
accounts-ui@1.4.2 accounts-ui
accounts-password@2.3.4 accounts-password
accounts-google@1.4.0 accounts-google
service-configuration@1.3.1 service-configuration
google-config-ui@1.0.3 # Adds the UI for logging in via Google google-config-ui # Adds the UI for logging in via Google
alanning:roles # Adds roles to the user alanning:roles # Adds roles to the user
msavin:mongol # Free version of MeteorToys - Provides access to the client side MongoDB for debugging. (Ctrl-M to activate :: https://atmospherejs.com/msavin/mongol) # Mongol requires mongo@1.6.0 which conflicts with the framework.
#msavin:mongol@10.0.1 # Free version of MeteorToys - Provides access to the client side MongoDB for debugging. (Ctrl-M to activate :: https://atmospherejs.com/msavin/mongol)
session session

View File

@@ -1 +1 @@
METEOR@2.12 METEOR@3.0.4

View File

@@ -1,99 +1,101 @@
accounts-base@2.2.8 accounts-base@3.0.3
accounts-google@1.4.0 accounts-google@1.4.1
accounts-oauth@1.4.2 accounts-oauth@1.4.5
accounts-password@2.3.4 accounts-password@3.0.3
accounts-ui@1.4.2 accounts-ui@1.4.3
accounts-ui-unstyled@1.7.0 accounts-ui-unstyled@1.7.2
alanning:roles@3.4.0 alanning:roles@4.0.0
allow-deny@1.1.1 allow-deny@2.0.0
autoupdate@1.8.0 autoupdate@2.0.0
babel-compiler@7.10.4 babel-compiler@7.11.2
babel-runtime@1.5.1 babel-runtime@1.5.2
base64@1.0.12 base64@1.0.13
binary-heap@1.0.11 binary-heap@1.0.12
blaze@2.6.2 blaze@3.0.1
blaze-tools@1.1.3 blaze-tools@2.0.0
boilerplate-generator@1.7.1 boilerplate-generator@2.0.0
caching-compiler@1.2.2 caching-compiler@2.0.1
caching-html-compiler@1.2.1 caching-html-compiler@2.0.0
callback-hook@1.5.1 callback-hook@1.6.0
check@1.3.2 check@1.4.4
ddp@1.4.1 core-runtime@1.0.0
ddp-client@2.6.1 ddp@1.4.2
ddp-common@1.4.0 ddp-client@3.0.3
ddp-rate-limiter@1.2.0 ddp-common@1.4.4
ddp-server@2.6.1 ddp-rate-limiter@1.2.2
diff-sequence@1.1.2 ddp-server@3.0.3
dynamic-import@0.7.3 diff-sequence@1.1.3
ecmascript@0.16.7 dynamic-import@0.7.4
ecmascript-runtime@0.8.1 ecmascript@0.16.10
ecmascript-runtime-client@0.12.1 ecmascript-runtime@0.8.3
ecmascript-runtime-server@0.11.0 ecmascript-runtime-client@0.12.2
ejson@1.1.3 ecmascript-runtime-server@0.11.1
email@2.2.5 ejson@1.1.4
es5-shim@4.8.0 email@3.1.1
fetch@0.1.3 es5-shim@4.8.1
geojson-utils@1.0.11 facts-base@1.0.2
google-config-ui@1.0.3 fetch@0.1.5
google-oauth@1.4.3 geojson-utils@1.0.12
hot-code-push@1.0.4 google-config-ui@1.0.4
html-tools@1.1.3 google-oauth@1.4.5
htmljs@1.1.1 hot-code-push@1.0.5
id-map@1.1.1 html-tools@2.0.0
inter-process-messaging@0.1.1 htmljs@2.0.1
jquery@3.0.0 id-map@1.2.0
launch-screen@1.3.0 inter-process-messaging@0.1.2
less@4.0.0 jquery@3.0.2
localstorage@1.2.0 launch-screen@2.0.1
logging@1.3.2 less@4.1.1
meteor@1.11.2 localstorage@1.2.1
meteor-base@1.5.1 logging@1.3.5
meteortoys:toykit@10.0.0 meteor@2.0.2
minifier-css@1.6.4 meteor-base@1.5.2
minifier-js@2.7.5 minifier-css@2.0.0
minimongo@1.9.3 minifier-js@3.0.1
mobile-experience@1.1.0 minimongo@2.0.1
mobile-status-bar@1.1.0 mobile-experience@1.1.2
modern-browsers@0.1.9 mobile-status-bar@1.1.1
modules@0.19.0 modern-browsers@0.1.11
modules-runtime@0.13.1 modules@0.20.3
mongo@1.16.6 modules-runtime@0.13.2
mongo-decimal@0.1.3 mongo@2.0.2
mongo-dev-server@1.1.0 mongo-decimal@0.1.4
mongo-id@1.0.8 mongo-dev-server@1.1.1
msavin:mongol@10.0.1 mongo-id@1.0.9
npm-mongo@4.16.0 npm-mongo@4.17.4
oauth@2.2.0 oauth@3.0.0
oauth2@1.3.2 oauth2@1.3.3
observe-sequence@1.0.21 observe-sequence@2.0.0
ordered-dict@1.1.0 ordered-dict@1.2.0
promise@0.12.2 promise@1.0.0
random@1.2.1 random@1.2.2
rate-limit@1.1.1 rate-limit@1.1.2
react-fast-refresh@0.2.7 react-fast-refresh@0.2.9
react-meteor-data@2.7.2 react-meteor-data@2.0.1
reactive-dict@1.3.1 reactive-dict@1.3.2
reactive-var@1.0.12 reactive-var@1.0.13
reload@1.3.1 reload@1.3.2
retry@1.1.0 retry@1.1.1
routepolicy@1.1.1 routepolicy@1.1.2
service-configuration@1.3.1 service-configuration@1.3.5
session@1.2.1 session@1.2.2
sha@1.0.9 sha@1.0.10
shell-server@0.5.0 shell-server@0.6.1
socket-stream-client@0.5.1 socket-stream-client@0.5.3
spacebars@1.3.0 spacebars@2.0.0
spacebars-compiler@1.3.1 spacebars-compiler@2.0.0
standard-minifier-css@1.9.2 standard-minifier-css@1.9.3
standard-minifier-js@2.8.1 standard-minifier-js@3.0.0
static-html@1.3.2 static-html@1.4.0
templating@1.4.2 static-html-tools@1.0.0
templating-compiler@1.4.1 templating@1.4.4
templating-runtime@1.6.3 templating-compiler@2.0.0
templating-tools@1.2.2 templating-runtime@2.0.1
tracker@1.3.2 templating-tools@2.0.0
typescript@4.9.4 tracker@1.3.4
underscore@1.0.13 typescript@5.4.3
url@1.3.2 underscore@1.6.4
webapp@1.13.5 url@1.3.5
webapp-hashing@1.1.1 webapp@2.0.4
webapp-hashing@1.1.2
zodern:types@1.0.13

View File

@@ -6,28 +6,28 @@ import { Roles } from 'meteor/alanning:roles';
if (Meteor.isServer) { if (Meteor.isServer) {
Meteor.methods({ Meteor.methods({
'admin.fixRecords'(input) { async 'admin.fixRecords'(input) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
console.log("In Fix Records"); console.log("In Fix Records");
console.log("Deleting invalid records..."); console.log("Deleting invalid records...");
// Delete any records missing key fields. // Delete any records missing key fields.
Meteor.Records.remove({serial: {$exists: false}}); await Meteor.Records.removeAsync({serial: {$exists: false}});
Meteor.Records.remove({deviceId: {$exists: false}}); await Meteor.Records.removeAsync({deviceId: {$exists: false}});
Meteor.Records.remove({endTime: {$exists: false}}); await Meteor.Records.removeAsync({endTime: {$exists: false}});
console.log("Consolidating records..."); console.log("Consolidating records...");
let emails = _.uniq(Meteor.Records.find({}, { let emails = _.uniq((await Meteor.Records.find({}, {
sort: {email: 1}, sort: {email: 1},
fields: {email: true} fields: {email: true}
}).fetch().map(function (x) { }).fetchAsync()).map(function (x) {
return x.email; return x.email;
}), true); }), true);
emails.forEach(email => { for(const email of emails) {
// Find all records for the user sorted from oldest to newest. // Find all records for the user sorted from oldest to newest.
let records = Meteor.Records.find({email}, {sort: {startTime: 1}}).fetch(); let records = await Meteor.Records.find({email}, {sort: {startTime: 1}}).fetchAsync();
let newRecords = []; let newRecords = [];
let record = records[0]; let record = records[0];
@@ -46,12 +46,12 @@ if (Meteor.isServer) {
} }
newRecords.push(record); newRecords.push(record);
Meteor.Records.remove({email}); await Meteor.Records.removeAsync({email});
for (let index = 0; index < newRecords.length; index++) { for (let index = 0; index < newRecords.length; index++) {
Meteor.Records.insert(newRecords[index]); await Meteor.Records.insertAsync(newRecords[index]);
}
} }
});
} }
}, },
}); });

View File

@@ -33,7 +33,7 @@ if (Meteor.isServer) {
* @param params An object with a single attribute. The attribute must be one of: email, deviceId, assetId, serial, staffId, or studentId. It will find all Assignment data for the given attribute value. * @param params An object with a single attribute. The attribute must be one of: email, deviceId, assetId, serial, staffId, or studentId. It will find all Assignment data for the given attribute value.
* @returns {any} Array of Asset Assignment History objects. * @returns {any} Array of Asset Assignment History objects.
*/ */
'AssetAssignmentHistory.get'(params) { async 'AssetAssignmentHistory.get'(params) {
let result let result
if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
@@ -53,11 +53,11 @@ if (Meteor.isServer) {
if(params.email) check(params.email, String) if(params.email) check(params.email, String)
if(params.email) { if(params.email) {
let person = Students.findOne({email: params.email}) let person = await Students.findOneAsync({email: params.email})
if(person) params.studentId = person._id; if(person) params.studentId = person._id;
else { else {
person = Staff.findOne({email: params.email}) person = await Staff.findOneAsync({email: params.email})
if(person) params.staffId = person._id; if(person) params.staffId = person._id;
// else throw new Meteor.Error("Could not find a student or staff member with the given email.") // else throw new Meteor.Error("Could not find a student or staff member with the given email.")
@@ -69,8 +69,8 @@ if (Meteor.isServer) {
else if(params.assetId) query.assetId = params.assetId; else if(params.assetId) query.assetId = params.assetId;
else if(params.deviceId) query.deviceId = params.deviceId; else if(params.deviceId) query.deviceId = params.deviceId;
asset = Assets.findOne(query) asset = await Assets.findOneAsync(query)
if(asset) assetType = AssetTypes.findOne({_id: asset.assetTypeId}) if(asset) assetType = await AssetTypes.findOneAsync({_id: asset.assetTypeId})
} }
else { else {
if(params.studentId) { if(params.studentId) {
@@ -85,25 +85,25 @@ if (Meteor.isServer) {
query = undefined; query = undefined;
} }
person = query.assigneeType === "Student" ? Students.findOne({id: query.assigneeId}) : Staff.findOne({id: query.assigneeId}) person = query.assigneeType === "Student" ? await Students.findOneAsync({id: query.assigneeId}) : await Staff.findOneAsync({id: query.assigneeId})
} }
if(query) { if(query) {
//Sort by the last time the record was updated from most to least recent. //Sort by the last time the record was updated from most to least recent.
result = AssetAssignmentHistory.find(query, {sort: {endDate: -1}}).fetch(); result = await AssetAssignmentHistory.find(query, {sort: {endDate: -1}}).fetchAsync();
//Expand the assignee, asset, and asset type data. //Expand the assignee, asset, and asset type data.
for(let next of result) { for(let next of result) {
if(person) next.assignee = person if(person) next.assignee = person
else next.assignee = next.assigneeType === "Student" ? Students.findOne({_id: next.assigneeId}) : Staff.findOne({_id: next.assigneeId}) else next.assignee = next.assigneeType === "Student" ? await Students.findOneAsync({_id: next.assigneeId}) : await Staff.findOneAsync({_id: next.assigneeId})
if(asset) { if(asset) {
next.asset = asset next.asset = asset
next.assetType = assetType next.assetType = assetType
} }
else { else {
next.asset = Assets.findOne({assetId: next.assetId}) next.asset = await Assets.findOneAsync({assetId: next.assetId})
if(next.asset) next.assetType = AssetTypes.findOne({_id: next.asset.assetTypeId}) if(next.asset) next.assetType = await AssetTypes.findOneAsync({_id: next.asset.assetTypeId})
} }
} }
} }

View File

@@ -48,26 +48,26 @@ if (Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'assetTypes.add'(name, description, year) { async 'assetTypes.add'(name, description, year) {
check(name, String); check(name, String);
check(description, String); check(description, String);
check(year, String); check(year, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
AssetTypes.insert({name, description, year}); await AssetTypes.insertAsync({name, description, year});
} }
}, },
'assetTypes.update'(_id, name, description, year) { async 'assetTypes.update'(_id, name, description, year) {
check(_id, String); check(_id, String);
check(name, String); check(name, String);
check(description, String); check(description, String);
check(year, String); check(year, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
AssetTypes.update({_id}, {$set: {name, description, year}}); await AssetTypes.updateAsync({_id}, {$set: {name, description, year}});
} }
}, },
'assetTypes.remove'(_id) { async 'assetTypes.remove'(_id) {
check(_id, String); check(_id, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {

View File

@@ -84,7 +84,7 @@ if (Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'assets.add'(assetTypeId, assetId, serial, condition, conditionDetails) { async 'assets.add'(assetTypeId, assetId, serial, condition, conditionDetails) {
check(assetTypeId, String); check(assetTypeId, String);
check(assetId, String); check(assetId, String);
check(serial, String); check(serial, String);
@@ -101,29 +101,29 @@ Meteor.methods({
assetId = assetId.toUpperCase(); assetId = assetId.toUpperCase();
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
let assetType = AssetTypes.findOne({assetTypeId}); let assetType = await AssetTypes.findOneAsync({assetTypeId});
if(Assets.findOne({assetId})) { if(await Assets.findOneAsync({assetId})) {
//return {error: true, errorType: 'duplicateAssetId'} //return {error: true, errorType: 'duplicateAssetId'}
throw new Meteor.Error("Duplicate Asset Id", "Cannot use the same asset ID twice.") throw new Meteor.Error("Duplicate Asset Id", "Cannot use the same asset ID twice.")
} }
else if(serial) { else if(serial) {
Assets.insert({assetTypeId, assetId, serial, condition, conditionDetails}); await Assets.insertAsync({assetTypeId, assetId, serial, condition, conditionDetails});
} }
else { else {
Assets.insert({assetTypeId, assetId, condition, conditionDetails}); await Assets.insertAsync({assetTypeId, assetId, condition, conditionDetails});
} }
} }
else throw new Meteor.Error("User Permission Error"); else throw new Meteor.Error("User Permission Error");
}, },
'assets.update'(_id, assetTypeId, assetId, serial, condition, conditionDetails) { async 'assets.update'(_id, assetTypeId, assetId, serial, condition, conditionDetails) {
check(_id, String); check(_id, String);
check(assetTypeId, String); check(assetTypeId, String);
check(assetId, String); check(assetId, String);
if(serial) check(serial, String); if(serial) check(serial, String);
check(condition, String); check(condition, String);
if(conditionDetails) check(conditionDetails, String); if(conditionDetails) check(conditionDetails, String);
const existing = Assets.findOne({_id}) const existing = await Assets.findOneAsync({_id})
if(!conditions.includes(condition)) { if(!conditions.includes(condition)) {
//Should never happen. //Should never happen.
@@ -133,17 +133,17 @@ Meteor.methods({
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
//TODO: Need to first verify there are no checked out assets to the staff member. //TODO: Need to first verify there are no checked out assets to the staff member.
Assets.update({_id}, {$set: {assetTypeId, assetId, serial, condition, conditionDetails}}); await Assets.updateAsync({_id}, {$set: {assetTypeId, assetId, serial, condition, conditionDetails}});
if(assetId !== existing.assetId) { if(assetId !== existing.assetId) {
//When changing the asset id we also need to update the other locations in the data where that ID exists. //When changing the asset id we also need to update the other locations in the data where that ID exists.
// assetAssignmentHistory.assetId // assetAssignmentHistory.assetId
AssetAssignmentHistory.updateMany({assetId: existing.assetId}, {$set: {assetId}}) await AssetAssignmentHistory.updateManyAsync({assetId: existing.assetId}, {$set: {assetId}})
} }
} }
else throw new Meteor.Error("User Permission Error"); else throw new Meteor.Error("User Permission Error");
}, },
'assets.updateCondition'(_id, condition, conditionDetails) { async 'assets.updateCondition'(_id, condition, conditionDetails) {
console.log("updating condtition: " + condition + " / " + conditionDetails) console.log("updating condtition: " + condition + " / " + conditionDetails)
check(_id, String) check(_id, String)
check(condition, String) check(condition, String)
@@ -157,15 +157,15 @@ Meteor.methods({
if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
console.log("updating .... ") console.log("updating .... ")
Assets.update({_id}, {$set: {condition, conditionDetails}}); await Assets.updateAsync({_id}, {$set: {condition, conditionDetails}});
} }
else throw new Meteor.Error("User Permission Error"); else throw new Meteor.Error("User Permission Error");
}, },
'assets.remove'(_id) { async 'assets.remove'(_id) {
check(_id, String); check(_id, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
let asset = Assets.findOne({_id}); let asset = await Assets.findOneAsync({_id});
if(asset) { if(asset) {
// Ensure the asset is not assigned still. Must unassign then remove. That allows us to maintain historical records for assignees. // Ensure the asset is not assigned still. Must unassign then remove. That allows us to maintain historical records for assignees.
@@ -173,7 +173,7 @@ Meteor.methods({
throw new Meteor.Error("Must unassign the asset before removal."); throw new Meteor.Error("Must unassign the asset before removal.");
} }
else { else {
Assets.remove({_id}); await Assets.removeAsync({_id});
} }
} }
else { else {
@@ -192,7 +192,7 @@ Meteor.methods({
* @param conditionDetails A text block detailing the current condition (if it is needed). * @param conditionDetails A text block detailing the current condition (if it is needed).
* @param date The date/time of the action. Will be set to the current date/time if not provided. * @param date The date/time of the action. Will be set to the current date/time if not provided.
*/ */
'assets.assign'(assetId, assigneeType, assigneeId, condition, conditionDetails, date) { async 'assets.assign'(assetId, assigneeType, assigneeId, condition, conditionDetails, date) {
check(assigneeId, String); check(assigneeId, String);
check(assigneeType, String); check(assigneeType, String);
check(assetId, String); check(assetId, String);
@@ -215,7 +215,7 @@ Meteor.methods({
throw new Meteor.Error("Error: Received incorrect assignee type in adding an assignment."); throw new Meteor.Error("Error: Received incorrect assignee type in adding an assignment.");
} }
else if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) { else if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
let asset = Assets.findOne({assetId}); let asset = await Assets.findOneAsync({assetId});
if(asset) { if(asset) {
if(asset.assigneeId) { if(asset.assigneeId) {
@@ -224,7 +224,7 @@ Meteor.methods({
throw new Meteor.Error("Asset is already assigned.", "Cannot assign an asset that has already been assigned."); throw new Meteor.Error("Asset is already assigned.", "Cannot assign an asset that has already been assigned.");
} }
else { else {
Assets.update({assetId}, {$set: {assigneeType, assigneeId, assignmentDate: date, condition, conditionDetails, assignedBy: Meteor.userId()}}); await Assets.updateAsync({assetId}, {$set: {assigneeType, assigneeId, assignmentDate: date, condition, conditionDetails, assignedBy: Meteor.userId()}});
} }
} }
else { else {
@@ -242,7 +242,7 @@ Meteor.methods({
* @param conditionDetails A text block detailing the current condition (if it is needed). * @param conditionDetails A text block detailing the current condition (if it is needed).
* @param date The date/time of the action. Will be set to the current date/time if not provided. * @param date The date/time of the action. Will be set to the current date/time if not provided.
*/ */
'assets.unassign'(assetId, comment, condition, conditionDetails, date) { async 'assets.unassign'(assetId, comment, condition, conditionDetails, date) {
check(assetId, String); check(assetId, String);
if(date) check(date, Date); if(date) check(date, Date);
if(comment) check(comment, String); if(comment) check(comment, String);
@@ -258,17 +258,17 @@ Meteor.methods({
} }
if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
let asset = Assets.findOne({assetId}); let asset = await Assets.findOneAsync({assetId});
if(asset) { if(asset) {
let assetType = AssetTypes.findOne({_id: asset.assetTypeId}); let assetType = await AssetTypes.findOneAsync({_id: asset.assetTypeId});
try { try {
AssetAssignmentHistory.insert({assetKey: asset._id, assetId, serial: asset.serial, assetTypeName: (assetType ? assetType.name : "UNK"), assigneeType: asset.assigneeType, assigneeId: asset.assigneeId, startDate: asset.assignmentDate, endDate: date, startCondition: asset.condition, endCondition: condition, startConditionDetails: asset.conditionDetails, endConditionDetails: conditionDetails, comment, unassignedBy: Meteor.userId(), assignedBy: asset.assignedBy}); await AssetAssignmentHistory.insertAsync({assetKey: asset._id, assetId, serial: asset.serial, assetTypeName: (assetType ? assetType.name : "UNK"), assigneeType: asset.assigneeType, assigneeId: asset.assigneeId, startDate: asset.assignmentDate, endDate: date, startCondition: asset.condition, endCondition: condition, startConditionDetails: asset.conditionDetails, endConditionDetails: conditionDetails, comment, unassignedBy: Meteor.userId(), assignedBy: asset.assignedBy});
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
Assets.update({assetId}, {$unset: {assigneeType: "", assigneeId: "", assignmentDate: "", assignedBy: ""}, $set: {condition, conditionDetails}}); await Assets.updateAsync({assetId}, {$unset: {assigneeType: "", assigneeId: "", assignmentDate: "", assignedBy: ""}, $set: {condition, conditionDetails}});
} }
else { else {
console.error("Could not find the asset: " + assetId); console.error("Could not find the asset: " + assetId);
@@ -280,7 +280,9 @@ Meteor.methods({
/** /**
* A fix to remove the AssetAssignment collection and merge it with the Asset collection. * A fix to remove the AssetAssignment collection and merge it with the Asset collection.
*/ */
'assets.fixAssetAssignments'() { async 'assets.fixAssetAssignments'() {
//Note: Did not update this to Meteor 3.0
// Removed this since it should no longer be relevant. // Removed this since it should no longer be relevant.
// let assignmentDate = new Date(); // let assignmentDate = new Date();
@@ -310,17 +312,17 @@ Meteor.methods({
/** /**
* A fix to remove the AssetAssignment collection and merge it with the Asset collection. * A fix to remove the AssetAssignment collection and merge it with the Asset collection.
*/ */
'assets.fixAssetCondition'() { async 'assets.fixAssetCondition'() {
// Removed this since it should no longer be relevant. // Removed this since it should no longer be relevant.
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Assets.update({assetTypeId: 'xPu8YK39pmQW93Fuz', condition: {$exists: false}}, {$set: {condition: 'Okay', conditionDetails: 'Automated Condition'}}, {multi: true}); //Lenovo E100 CB await Assets.updateAsync({assetTypeId: 'xPu8YK39pmQW93Fuz', condition: {$exists: false}}, {$set: {condition: 'Okay', conditionDetails: 'Automated Condition'}}, {multi: true}); //Lenovo E100 CB
Assets.update({assetTypeId: 'casMp4pJ9t8FtpyuR', condition: {$exists: false}}, {$set: {condition: 'Good', conditionDetails: 'Automated Condition'}}, {multi: true}); //Lenovo E100 Charger await Assets.updateAsync({assetTypeId: 'casMp4pJ9t8FtpyuR', condition: {$exists: false}}, {$set: {condition: 'Good', conditionDetails: 'Automated Condition'}}, {multi: true}); //Lenovo E100 Charger
Assets.update({assetTypeId: 'ZD9XiHqGr6TcKH9Nv', condition: {$exists: false}}, {$set: {condition: 'New'}}, {multi: true}); //Acer CB315 CB await Assets.updateAsync({assetTypeId: 'ZD9XiHqGr6TcKH9Nv', condition: {$exists: false}}, {$set: {condition: 'New'}}, {multi: true}); //Acer CB315 CB
Assets.update({assetTypeId: 'mfE9NtiFBotb8kp4v', condition: {$exists: false}}, {$set: {condition: 'New'}}, {multi: true}); //Acer CB315 Charger await Assets.updateAsync({assetTypeId: 'mfE9NtiFBotb8kp4v', condition: {$exists: false}}, {$set: {condition: 'New'}}, {multi: true}); //Acer CB315 Charger
Assets.update({assetTypeId: 'btEsKYxW4Sgf7T8nA', condition: {$exists: false}}, {$set: {condition: 'Good',conditionDetails: 'Automated Condition'}}, {multi: true}); //Dell 3100 Charger await Assets.updateAsync({assetTypeId: 'btEsKYxW4Sgf7T8nA', condition: {$exists: false}}, {$set: {condition: 'Good',conditionDetails: 'Automated Condition'}}, {multi: true}); //Dell 3100 Charger
Assets.update({assetTypeId: '9bszeFJNPteMDbye5', condition: {$exists: false}}, {$set: {condition: 'Like New',conditionDetails: 'Automated Condition'}}, {multi: true}); //HP 11A CB await Assets.updateAsync({assetTypeId: '9bszeFJNPteMDbye5', condition: {$exists: false}}, {$set: {condition: 'Like New',conditionDetails: 'Automated Condition'}}, {multi: true}); //HP 11A CB
Assets.update({assetTypeId: 'tCj7s5T2YcFXZEaqE', condition: {$exists: false}}, {$set: {condition: 'Like New',conditionDetails: 'Automated Condition'}}, {multi: true}); //HP 11A Charger await Assets.updateAsync({assetTypeId: 'tCj7s5T2YcFXZEaqE', condition: {$exists: false}}, {$set: {condition: 'Like New',conditionDetails: 'Automated Condition'}}, {multi: true}); //HP 11A Charger
} }
} }
}); });

View File

@@ -42,7 +42,7 @@ if (Meteor.isServer) {
* @param params An object with a single attribute. The attribute must be one of: deviceId, serial, email. It will find all Chromebook data that starts with the given attribute value. * @param params An object with a single attribute. The attribute must be one of: deviceId, serial, email. It will find all Chromebook data that starts with the given attribute value.
* @returns {any} Array of Chromebook data objects. * @returns {any} Array of Chromebook data objects.
*/ */
'DataCollection.chromebookData'(params) { async 'DataCollection.chromebookData'(params) {
if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
let query = {}; let query = {};
@@ -51,7 +51,7 @@ if (Meteor.isServer) {
// For asset ID's, we need to get the serial from the asset collection first. // For asset ID's, we need to get the serial from the asset collection first.
if(params.assetId) { if(params.assetId) {
let asset = Assets.findOne({assetId : params.assetId}); let asset = await Assets.findOneAsync({assetId : params.assetId});
if(asset) { if(asset) {
params.serial = asset.serial; params.serial = asset.serial;
@@ -70,14 +70,14 @@ if (Meteor.isServer) {
$options: "i" $options: "i"
} : params.serial; } : params.serial;
else if(params.studentId) { else if(params.studentId) {
const student = Students.findOne({_id: params.studentId}) const student = await Students.findOneAsync({_id: params.studentId})
// console.log(student) // console.log(student)
if(student) query.email = student.email; if(student) query.email = student.email;
else query = undefined else query = undefined
} }
else if(params.staffId) { else if(params.staffId) {
const staff = Staff.findOne({_id: params.staffId}) const staff = await Staff.findOneAsync({_id: params.staffId})
if(staff) query.email = staff.email; if(staff) query.email = staff.email;
else query = undefined else query = undefined
@@ -101,27 +101,27 @@ if (Meteor.isServer) {
// console.log(query); // console.log(query);
//Sort by the last time the record was updated from most to least recent. //Sort by the last time the record was updated from most to least recent.
let result = Meteor.Records.find(query, {sort: {endTime: -1}}).fetch(); let result = await Meteor.Records.find(query, {sort: {endTime: -1}}).fetchAsync();
// console.log("Found: "); // console.log("Found: ");
// console.log(result); // console.log(result);
//Add some additional data to the records. //Add some additional data to the records.
for (let next of result) { for (let next of result) {
if (next.serial) { if (next.serial) {
next.asset = Assets.findOne({serial: next.serial}); next.asset = await Assets.findOneAsync({serial: next.serial});
} }
if (next.email) { if (next.email) {
next.person = Students.findOne({email: next.email}); next.person = Students.findOne({email: next.email});
if (!next.person) next.person = Staff.findOne({email: next.email}); if (!next.person) next.person = await Staff.findOneAsync({email: next.email});
} }
if (next.asset) { if (next.asset) {
next.assetType = AssetTypes.findOne({_id: next.asset.assetTypeId}) next.assetType = await AssetTypes.findOneAsync({_id: next.asset.assetTypeId})
if (next.asset.assigneeId) { if (next.asset.assigneeId) {
next.assignedTo = next.asset.assigneeType === "Student" ? Students.findOne({_id: next.asset.assigneeId}) : Staff.findOne({_id: next.asset.assigneeId}) next.assignedTo = next.asset.assigneeType === "Student" ? await Students.findOneAsync({_id: next.asset.assigneeId}) : await Staff.findOneAsync({_id: next.asset.assigneeId})
} }
} }
} }

View File

@@ -13,25 +13,25 @@ if (Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'sites.update'(_id, name, externalId) { async 'sites.update'(_id, name, externalId) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Sites.update({_id}, {$set: {name, externalId}}); await Sites.updateAsync({_id}, {$set: {name, externalId}});
} }
}, },
'sites.add'(name, externalId) { async 'sites.add'(name, externalId) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Sites.insert({name, externalId}); await Sites.insertAsync({name, externalId});
} }
}, },
'sites.remove'(_id) { async 'sites.remove'(_id) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
let site = Sites.find({_id}); let site = await Sites.findOneAsync({_id});
if(site) { if(site) {
//Clear any site references in student/room entries. //Clear any site references in student/room entries.
Students.update({siteId: _id}, {$unset: {siteId: 1}}); await Students.updateAsync({siteId: _id}, {$unset: {siteId: 1}});
Staff.update({siteId: _id}, {$unset: {siteId: 1}}); await Staff.updateAsync({siteId: _id}, {$unset: {siteId: 1}});
Sites.remove({_id}); await Sites.removeAsync({_id});
} }
} }
}, },

View File

@@ -17,17 +17,17 @@ if (Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'staff.add'(id, firstName, lastName, email, siteId) { async 'staff.add'(id, firstName, lastName, email, siteId) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Staff.insert({id, firstName, lastName, email, siteId}); await Staff.insertAsync({id, firstName, lastName, email, siteId});
} }
}, },
'staff.update'(_id, id, firstName, lastName, email, siteId) { async 'staff.update'(_id, id, firstName, lastName, email, siteId) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Staff.update({_id}, {$set: {id, firstName, lastName, email, siteId}}); await Staff.updateAsync({_id}, {$set: {id, firstName, lastName, email, siteId}});
} }
}, },
'staff.remove'(_id) { async 'staff.remove'(_id) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
//TODO: Need to first verify there are no checked out assets to the staff member. //TODO: Need to first verify there are no checked out assets to the staff member.
} }
@@ -52,12 +52,12 @@ Meteor.methods({
* StuEmail,Student ID,First Name,Last Name,Grade,First Name Alias,Last Name Alias * StuEmail,Student ID,First Name,Last Name,Grade,First Name Alias,Last Name Alias
* @type: Currently only supports 'CSV' or 'Aeries Text Report' * @type: Currently only supports 'CSV' or 'Aeries Text Report'
*/ */
'staff.loadCsv'(csv, type, siteId) { async 'staff.loadCsv'(csv, type, siteId) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
check(csv, String); check(csv, String);
check(siteId, String); check(siteId, String);
let site = Sites.findOne({_id: siteId}); let site = await Sites.findOneAsync({_id: siteId});
if(site) { if(site) {
let cleanCsv; let cleanCsv;
@@ -107,8 +107,8 @@ Meteor.methods({
const bound = Meteor.bindEnvironment((callback) => {callback();}); const bound = Meteor.bindEnvironment((callback) => {callback();});
parse(cleanCsv, {}, function(err, records) { parse(cleanCsv, {}, async function(err, records) {
bound(() => { bound(async () => {
if(err) console.error(err); if(err) console.error(err);
else { else {
let foundIds = new Set(); let foundIds = new Set();
@@ -138,7 +138,7 @@ Meteor.methods({
//console.log(staff); //console.log(staff);
try { try {
Staff.upsert({id: staff.id}, {$set: staff}); await Staff.upsertAsync({id: staff.id}, {$set: staff});
} }
catch(err) { catch(err) {
console.error(err); console.error(err);

View File

@@ -8,7 +8,7 @@ import {parse} from 'csv-parse';
export const Students = new Mongo.Collection('students'); export const Students = new Mongo.Collection('students');
if (Meteor.isServer) { if (Meteor.isServer) {
Students.createIndex({id: 1}, {name: "External ID", unique: true}); await Students.createIndexAsync({id: 1}, {name: "External ID", unique: true});
// This code only runs on the server // This code only runs on the server
Meteor.publish('students', function(siteId) { Meteor.publish('students', function(siteId) {
@@ -17,26 +17,26 @@ if (Meteor.isServer) {
}); });
Meteor.methods({ Meteor.methods({
'students.add'(id, firstName, firstNameAlias, lastName, email, siteId, grade, active) { async 'students.add'(id, firstName, firstNameAlias, lastName, email, siteId, grade, active) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Students.insert({id, firstName, firstNameAlias, lastName, email, siteId, grade, active, activeChangeTimestamp: active ? "" : new Date()}); await Students.insertAsync({id, firstName, firstNameAlias, lastName, email, siteId, grade, active, activeChangeTimestamp: active ? "" : new Date()});
} }
}, },
'students.update'(_id, id, firstName, firstNameAlias, lastName, email, siteId, grade, active) { async 'students.update'(_id, id, firstName, firstNameAlias, lastName, email, siteId, grade, active) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Students.update({_id}, {$set: {id, firstName, firstNameAlias, lastName, email, siteId, grade, active, activeChangeTimestamp: active ? "" : new Date()}}); await Students.updateAsync({_id}, {$set: {id, firstName, firstNameAlias, lastName, email, siteId, grade, active, activeChangeTimestamp: active ? "" : new Date()}});
} }
}, },
'students.remove'(_id) { async 'students.remove'(_id) {
// Does not actually remove the student (not currently possible. Does set the student to not-active. // Does not actually remove the student (not currently possible. Does set the student to not-active.
// If we want to remove students we should allow it for non-active students if there are no assets assigned. // If we want to remove students we should allow it for non-active students if there are no assets assigned.
// We may want to do this automatically, perhaps for students that have been non-active for a long period of time. // We may want to do this automatically, perhaps for students that have been non-active for a long period of time.
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
// Set the student as non-active and set the timestamp for the change (so we know how long they have been inactive for - so we can potentially automatically remove them later. // Set the student as non-active and set the timestamp for the change (so we know how long they have been inactive for - so we can potentially automatically remove them later.
Students.update({_id}, {$set: {active: false, activeChangeTimestamp: new Date()}}) await Students.updateAsync({_id}, {$set: {active: false, activeChangeTimestamp: new Date()}})
} }
}, },
'students.getPossibleGrades'() { async 'students.getPossibleGrades'() {
return Students.rawCollection().distinct('grade', {}); return Students.rawCollection().distinct('grade', {});
}, },
/** /**
@@ -44,12 +44,12 @@ if (Meteor.isServer) {
* @param _id The student's database ID. * @param _id The student's database ID.
* @param alias The alias to set for the student. * @param alias The alias to set for the student.
*/ */
'students.setAlias'(_id, alias) { async 'students.setAlias'(_id, alias) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
check(_id, String); check(_id, String);
check(alias, String); check(alias, String);
Students.update({_id}, !alias || !alias.length() ? {$unset: {alias: true}} : {$set: {alias}}); await Students.updateAsync({_id}, !alias || !alias.length() ? {$unset: {alias: true}} : {$set: {alias}});
} }
}, },
/** /**
@@ -81,12 +81,12 @@ if (Meteor.isServer) {
* TODO: Each imported student should be attached to the correct site * TODO: Each imported student should be attached to the correct site
* TODO: Any students not imported should be marked as deactivated * TODO: Any students not imported should be marked as deactivated
*/ */
'students.loadCsv'(csv, type, test) { async 'students.loadCsv'(csv, type, test) {
try { try {
if (Roles.userIsInRole(Meteor.userId(), "admin", {anyScope: true})) { if (Roles.userIsInRole(Meteor.userId(), "admin", {anyScope: true})) {
check(csv, String) check(csv, String)
let sites = Sites.find().fetch() let sites = await Sites.find().fetchAsync()
let sitesByExternalId = {} let sitesByExternalId = {}
// Map all sites by external ID so we can quickly find the site for each imported student. // Map all sites by external ID so we can quickly find the site for each imported student.
@@ -95,7 +95,7 @@ if (Meteor.isServer) {
sitesByExternalId[site.externalId] = site sitesByExternalId[site.externalId] = site
//Note: Only include active students since we don't want to repeatedly make students non-active (resetting the timestamp). //Note: Only include active students since we don't want to repeatedly make students non-active (resetting the timestamp).
let existingStudents = Students.find({active: true}).fetch() let existingStudents = await Students.find({active: true}).fetchAsync()
let existingStudentIds = new Set() let existingStudentIds = new Set()
// Collect all pre-existing student ID's. Will remove them as we import, and use the remaining set to de-activate the students no longer in the district. // Collect all pre-existing student ID's. Will remove them as we import, and use the remaining set to de-activate the students no longer in the district.
@@ -144,7 +144,7 @@ if (Meteor.isServer) {
* @param test * @param test
* @returns {string} * @returns {string}
*/ */
const readCsv = (err, records, sitesByExternalId, existingStudentIds, test) => { const readCsv = async (err, records, sitesByExternalId, existingStudentIds, test) => {
let output = "" let output = ""
if (err) console.error(err) if (err) console.error(err)
@@ -189,7 +189,7 @@ if (Meteor.isServer) {
if (!test) { if (!test) {
try { try {
existingStudentIds.delete(student.id) existingStudentIds.delete(student.id)
Students.upsert({id: student.id}, {$set: student}) await Students.upsertAsync({id: student.id}, {$set: student})
} catch (err) { } catch (err) {
console.log("Error while calling Students.upsert(..)") console.log("Error while calling Students.upsert(..)")
console.error(err) console.error(err)
@@ -212,10 +212,10 @@ if (Meteor.isServer) {
nonActiveCount++ nonActiveCount++
if (test) { if (test) {
output += "Changing active status for student: " + Students.findOne({id: studentId}) + "\r\n" output += "Changing active status for student: " + await Students.findOneAsync({id: studentId}) + "\r\n"
} else { } else {
try { try {
Students.update({id: studentId}, { await Students.updateAsync({id: studentId}, {
$set: { $set: {
active: false, active: false,
activeChangeTimestamp: new Date() activeChangeTimestamp: new Date()
@@ -238,5 +238,4 @@ if (Meteor.isServer) {
return output return output
} }
} }

View File

@@ -46,7 +46,7 @@ if (Meteor.isServer) {
}); });
Meteor.methods({ Meteor.methods({
'users.setUserRoles'(userId, roles) { async 'users.setUserRoles'(userId, roles) {
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
check(userId, String); check(userId, String);
check(roles, Array); check(roles, Array);

View File

@@ -25,7 +25,7 @@ if(Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'workshops.add'(name, description, signupLimit) { async 'workshops.add'(name, description, signupLimit) {
let signupSheet = []; let signupSheet = [];
console.log(name) console.log(name)
@@ -40,10 +40,10 @@ Meteor.methods({
})) }))
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Workshops.insert({name, description, signupLimit, signupSheet}); await Workshops.insertAsync({name, description, signupLimit, signupSheet});
} }
}, },
'workshops.update'(_id, name, description, signupLimit) { async 'workshops.update'(_id, name, description, signupLimit) {
check(_id, String); check(_id, String);
check(name, String); check(name, String);
check(description, String); check(description, String);
@@ -54,45 +54,45 @@ Meteor.methods({
})) }))
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Workshops.update({_id}, {$set: {name, description, signupLimit}}); await Workshops.updateAsync({_id}, {$set: {name, description, signupLimit}});
} }
}, },
'workshops.signup'(_id) { async 'workshops.signup'(_id) {
check(_id, String); check(_id, String);
if(Meteor.userId()) { if(Meteor.userId()) {
let workshop = Workshops.findOne(_id); let workshop = await Workshops.findOneAsync(_id);
if(workshop) { if(workshop) {
if(!workshop.signupLimit || workshop.signedUp.length < workshop.signupLimit) { if(!workshop.signupLimit || workshop.signedUp.length < workshop.signupLimit) {
Workshops.update({_id}, {$push: {signupSheet: {_id: Meteor.userId()}}}); await Workshops.updateAsync({_id}, {$push: {signupSheet: {_id: Meteor.userId()}}});
} }
} }
} }
}, },
'workshops.unsignup'(_id) { async 'workshops.unsignup'(_id) {
check(_id, String); check(_id, String);
if(Meteor.userId()) { if(Meteor.userId()) {
let workshop = Workshops.findOne(_id); let workshop = await Workshops.findOneAsync(_id);
if(workshop) { if(workshop) {
Workshops.update({_id}, {$pull: {signupSheet: {_id: Meteor.userId()}}}); await Workshops.updateAsync({_id}, {$pull: {signupSheet: {_id: Meteor.userId()}}});
} }
} }
}, },
'workshops.complete'(_id) { async 'workshops.complete'(_id) {
check(_id, String); check(_id, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Workshops.update({_id}, {$set: {isComplete: true}}) await Workshops.updateAsync({_id}, {$set: {isComplete: true}})
} }
}, },
'workshops.remove'(_id) { async 'workshops.remove'(_id) {
check(_id, String); check(_id, String);
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
Workshops.remove({_id}) await Workshops.removeAsync({_id})
} }
}, },
}); });

View File

@@ -24,22 +24,22 @@ if(Meteor.isServer) {
let watchForAdmin = false; let watchForAdmin = false;
//Setup the roles. //Setup the roles.
Roles.createRole('admin', {unlessExists: true}); await Roles.createRoleAsync('admin', {unlessExists: true});
Roles.createRole('laptop-management', {unlessExists: true}); await Roles.createRoleAsync('laptop-management', {unlessExists: true});
Roles.addRolesToParent('laptop-management', 'admin', {unlessExists: true}); await Roles.addRolesToParentAsync('laptop-management', 'admin', {unlessExists: true});
//Roles.addUsersToRoles("zwbMiaSKHix4bWQ8d", 'admin', 'global', {unlessExists: true}); //Roles.addUsersToRoles("zwbMiaSKHix4bWQ8d", 'admin', 'global', {unlessExists: true});
// If we are passed an email address that should be admin by default, then ensure that user is admin, or mark it as needing to be admin if the user ever logs in. // If we are passed an email address that should be admin by default, then ensure that user is admin, or mark it as needing to be admin if the user ever logs in.
// Given that this app requires Google OAuth2, and we expect logins to be restricted to district email addresses, this should be very secure. // Given that this app requires Google OAuth2, and we expect logins to be restricted to district email addresses, this should be very secure.
if(adminEmail) { if(adminEmail) {
let user = Meteor.users.findOne({"services.google.email": adminEmail}); let user = await Meteor.users.findOneAsync({"services.google.email": adminEmail});
if(user) { if(user) {
let assignment = Meteor.roleAssignment.findOne({'user._id': user._id, "role._id": "admin"}); let assignment = await Meteor.roleAssignment.findOneAsync({'user._id': user._id, "role._id": "admin"});
// console.log("Admin Role Assignment: " + JSON.stringify(assignment)); // console.log("Admin Role Assignment: " + JSON.stringify(assignment));
if(!assignment) { if(!assignment) {
Roles.addUsersToRoles(user._id, ['admin']); await Roles.addUsersToRolesAsync(user._id, ['admin']);
} }
} }
else { else {
@@ -50,7 +50,7 @@ if(Meteor.isServer) {
// Listen for users logging in so we can setup the admin user automatically once they log in the first time. // Listen for users logging in so we can setup the admin user automatically once they log in the first time.
if(watchForAdmin) { if(watchForAdmin) {
// TODO: It would be nice to remove this handler after the admin user is found, but the docs are pretty ambiguous about how to do that. Not a big deal, just annoying. // TODO: It would be nice to remove this handler after the admin user is found, but the docs are pretty ambiguous about how to do that. Not a big deal, just annoying.
Accounts.onLogin(function (data) { Accounts.onLogin(async function (data) {
// console.log("User logged in:"); // console.log("User logged in:");
// console.log(data.user.services.google.email); // console.log(data.user.services.google.email);
@@ -60,7 +60,7 @@ if(Meteor.isServer) {
if (watchForAdmin) { if (watchForAdmin) {
try { try {
if (data.user.services.google.email === adminEmail) { if (data.user.services.google.email === adminEmail) {
Roles.addUsersToRoles(data.user._id, ['admin']); await Roles.addUsersToRolesAsync(data.user._id, ['admin']);
watchForAdmin = false; watchForAdmin = false;
} }
} catch (err) { } catch (err) {

View File

@@ -38,13 +38,13 @@ const AssetTypeEditor = ({value, close}) => {
const [name, setName] = useState(value.name || "") const [name, setName] = useState(value.name || "")
const [description, setDescription] = useState(value.description || "") const [description, setDescription] = useState(value.description || "")
const applyChanges = () => { const applyChanges = async () => {
close() close()
//TODO Should invert this and only close if there was success on the server. //TODO Should invert this and only close if there was success on the server.
if(value._id) if(value._id)
Meteor.call("assetTypes.update", value._id, name, description, year); await Meteor.callAsync("assetTypes.update", value._id, name, description, year);
else else
Meteor.call("assetTypes.add", name, description, year); await Meteor.callAsync("assetTypes.add", name, description, year);
} }
const rejectChanges = () => { const rejectChanges = () => {
close() close()
@@ -69,8 +69,8 @@ const AssetTypeEditor = ({value, close}) => {
export default () => { export default () => {
Meteor.subscribe('assetTypes'); Meteor.subscribe('assetTypes');
const {assetTypes} = useTracker(() => { const {assetTypes} = useTracker(async () => {
let assetTypes = AssetTypes.find().fetch(); let assetTypes = await AssetTypes.find().fetchAsync();
return {assetTypes} return {assetTypes}
}); });

View File

@@ -30,13 +30,13 @@ const SiteEditor = ({value, close}) => {
const [name, setName] = useState(value.name || "") const [name, setName] = useState(value.name || "")
const [externalId, setExternalId] = useState(value.externalId || "") const [externalId, setExternalId] = useState(value.externalId || "")
const applyChanges = () => { const applyChanges = async () => {
close() close()
//TODO Should invert this and only close if there was success on the server. //TODO Should invert this and only close if there was success on the server.
if(value._id) if(value._id)
Meteor.call("sites.update", value._id, name, externalId); await Meteor.callAsync("sites.update", value._id, name, externalId);
else else
Meteor.call("sites.add", name, externalId); await Meteor.callAsync("sites.add", name, externalId);
} }
const rejectChanges = () => { const rejectChanges = () => {
close() close()
@@ -58,8 +58,8 @@ const SiteEditor = ({value, close}) => {
export default () => { export default () => {
Meteor.subscribe('sites'); Meteor.subscribe('sites');
const {sites} = useTracker(() => { const {sites} = useTracker(async () => {
const sites = Sites.find({}).fetch(); const sites = await Sites.find({}).fetchAsync();
return { return {
sites sites
} }

View File

@@ -42,8 +42,8 @@ const StaffEditor = ({value, close, defaultSiteId}) => {
const [lastName, setLastName] = useState(value.lastName || "") const [lastName, setLastName] = useState(value.lastName || "")
const [siteId, setSiteId] = useState(value.siteId ? value.siteId : defaultSiteId) const [siteId, setSiteId] = useState(value.siteId ? value.siteId : defaultSiteId)
const {sites} = useTracker(() => { const {sites} = useTracker(async () => {
let sites = Sites.find({}).fetch(); let sites = await Sites.find({}).fetchAsync();
return {sites} return {sites}
}); });
@@ -52,13 +52,13 @@ const StaffEditor = ({value, close, defaultSiteId}) => {
setSiteId(sites[0]._id) setSiteId(sites[0]._id)
} }
const applyChanges = () => { const applyChanges = async () => {
close() close()
//TODO Should invert this and only close if there was success on the server. //TODO Should invert this and only close if there was success on the server.
if(value._id) if(value._id)
Meteor.call("staff.update", value._id, id, firstName, lastName, email, siteId); await Meteor.callAsync("staff.update", value._id, id, firstName, lastName, email, siteId);
else else
Meteor.call("staff.add", id, firstName, lastName, email, siteId); await Meteor.callAsync("staff.add", id, firstName, lastName, email, siteId);
} }
const rejectChanges = () => { const rejectChanges = () => {
close() close()
@@ -94,17 +94,17 @@ export default () => {
Meteor.subscribe('sites'); Meteor.subscribe('sites');
Meteor.subscribe('staff'); Meteor.subscribe('staff');
const {sites} = useTracker(() => { const {sites} = useTracker(async () => {
const sites = Sites.find({}).fetch(); const sites = await Sites.find({}).fetchAsync();
sites.push(siteAll); sites.push(siteAll);
return {sites} return {sites}
}); });
const {staff} = useTracker(() => { const {staff} = useTracker(async () => {
const staffQuery = site === siteAll._id ? {} : {siteId: site} const staffQuery = site === siteAll._id ? {} : {siteId: site}
let staff = Staff.find(staffQuery).fetch(); let staff = await Staff.find(staffQuery).fetchAsync();
return {staff} return {staff}
}); });

View File

@@ -56,8 +56,8 @@ const StudentEditor = ({value, close, defaultSiteId}) => {
const [active, setActive] = useState(value.active) const [active, setActive] = useState(value.active)
const [siteId, setSiteId] = useState(value.siteId ? value.siteId : defaultSiteId) const [siteId, setSiteId] = useState(value.siteId ? value.siteId : defaultSiteId)
const {sites} = useTracker(() => { const {sites} = useTracker(async () => {
let sites = Sites.find({}).fetch(); let sites = await Sites.find({}).fetch();
return {sites} return {sites}
}); });
@@ -66,13 +66,13 @@ const StudentEditor = ({value, close, defaultSiteId}) => {
setSiteId(sites[0]._id) setSiteId(sites[0]._id)
} }
const applyChanges = () => { const applyChanges = async () => {
close() close()
//TODO Should invert this and only close if there was success on the server. //TODO Should invert this and only close if there was success on the server.
if(value._id) if(value._id)
Meteor.call("students.update", value._id, id, firstName, firstNameAlias, lastName, email, siteId, grade, active); await Meteor.callAsync("students.update", value._id, id, firstName, firstNameAlias, lastName, email, siteId, grade, active);
else else
Meteor.call("students.add", id, firstName, firstNameAlias, lastName, email, siteId, grade, active); await Meteor.callAsync("students.add", id, firstName, firstNameAlias, lastName, email, siteId, grade, active);
} }
const rejectChanges = () => { const rejectChanges = () => {
close() close()
@@ -110,8 +110,8 @@ export default () => {
Meteor.subscribe('sites'); Meteor.subscribe('sites');
Meteor.subscribe('students'); Meteor.subscribe('students');
const {sites} = useTracker(() => { const {sites} = useTracker(async () => {
const sites = Sites.find({}).fetch(); const sites = await Sites.find({}).fetchAsync();
sites.push(siteAll); sites.push(siteAll);
@@ -124,7 +124,7 @@ export default () => {
const [active, setActive] = useState(ACTIVE_BOTH) const [active, setActive] = useState(ACTIVE_BOTH)
const [nameSearch, setNameSearch] = useState("") const [nameSearch, setNameSearch] = useState("")
const {students} = useTracker(() => { const {students} = useTracker(async () => {
const studentQuery = site === siteAll._id ? {} : {siteId: site} const studentQuery = site === siteAll._id ? {} : {siteId: site}
if(active !== ACTIVE_BOTH) { if(active !== ACTIVE_BOTH) {
@@ -135,7 +135,7 @@ export default () => {
studentQuery["$or"] = [{firstName: {$regex: nameSearch, $options: 'i'}}, {firstNameAlias: {$regex: nameSearch, $options: 'i'}}, {lastName: {$regex: nameSearch, $options: 'i'}}] studentQuery["$or"] = [{firstName: {$regex: nameSearch, $options: 'i'}}, {firstNameAlias: {$regex: nameSearch, $options: 'i'}}, {lastName: {$regex: nameSearch, $options: 'i'}}]
} }
let students = Students.find(studentQuery).fetch(); let students = await Students.find(studentQuery).fetchAsync();
return {students} return {students}
}); });

View File

@@ -53,9 +53,9 @@ const AddAssets = ({assetTypes}) => {
backgroundColor: selectedAssetType === assetType ? '#EECFA6' : 'white' backgroundColor: selectedAssetType === assetType ? '#EECFA6' : 'white'
} }
} }
const addAsset = () => { const addAsset = async () => {
//TODO: Check the inputs. //TODO: Check the inputs.
Meteor.call("assets.add", selectedAssetType._id, assetId, serial, condition, conditionDetails); await Meteor.callAsync("assets.add", selectedAssetType._id, assetId, serial, condition, conditionDetails);
setAssetId("") setAssetId("")
setSerial("") setSerial("")
} }
@@ -122,8 +122,8 @@ const AddAssets = ({assetTypes}) => {
export default () => { export default () => {
Meteor.subscribe('assetTypes'); Meteor.subscribe('assetTypes');
const {assetTypes} = useTracker(() => { const {assetTypes} = useTracker(async () => {
const assetTypes = AssetTypes.find({}, {sort: {year: -1}}).fetch(); const assetTypes = await AssetTypes.find({}, {sort: {year: -1}}).fetchAsync();
return { return {
assetTypes assetTypes

View File

@@ -44,13 +44,13 @@ const AssetEditor = ({value, close}) => {
const [assetTypeId, setAssetTypeId] = useState(value.assetTypeId || "") const [assetTypeId, setAssetTypeId] = useState(value.assetTypeId || "")
const assetTypes = AssetTypes.find({}, {sort: {year: -1}}); const assetTypes = AssetTypes.find({}, {sort: {year: -1}});
const applyChanges = () => { const applyChanges = async () => {
close() close()
//TODO Should invert this and only close if there was success on the server. //TODO Should invert this and only close if there was success on the server.
if(value._id) if(value._id)
Meteor.call("assets.update", value._id, assetTypeId, assetId, serial, condition, conditionDetails); await Meteor.callAsync("assets.update", value._id, assetTypeId, assetId, serial, condition, conditionDetails);
else else
Meteor.call("assets.add", assetTypeId, assetId, serial, condition, conditionDetails); await Meteor.callAsync("assets.add", assetTypeId, assetId, serial, condition, conditionDetails);
} }
const rejectChanges = () => { const rejectChanges = () => {
close() close()
@@ -93,15 +93,15 @@ export default () => {
const assetTypes = [{name: "All", _id: 0}, ...AssetTypes.find({}, {sort: {year: -1}}).fetch()] const assetTypes = [{name: "All", _id: 0}, ...AssetTypes.find({}, {sort: {year: -1}}).fetch()]
const {assets} = useTracker(() => { const {assets} = useTracker(async () => {
let query = {} let query = {}
if(assetId) query.assetId = {$regex: assetId, $options: 'i'} if(assetId) query.assetId = {$regex: assetId, $options: 'i'}
if(serial) query.serial = {$regex: serial, $options: 'i'} if(serial) query.serial = {$regex: serial, $options: 'i'}
if(assetTypeId) query.assetTypeId = assetTypeId if(assetTypeId) query.assetTypeId = assetTypeId
const assets = Assets.find(query).fetch(); const assets = await Assets.find(query).fetchAsync();
const assetTypes = AssetTypes.find({}, {sort: {year: -1}}).fetch(); const assetTypes = await AssetTypes.find({}, {sort: {year: -1}}).fetchAsync();
const assetTypeNameMap = assetTypes.reduce((map, obj) => { const assetTypeNameMap = assetTypes.reduce((map, obj) => {
map[obj._id] = obj; map[obj._id] = obj;
return map; return map;
@@ -170,8 +170,8 @@ export default () => {
maxHeight: '40rem' maxHeight: '40rem'
} }
const removeAsset = (asset) => { const removeAsset = async (asset) => {
Meteor.call("assets.remove", asset._id); await Meteor.callAsync("assets.remove", asset._id);
setRemoveRow(undefined) setRemoveRow(undefined)
} }

View File

@@ -59,17 +59,17 @@ const AssignmentsByAsset = () => {
const [assetIdInput, setAssetIdInput] = useState(undefined) const [assetIdInput, setAssetIdInput] = useState(undefined)
const {foundAsset} = useTracker(() => { const {foundAsset} = useTracker(async () => {
let foundAsset = null; let foundAsset = null;
if(assetId) { if(assetId) {
foundAsset = Assets.findOne({assetId: assetId}); foundAsset = await Assets.findOneAsync({assetId: assetId});
if(foundAsset) { if(foundAsset) {
foundAsset.assetType = AssetTypes.findOne({_id: foundAsset.assetTypeId}) foundAsset.assetType = await AssetTypes.findOneAsync({_id: foundAsset.assetTypeId})
if(foundAsset.assigneeId) if(foundAsset.assigneeId)
foundAsset.assignee = foundAsset.assigneeType === "Student" ? Students.findOne({_id: foundAsset.assigneeId}) : Staff.findOne({_id: foundAsset.assigneeId}) foundAsset.assignee = foundAsset.assigneeType === "Student" ? await Students.findOneAsync({_id: foundAsset.assigneeId}) : await Staff.findOneAsync({_id: foundAsset.assigneeId})
} }
} }
@@ -99,7 +99,7 @@ const AssignmentsByAsset = () => {
const [assignmentData, setAssignmentData] = useState([]) const [assignmentData, setAssignmentData] = useState([])
// Collect the usage and assignment data when the selected person changes. // Collect the usage and assignment data when the selected person changes.
useEffect(() => { useEffect(async () => {
try { try {
if(foundAsset) { if(foundAsset) {
let query = {assetId: foundAsset.assetId} let query = {assetId: foundAsset.assetId}
@@ -107,11 +107,11 @@ const AssignmentsByAsset = () => {
console.log("Requesting asset historical data") console.log("Requesting asset historical data")
console.log(query) console.log(query)
Meteor.call('DataCollection.chromebookData', query, (err, result) => { await Meteor.callAsync('DataCollection.chromebookData', query, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setUsageData(result) else setUsageData(result)
}) })
Meteor.call('AssetAssignmentHistory.get', query, (err, result) => { await Meteor.callAsync('AssetAssignmentHistory.get', query, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setAssignmentData(result) else setAssignmentData(result)
}) })
@@ -149,19 +149,19 @@ const AssignmentsByAsset = () => {
setUnassignConditionDetails(foundAsset.conditionDetails || "") setUnassignConditionDetails(foundAsset.conditionDetails || "")
setOpenUnassignDialog(true); setOpenUnassignDialog(true);
} }
const unassignDialogClosed = (unassign) => { const unassignDialogClosed = async (unassign) => {
setOpenUnassignDialog(false) setOpenUnassignDialog(false)
if(unassign === true) { if(unassign === true) {
if(unassignDialogEditConditionOnly) { if(unassignDialogEditConditionOnly) {
Meteor.call('assets.updateCondition', foundAsset._id, unassignCondition, unassignConditionDetails, (err, result) => { await Meteor.callAsync('assets.updateCondition', foundAsset._id, unassignCondition, unassignConditionDetails, (err, result) => {
if(err) console.error(err) if(err) console.error(err)
else if(assetIdInput) assetIdInput.focus() else if(assetIdInput) assetIdInput.focus()
}) })
} }
else { else {
// Call assets.unassign(assetId, comment, condition, conditionDetails, date) // Call assets.unassign(assetId, comment, condition, conditionDetails, date)
Meteor.call('assets.unassign', foundAsset.assetId, unassignComment, unassignCondition, unassignConditionDetails, (err, result) => { await Meteor.callAsync('assets.unassign', foundAsset.assetId, unassignComment, unassignCondition, unassignConditionDetails, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else if (assetIdInput) assetIdInput.focus() else if (assetIdInput) assetIdInput.focus()
}) })

View File

@@ -62,7 +62,7 @@ const AssignmentsByPerson = () => {
const [searchInput, setSearchInput] = useState(undefined) const [searchInput, setSearchInput] = useState(undefined)
const {people} = useTracker(() => { const {people} = useTracker(async () => {
let people = []; let people = [];
if(search && search.length > 1) { if(search && search.length > 1) {
@@ -80,8 +80,8 @@ const AssignmentsByPerson = () => {
// Look for students/staff that are active or whose active flag is not set. // Look for students/staff that are active or whose active flag is not set.
if(!includeInactive) query = {$and: [query, {$or: [{active: true}, {active: {$exists: false}}]}]} if(!includeInactive) query = {$and: [query, {$or: [{active: true}, {active: {$exists: false}}]}]}
const students = Students.find(query).fetch(); const students = await Students.find(query).fetchAsync();
const staff = Staff.find(query).fetch(); const staff = await Staff.find(query).fetchAsync();
for(let next of students) next.type = "Student" for(let next of students) next.type = "Student"
for(let next of staff) next.type = "Staff" for(let next of staff) next.type = "Staff"
@@ -92,11 +92,11 @@ const AssignmentsByPerson = () => {
return {people} return {people}
}, [search]); }, [search]);
const {assets} = useTracker(() => { const {assets} = useTracker(async () => {
let assets = []; let assets = [];
if(selectedPerson) { if(selectedPerson) {
assets = Assets.find({assigneeId: selectedPerson._id}).fetch(); assets = await Assets.find({assigneeId: selectedPerson._id}).fetchAsync();
for(let next of assets) { for(let next of assets) {
next.assetType = AssetTypes.findOne({_id: next.assetTypeId}) next.assetType = AssetTypes.findOne({_id: next.assetTypeId})
@@ -106,17 +106,17 @@ const AssignmentsByPerson = () => {
return {assets} return {assets}
}, [selectedPerson]); }, [selectedPerson]);
const {foundAsset} = useTracker(() => { const {foundAsset} = useTracker(async () => {
let foundAsset = null; let foundAsset = null;
if(assetId) { if(assetId) {
foundAsset = Assets.findOne({assetId: assetId}); foundAsset = await Assets.findOneAsync({assetId: assetId});
if(foundAsset) { if(foundAsset) {
foundAsset.assetType = AssetTypes.findOne({_id: foundAsset.assetTypeId}) foundAsset.assetType = await AssetTypes.findOneAsync({_id: foundAsset.assetTypeId})
if(foundAsset.assigneeId) if(foundAsset.assigneeId)
foundAsset.assignee = foundAsset.assigneeType === "Student" ? Students.findOne({_id: foundAsset.assigneeId}) : Staff.findOne({_id: foundAsset.assigneeId}) foundAsset.assignee = foundAsset.assigneeType === "Student" ? await Students.findOneAsync({_id: foundAsset.assigneeId}) : await Staff.findOneAsync({_id: foundAsset.assigneeId})
} }
} }
@@ -127,7 +127,7 @@ const AssignmentsByPerson = () => {
const [assignmentData, setAssignmentData] = useState([]) const [assignmentData, setAssignmentData] = useState([])
// Collect the usage and assignment data when the selected person changes. // Collect the usage and assignment data when the selected person changes.
useEffect(() => { useEffect(async () => {
try { try {
if(selectedPerson) { if(selectedPerson) {
let query = selectedPerson.type === "Student" ? {studentId: selectedPerson._id} : {staffId: selectedPerson._id} let query = selectedPerson.type === "Student" ? {studentId: selectedPerson._id} : {staffId: selectedPerson._id}
@@ -135,11 +135,11 @@ const AssignmentsByPerson = () => {
console.log("Collecting person history") console.log("Collecting person history")
console.log(query) console.log(query)
Meteor.call('DataCollection.chromebookData', query, (err, result) => { await Meteor.callAsync('DataCollection.chromebookData', query, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setUsageData(result) else setUsageData(result)
}) })
Meteor.call('AssetAssignmentHistory.get', query, (err, result) => { await Meteor.callAsync('AssetAssignmentHistory.get', query, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setAssignmentData(result) else setAssignmentData(result)
}) })
@@ -161,12 +161,12 @@ const AssignmentsByPerson = () => {
setOpenAssignDialog(true) setOpenAssignDialog(true)
} }
} }
const assignDialogClosed = (assign) => { const assignDialogClosed = async (assign) => {
setOpenAssignDialog(false) setOpenAssignDialog(false)
if(assign === true) { if(assign === true) {
// Call assets.assign // Call assets.assign
Meteor.call('assets.assign', foundAsset.assetId, selectedPerson.type, selectedPerson._id, assignCondition, assignConditionDetails, (err, result) => { await Meteor.callAsync('assets.assign', foundAsset.assetId, selectedPerson.type, selectedPerson._id, assignCondition, assignConditionDetails, (err, result) => {
if(err) console.error(err) if(err) console.error(err)
else { else {
// Clear the asset id field and set focus to it. // Clear the asset id field and set focus to it.
@@ -193,19 +193,19 @@ const AssignmentsByPerson = () => {
setUnassignConditionDetails(asset.conditionDetails || "") setUnassignConditionDetails(asset.conditionDetails || "")
setOpenUnassignDialog(true); setOpenUnassignDialog(true);
} }
const unassignDialogClosed = (unassign) => { const unassignDialogClosed = async (unassign) => {
setOpenUnassignDialog(false) setOpenUnassignDialog(false)
if(unassign === true) { if(unassign === true) {
if(unassignDialogEditConditionOnly) { if(unassignDialogEditConditionOnly) {
Meteor.call('assets.updateCondition', unassignAsset._id, unassignCondition, unassignConditionDetails, (err, result) => { await Meteor.callAsync('assets.updateCondition', unassignAsset._id, unassignCondition, unassignConditionDetails, (err, result) => {
if(err) console.error(err) if(err) console.error(err)
else if(assetIdInput) assetIdInput.focus() else if(assetIdInput) assetIdInput.focus()
}) })
} }
else { else {
// Call assets.unassign(assetId, comment, condition, conditionDetails, date) // Call assets.unassign(assetId, comment, condition, conditionDetails, date)
Meteor.call('assets.unassign', unassignAsset.assetId, unassignComment, unassignCondition, unassignConditionDetails, (err, result) => { await Meteor.callAsync('assets.unassign', unassignAsset.assetId, unassignComment, unassignCondition, unassignConditionDetails, (err, result) => {
if(err) console.error(err) if(err) console.error(err)
else if(assetIdInput) assetIdInput.focus() else if(assetIdInput) assetIdInput.focus()
}) })
@@ -322,7 +322,7 @@ const AssignmentsByPerson = () => {
})} })}
</TextField> </TextField>
</div> </div>
<TextField style={{marginTop: '1rem',minWidth: '30rem'}} multiline rows={4} variant="outlined" label="Condition Details" value={assignConditionDetails} onChange={(e) => {setAssignConditionDetails(e.target.value)}}/> <TextField style={{marginTop: '1rem',minWidth: '30rem'}} multiline rows={4} variant="outlined" label="Condition Details" value={assignConditionDetails} onChange={(e,v) => {setAssignConditionDetails(v)}}/>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={() => assignDialogClosed(true)}>Assign</Button> <Button onClick={() => assignDialogClosed(true)}>Assign</Button>

View File

@@ -16,10 +16,10 @@ import Button from "@mui/material/Button";
const AssignmentsReport = () => { const AssignmentsReport = () => {
const theme = useTheme(); const theme = useTheme();
const {people} = useTracker(() => { const {people} = useTracker(async () => {
let assets = Assets.find({assigneeId: {$exists: true}, assigneeType: "Student"}).fetch() let assets = await Assets.find({assigneeId: {$exists: true}, assigneeType: "Student"}).fetchAsync()
let assetTypes = AssetTypes.find().fetch() let assetTypes = await AssetTypes.find().fetchAsync()
let students = Students.find().fetch() let students = await Students.find().fetchAsync()
let people = [] let people = []
let assetTypesById = assetTypes.reduce((map, obj) => {map[obj._id] = obj; return map}, {}) let assetTypesById = assetTypes.reduce((map, obj) => {map[obj._id] = obj; return map}, {})

View File

@@ -33,12 +33,12 @@ export default () => {
const [searchType, setSearchType] = useState("email") const [searchType, setSearchType] = useState("email")
const [value, setValue] = useState("") const [value, setValue] = useState("")
const search = () => { const search = async () => {
if(searchType === 'email' || searchType === 'firstName' || searchType === 'lastName') { if(searchType === 'email' || searchType === 'firstName' || searchType === 'lastName') {
if (value && value.length > 1) { if (value && value.length > 1) {
let query = searchType === 'email' ? {email: {$regex: value, $options: 'i'}} : searchType === 'firstName' ? {firstName: {$regex: value, $options: 'i'}} : {lastName: {$regex: value, $options: 'i'}} let query = searchType === 'email' ? {email: {$regex: value, $options: 'i'}} : searchType === 'firstName' ? {firstName: {$regex: value, $options: 'i'}} : {lastName: {$regex: value, $options: 'i'}}
let students = Students.find(query).fetch() let students = await Students.find(query).fetchAsync()
let staff = Staff.find(query).fetch() let staff = await Staff.find(query).fetchAsync()
let all = [...staff, ...students] let all = [...staff, ...students]
if (all.length > 1) { if (all.length > 1) {
@@ -50,7 +50,7 @@ export default () => {
} }
} }
else if(searchType === 'assetId' || searchType === 'serial') { else if(searchType === 'assetId' || searchType === 'serial') {
let asset = Assets.findOne(searchType === 'assetId' ? {assetId: value.toUpperCase()} : {serial : value}); let asset = await Assets.findOneAsync(searchType === 'assetId' ? {assetId: value.toUpperCase()} : {serial : value});
console.log(asset) console.log(asset)
if(asset) { if(asset) {
if(searchType === 'assetId') if(searchType === 'assetId')
@@ -102,7 +102,7 @@ export default () => {
</Dialog> </Dialog>
<div style={{display: "flex", flexDirection: "column", marginTop: "1rem"}} sx={{ p: '2px 4px', display: 'flex', alignItems: 'center', width: 400 }}> <div style={{display: "flex", flexDirection: "column", marginTop: "1rem"}} sx={{ p: '2px 4px', display: 'flex', alignItems: 'center', width: 400 }}>
{/*<Paper componet='form'>*/} {/*<Paper component='form'>*/}
{/* <div style={{marginBottom: "1rem", marginTop: "2rem"}}>*/} {/* <div style={{marginBottom: "1rem", marginTop: "2rem"}}>*/}
{/* <ToggleButtonGroup color="primary" value={resultType} exclusive onChange={(e, type)=>setResultType(type)} aria-label="Result Type">*/} {/* <ToggleButtonGroup color="primary" value={resultType} exclusive onChange={(e, type)=>setResultType(type)} aria-label="Result Type">*/}
{/* <ToggleButton value="usage">Usage History</ToggleButton>*/} {/* <ToggleButton value="usage">Usage History</ToggleButton>*/}

View File

@@ -31,10 +31,10 @@ import {InputLabel, List, ListItem, ListItemButton, ListItemText} from "@mui/mat
export default () => { export default () => {
const navigate = useNavigate() const navigate = useNavigate()
const [value, setValue] = useState("") const [value, setValue] = useState("")
const search = () => { const search = async () => {
if(value && value.length > 1) { if(value && value.length > 1) {
let students = Students.find({email: {$regex: value, $options: 'i'}}).fetch() let students = await Students.find({email: {$regex: value, $options: 'i'}}).fetchAsync()
let staff = Staff.find({email: {$regex: value, $options: 'i'}}).fetch() let staff = await Staff.find({email: {$regex: value, $options: 'i'}}).fetchAsync()
let all = [...staff, ...students] let all = [...staff, ...students]
if(all.length > 1) { if(all.length > 1) {

View File

@@ -31,15 +31,15 @@ const cssEditorField = {
minWidth: '10rem' minWidth: '10rem'
} }
const Statistics = () => { const Statistics = async () => {
const [selectedMissingAsset, setSelectedMissingAsset] = useState("") const [selectedMissingAsset, setSelectedMissingAsset] = useState("")
const {assetStatistics} = useTracker(() => { const {assetStatistics} = useTracker(async () => {
let assetStatistics = [] let assetStatistics = []
const assetTypes = AssetTypes.find({}, {year: 1}).fetch() const assetTypes = await AssetTypes.find({}, {year: 1}).fetchAsync()
for(let type of assetTypes) { for(let type of assetTypes) {
let count = Assets.find({assetTypeId: type._id, condition: {$in: functionalConditions}}).count() let count = await Assets.find({assetTypeId: type._id, condition: {$in: functionalConditions}}).countAsync()
if(count > 0) { if(count > 0) {
assetStatistics.push({name: type.name, count}) assetStatistics.push({name: type.name, count})
@@ -49,13 +49,13 @@ const Statistics = () => {
return {assetStatistics} return {assetStatistics}
}) })
const {missingAssets} = useTracker(() => { const {missingAssets} = useTracker(async () => {
let missingAssets = []; let missingAssets = [];
missingAssets = Assets.find({condition: 'Missing'}).fetch(); missingAssets = await Assets.find({condition: 'Missing'}).fetchAsync();
for(let next of missingAssets) { for(let next of missingAssets) {
next.assetType = AssetTypes.findOne({_id: next.assetTypeId}) next.assetType = await AssetTypes.findOneAsync({_id: next.assetTypeId})
} }
return {missingAssets} return {missingAssets}

View File

@@ -84,7 +84,7 @@ export default () => {
const [assignmentData, setAssignmentData] = useState([]) const [assignmentData, setAssignmentData] = useState([])
const [search, setSearch] = useSearchParams() const [search, setSearch] = useSearchParams()
useEffect(() => { useEffect(async () => {
let args; let args;
if(search.get('studentId')) { if(search.get('studentId')) {
@@ -106,7 +106,7 @@ export default () => {
args = {assetId: search.get('assetId')} args = {assetId: search.get('assetId')}
} }
Meteor.call('DataCollection.chromebookData', args, (err, result) => { await Meteor.callAsync('DataCollection.chromebookData', args, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setUsageData(result) else setUsageData(result)
}) })
@@ -124,7 +124,7 @@ export default () => {
// args = {assetId: search.get('assetId')} // args = {assetId: search.get('assetId')}
// } // }
Meteor.call('AssetAssignmentHistory.get', args, (err, result) => { await Meteor.callAsync('AssetAssignmentHistory.get', args, (err, result) => {
if (err) console.error(err) if (err) console.error(err)
else setAssignmentData(result) else setAssignmentData(result)
}) })

View File

@@ -42,7 +42,7 @@ export const StudentPage = (props) => {
<div style={{width: '100%', height: '100%', background: 'url(/images/student.svg)', backgroundSize: 'cover', backgroundPosition: 'center bottom', position: 'fixed', right: 0, bottom: 0, top: 0, left: 0}}> </div> <div style={{width: '100%', height: '100%', background: 'url(/images/student.svg)', backgroundSize: 'cover', backgroundPosition: 'center bottom', position: 'fixed', right: 0, bottom: 0, top: 0, left: 0}}> </div>
<div style={{display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100%', width: '100%'}}> <div style={{display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100%', width: '100%'}}>
<Button css={{height: "100%", width: '100px', margin: 'auto'}} variant="contained" className="button" onClick={performLogin}>Login</Button>*/} <Button css={{height: "100%", width: '100px', margin: 'auto'}} variant="contained" className="button" onClick={performLogin}>Login</Button>
</div> </div>
</> </>
)} )}

View File

@@ -50,15 +50,15 @@ export const WorkshopList = () => {
const isAdmin = user && Roles.userIsInRole(user._id, 'admin', 'global'); const isAdmin = user && Roles.userIsInRole(user._id, 'admin', 'global');
const [selectedWorkshop, setSelectedWorkshop] = useState("") const [selectedWorkshop, setSelectedWorkshop] = useState("")
const {workshops} = useTracker(() => { const {workshops} = useTracker(async () => {
let workshops = []; let workshops = [];
workshops = Workshops.find({isComplete: false}).fetch(); workshops = await Workshops.find({isComplete: false}).fetchAsync();
for(let workshop of workshops) { for(let workshop of workshops) {
for(let user of workshop.signupSheet) { for(let user of workshop.signupSheet) {
user.data = Students.findOne({_id: user._id}) user.data = await Students.findOneAsync({_id: user._id})
if(!user.data) user.data = Staff.findOne({_id: user._id}) if(!user.data) user.data = await Staff.findOneAsync({_id: user._id})
} }
} }
@@ -96,7 +96,7 @@ export const WorkshopList = () => {
setOpenWorkshopEditor(true) setOpenWorkshopEditor(true)
} }
} }
const workshopEditorClosed = (save) => { const workshopEditorClosed = async (save) => {
const completeHandler = (err, result) => { const completeHandler = (err, result) => {
if(err) console.error(err) if(err) console.error(err)
else { else {
@@ -105,8 +105,8 @@ export const WorkshopList = () => {
} }
if(save) { if(save) {
if(editedWorkshop._id) Meteor.call('workshops.update', editedWorkshop._id, editedName, editedDescription, editedSignupLimit, completeHandler) if(editedWorkshop._id) await Meteor.callAsync('workshops.update', editedWorkshop._id, editedName, editedDescription, editedSignupLimit, completeHandler)
else Meteor.call('workshops.add', editedName, editedDescription, editedSignupLimit, completeHandler) else await Meteor.callAsync('workshops.add', editedName, editedDescription, editedSignupLimit, completeHandler)
} }
else completeHandler() else completeHandler()
} }

View File

@@ -43,7 +43,7 @@ let UsersTable = ({rows}) => {
setPermissions({...permissions}) setPermissions({...permissions})
} }
let applyChanges = (e) => { let applyChanges = async (e) => {
let roles = []; let roles = [];
if(permissions.isAdmin) { if(permissions.isAdmin) {
@@ -55,7 +55,7 @@ let UsersTable = ({rows}) => {
} }
} }
Meteor.call("users.setUserRoles", edited._id, roles); await Meteor.callAsync("users.setUserRoles", edited._id, roles);
setEdited(undefined); setEdited(undefined);
} }

View File

@@ -11,9 +11,10 @@ if(!process.env.MONGO_URL2) {
} }
try { try {
let settings = Assets.getText('settings.json'); let settings = await Assets.getTextAsync('settings.json');
} }
catch(e) { catch(e) {
console.log(e)
console.error("Must have a /private/settings.json file with the following format:"); console.error("Must have a /private/settings.json file with the following format:");
console.error(` console.error(`
{ {

View File

@@ -7,7 +7,7 @@
console.log("Setting up Google OAuth..."); console.log("Setting up Google OAuth...");
try { try {
let settings = Assets.getText('settings.json'); let settings = await Assets.getTextAsync('settings.json');
if(settings) { if(settings) {
try { try {