Merge remote-tracking branch 'origin/master'

# Conflicts:
#	package-lock.json
This commit is contained in:
2022-08-15 13:20:23 -07:00
17 changed files with 150 additions and 39 deletions

View File

@@ -2,6 +2,8 @@ import {Meteor} from "meteor/meteor";
import { _ } from 'underscore'; import { _ } from 'underscore';
import { Roles } from 'meteor/alanning:roles'; import { Roles } from 'meteor/alanning:roles';
// console.log("Setting Up Admin...")
if (Meteor.isServer) { if (Meteor.isServer) {
Meteor.methods({ Meteor.methods({
'admin.fixRecords'(input) { 'admin.fixRecords'(input) {
@@ -54,3 +56,5 @@ if (Meteor.isServer) {
}, },
}); });
} }
// console.log("Admin setup.")

View File

@@ -0,0 +1,14 @@
import {Mongo} from "meteor/mongo";
export const AssetAssignmentHistory = new Mongo.Collection('assetAssignmentHistory');
/*
Maintains a historical record of asset assignments.
assetId: The asset's assigned ID (not a MongoID).
assigneeType: One of 'Student' or 'Staff'.
assigneeId: The MongoID of the student or staff the asset was assigned to.
startDate: The date/time of the assignment.
endDate: The date/time of the unassignment.
startCondition: TODO
endCondition: TODO
*/

View File

@@ -5,6 +5,8 @@ import { Roles } from 'meteor/alanning:roles';
//import SimpleSchema from "simpl-schema"; //import SimpleSchema from "simpl-schema";
import {AssetTypes} from "./asset-types"; import {AssetTypes} from "./asset-types";
// console.log("Setting Up Asset Assignments...")
export const AssetAssignments = new Mongo.Collection('assetAssignments'); export const AssetAssignments = new Mongo.Collection('assetAssignments');
/* /*
const TYPE_STUDENT = 1; const TYPE_STUDENT = 1;
@@ -42,8 +44,8 @@ if (Meteor.isServer) {
//try {AssetAssignments._dropIndex("name")} catch(e) {} //try {AssetAssignments._dropIndex("name")} catch(e) {}
//AssetAssignments.createIndex({name: "text"}, {name: "name", unique: false}); //AssetAssignments.createIndex({name: "text"}, {name: "name", unique: false});
try {AssetTypes._dropIndex("AssetID")} catch(e) {} //Typo put this as an index in AssetTypes instead of AssetAssignments. //try {AssetTypes._dropIndex("AssetID")} catch(e) {} //Typo put this as an index in AssetTypes instead of AssetAssignments.
AssetAssignments.createIndex({assetId: 1}, {name: "AssetID", unique: false}); //AssetAssignments.createIndex({assetId: 1}, {name: "AssetID", unique: false});
// This code only runs on the server // This code only runs on the server
Meteor.publish('assetAssignments', function(assetId) { Meteor.publish('assetAssignments', function(assetId) {
@@ -58,11 +60,6 @@ if (Meteor.isServer) {
}); });
} }
Meteor.methods({ Meteor.methods({
'AssetAssignments.getOne'(assetId) {
check(assetId, String);
return AssetAssignments.findOne(assetId);
},
/** /**
* Assigns the asset to the assignee. The assignee should either be a Student or Staff member. * Assigns the asset to the assignee. The assignee should either be a Student or Staff member.
* @param assetId The Mongo ID of the asset (asset._id). * @param assetId The Mongo ID of the asset (asset._id).
@@ -92,3 +89,4 @@ Meteor.methods({
}, },
}); });
// console.log("Asset assignments setup.")

View File

@@ -4,6 +4,8 @@ import { check } from 'meteor/check';
import { Roles } from 'meteor/alanning:roles'; import { Roles } from 'meteor/alanning:roles';
//import SimpleSchema from "simpl-schema"; //import SimpleSchema from "simpl-schema";
// console.log("Setting Up Asset Types...")
// //
// An asset type is a specific type of equipment. Example: Lenovo 100e Chromebook. // An asset type is a specific type of equipment. Example: Lenovo 100e Chromebook.
// //
@@ -74,3 +76,4 @@ Meteor.methods({
}, },
}); });
// console.log("Asset types setup.")

View File

@@ -5,6 +5,9 @@ import { Roles } from 'meteor/alanning:roles';
//import SimpleSchema from "simpl-schema"; //import SimpleSchema from "simpl-schema";
import {AssetTypes} from "./asset-types"; import {AssetTypes} from "./asset-types";
import {AssetAssignments} from "/imports/api/asset-assignments"; import {AssetAssignments} from "/imports/api/asset-assignments";
import {AssetAssignmentHistory} from "/imports/api/asset-assignment-history";
// console.log("Setting Up Assets...")
export const Assets = new Mongo.Collection('assets'); export const Assets = new Mongo.Collection('assets');
@@ -89,6 +92,7 @@ Meteor.methods({
Assets.insert({assetTypeId, assetId}); Assets.insert({assetTypeId, assetId});
} }
} }
else throw new Meteor.Error("User Permission Error");
}, },
'assets.update'(_id, assetId, serial) { 'assets.update'(_id, assetId, serial) {
check(_id, String); check(_id, String);
@@ -99,6 +103,7 @@ Meteor.methods({
//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: {assetId, serial}}); Assets.update({_id}, {$set: {assetId, serial}});
} }
else throw new Meteor.Error("User Permission Error");
}, },
'assets.remove'(_id) { 'assets.remove'(_id) {
check(_id, String); check(_id, String);
@@ -107,6 +112,7 @@ Meteor.methods({
//TODO: Ensure we have not assigned this asset??? Not sure if we should require unassigning first. //TODO: Ensure we have not assigned this asset??? Not sure if we should require unassigning first.
Assets.remove({_id}); Assets.remove({_id});
} }
else throw new Meteor.Error("User Permission Error");
}, },
/** /**
* Assigns the asset to the assignee. The assignee should either be a Student or Staff member. * Assigns the asset to the assignee. The assignee should either be a Student or Staff member.
@@ -127,8 +133,9 @@ Meteor.methods({
// Should never happen. // Should never happen.
console.error("Error: Received incorrect assignee type in adding an assignment."); console.error("Error: Received incorrect assignee type in adding an assignment.");
console.error(assigneeType); console.error(assigneeType);
throw new Meteor.Error("Error: Received incorrect assignee type in adding an assignment.");
} }
else if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { else if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
let asset = Assets.findOne({assetId}); let asset = Assets.findOne({assetId});
if(asset) { if(asset) {
@@ -145,6 +152,7 @@ Meteor.methods({
console.error("Could not find the asset: " + assetId) console.error("Could not find the asset: " + assetId)
} }
} }
else throw new Meteor.Error("User Permission Error");
}, },
/** /**
* Removes an assignment for the asset. * Removes an assignment for the asset.
@@ -158,37 +166,54 @@ Meteor.methods({
if(!date) date = new Date(); if(!date) date = new Date();
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
Assets.update({assetId}, {$unset: {assigneeType, assigneeId, assignmentDate}}); let asset = Assets.findOne({assetId});
if(asset) {
try {
AssetAssignmentHistory.insert({assetId, assigneeType: asset.assigneeType, assigneeId: asset.assigneeId, startDate: asset.assignmentDate, endDate: date});
} catch (e) {
console.error(e);
}
Assets.update({assetId}, {$unset: {assigneeType, assigneeId, assignmentDate}});
}
else {
console.error("Could not find the asset: " + assetId);
throw new Meteor.Error("Could not find the asset: " + assetId);
}
} }
else throw new Meteor.Error("User Permission Error");
}, },
/** /**
* 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'() { 'assets.fixAssetAssignments'() {
let assignmentDate = new Date(); // Removed this since it should no longer be relevant.
//This function just removes the need for the asset-assignments collection and merges it with assets.
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) { // let assignmentDate = new Date();
let assets = Assets.find({}).fetch(); // //This function just removes the need for the asset-assignments collection and merges it with assets.
let assetAssignments = AssetAssignments.find({}).fetch(); // if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
// let assets = Assets.find({}).fetch();
let assetMap = assets.reduce((map, obj) => { // let assetAssignments = AssetAssignments.find({}).fetch();
map[obj.assetId] = obj; //
return map; // let assetMap = assets.reduce((map, obj) => {
}, {}); // map[obj.assetId] = obj;
// return map;
console.log(assetMap); // }, {});
console.log(""); //
// console.log(assetMap);
for(let next of assetAssignments) { // console.log("");
console.log(next); //
let asset = assetMap[next.assetId]; // for(let next of assetAssignments) {
console.log("Updating " + asset.assetId + " to be assigned to " + next.assigneeType + ": " + next.assigneeId); // console.log(next);
let c = Assets.update({assetId: asset.assetId}, {$set: {assigneeType: next.assigneeType, assigneeId: next.assigneeId, assignmentDate}}); // let asset = assetMap[next.assetId];
console.log("Updated " + c + " Assets"); // console.log("Updating " + asset.assetId + " to be assigned to " + next.assigneeType + ": " + next.assigneeId);
console.log(Assets.findOne({assetId: asset.assetId})); // let c = Assets.update({assetId: asset.assetId}, {$set: {assigneeType: next.assigneeType, assigneeId: next.assigneeId, assignmentDate}});
} // console.log("Updated " + c + " Assets");
} // console.log(Assets.findOne({assetId: asset.assetId}));
// }
// }
} }
}); });
// console.log("Assets setup.")

View File

@@ -5,6 +5,8 @@ import { MongoClient } from 'mongodb';
import {Assets} from "/imports/api/assets"; import {Assets} from "/imports/api/assets";
//import {Roles} from 'alanning/roles'; //import {Roles} from 'alanning/roles';
// console.log("Setting Up Data Collection...")
//export const Records = new Mongo.Collection('records'); //export const Records = new Mongo.Collection('records');
let client; let client;
let database; let database;
@@ -104,3 +106,5 @@ if (Meteor.isServer) {
// }, // },
}); });
} }
// console.log("Data Collection setup.")

View File

@@ -7,3 +7,6 @@ import "./sites.js";
import "./asset-types.js"; import "./asset-types.js";
import "./assets.js"; import "./assets.js";
import "./asset-assignments.js"; import "./asset-assignments.js";
import "./asset-assignment-history.js";
// console.log("Finished setting up server side models.");

View File

@@ -4,6 +4,8 @@ import {Students} from "./students";
import {Staff} from "./staff"; import {Staff} from "./staff";
import { Roles } from 'meteor/alanning:roles'; import { Roles } from 'meteor/alanning:roles';
// console.log("Setting Up Sites...")
export const Sites = new Mongo.Collection('sites'); export const Sites = new Mongo.Collection('sites');
if (Meteor.isServer) { if (Meteor.isServer) {
@@ -36,3 +38,5 @@ Meteor.methods({
} }
}, },
}); });
// console.log("Sites setup.")

View File

@@ -5,6 +5,8 @@ import {check} from "meteor/check";
import {Sites} from "/imports/api/sites"; import {Sites} from "/imports/api/sites";
import {parse} from "csv-parse"; import {parse} from "csv-parse";
// console.log("Setting Up Staff...")
export const Staff = new Mongo.Collection('staff'); export const Staff = new Mongo.Collection('staff');
if (Meteor.isServer) { if (Meteor.isServer) {
@@ -150,3 +152,4 @@ Meteor.methods({
} }
}); });
// console.log("Staff setup.")

View File

@@ -5,6 +5,8 @@ import {Sites} from "./sites";
import { Roles } from 'meteor/alanning:roles'; import { Roles } from 'meteor/alanning:roles';
import {parse} from 'csv-parse'; import {parse} from 'csv-parse';
// console.log("Setting Up Students...")
export const Students = new Mongo.Collection('students'); export const Students = new Mongo.Collection('students');
if (Meteor.isServer) { if (Meteor.isServer) {
@@ -160,4 +162,6 @@ if (Meteor.isServer) {
} }
}); });
} }
// console.log("Students setup.")

View File

@@ -2,6 +2,8 @@ import { Meteor } from 'meteor/meteor';
import { Roles } from 'meteor/alanning:roles'; import { Roles } from 'meteor/alanning:roles';
import { check } from 'meteor/check'; import { check } from 'meteor/check';
// console.log("Setting Up Users...")
if (Meteor.isServer) { if (Meteor.isServer) {
Meteor.publish(null, function() { Meteor.publish(null, function() {
if(this.userId) { if(this.userId) {
@@ -66,3 +68,5 @@ if (Meteor.isServer) {
// }, // },
}); });
} }
// console.log("Users setup.")

View File

@@ -2,6 +2,8 @@ import { Accounts } from 'meteor/accounts-base'
import { Roles } from 'meteor/alanning:roles' import { Roles } from 'meteor/alanning:roles'
import {Meteor} from "meteor/meteor"; import {Meteor} from "meteor/meteor";
console.log("Setting up accounts-config...")
if(Meteor.isClient) { if(Meteor.isClient) {
Accounts.ui.config({ Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY' passwordSignupFields: 'USERNAME_ONLY'
@@ -68,3 +70,5 @@ if(Meteor.isServer) {
}); });
} }
} }
console.log("Finished setting up accounts-config.")

View File

@@ -9,6 +9,8 @@
import {Assets} from "/imports/api/assets"; import {Assets} from "/imports/api/assets";
import {Students} from "/imports/api/students"; import {Students} from "/imports/api/students";
import {AssetTypes} from "/imports/api/asset-types"; import {AssetTypes} from "/imports/api/asset-types";
import Button, { Label } from '@smui/button';
import Dialog, { Title, Content, Actions } from '@smui/dialog';
onMount(async () => { onMount(async () => {
Meteor.subscribe('assets'); Meteor.subscribe('assets');
@@ -53,6 +55,11 @@
const formatDate = (date) => { const formatDate = (date) => {
return date.toLocaleDateString('en-us', {weekday: 'long', year: 'numeric', month: 'short', day: 'numeric'}); return date.toLocaleDateString('en-us', {weekday: 'long', year: 'numeric', month: 'short', day: 'numeric'});
} }
const unassign = () => {
if(confirm("Unassign Asset?")) {
Meteor.call("assets.unassign", foundAsset.assetId);
}
}
</script> </script>
<div class="container"> <div class="container">
@@ -75,8 +82,26 @@
<div>Assigned on: {formatDate(foundAsset.assignmentDate)}</div> <div>Assigned on: {formatDate(foundAsset.assignmentDate)}</div>
<div>Assigned to: {foundAssignee.firstName} {foundAssignee.lastName} <div>Assigned to: {foundAssignee.firstName} {foundAssignee.lastName}
{#if foundAssignee.grade} ~ {foundAssignee.grade} {/if}({foundAssignee.email})</div> {#if foundAssignee.grade} ~ {foundAssignee.grade} {/if}({foundAssignee.email})</div>
<Button variant="raised" touch on:click={unassign}>
<Label style="color: white">Unassign</Label>
</Button>
{/if} {/if}
{/if} {/if}
<!-- <Dialog bind:open={showDialog} aria-labelledby="Confirm" aria-describedby="Unassign Confirmation">-->
<!-- &lt;!&ndash; Title cannot contain leading whitespace due to mdc-typography-baseline-top() &ndash;&gt;-->
<!-- <Title id="simple-title">Unassign Asset?</Title>-->
<!-- <Content id="simple-content"></Content>-->
<!-- <Actions>-->
<!-- <Button on:click={() => (clicked = 'No')}>-->
<!-- <Label>No</Label>-->
<!-- </Button>-->
<!-- <Button on:click={() => (clicked = 'Yes')}>-->
<!-- <Label>Yes</Label>-->
<!-- </Button>-->
<!-- </Actions>-->
<!-- </Dialog>-->
</div> </div>
<style> <style>

View File

@@ -1,10 +1,12 @@
console.log("Checking Environment...");
if(!process.env.MONGO_URL) { if(!process.env.MONGO_URL) {
console.log("Must provide the MONGO_URL environment variable point to the district central's main database. Should be of the format: `mongodb://localhost:27017/DatabaseName` or `mongodb://user_name:password@host.domain.com,host2.domain.com,host3.domain.com/DatabaseName?replicaSet=set_name`.") console.error("Must provide the MONGO_URL environment variable point to the district central's main database. Should be of the format: `mongodb://localhost:27017/DatabaseName` or `mongodb://user_name:password@host.domain.com,host2.domain.com,host3.domain.com/DatabaseName?replicaSet=set_name`.")
process.exit(0); process.exit(0);
} }
if(!process.env.MONGO_URL2) { if(!process.env.MONGO_URL2) {
console.log("Must provide the MONGO_URL2 environment variable pointing to the chromebook data collection dataset. Should be of the format: `mongodb://localhost:27017/DatabaseName` or `mongodb://user_name:password@host.domain.com,host2.domain.com,host3.domain.com/DatabaseName?replicaSet=set_name`.") console.error("Must provide the MONGO_URL2 environment variable pointing to the chromebook data collection dataset. Should be of the format: `mongodb://localhost:27017/DatabaseName` or `mongodb://user_name:password@host.domain.com,host2.domain.com,host3.domain.com/DatabaseName?replicaSet=set_name`.")
process.exit(0); process.exit(0);
} }
@@ -12,8 +14,8 @@ try {
let settings = Assets.getText('settings.json'); let settings = Assets.getText('settings.json');
} }
catch(e) { catch(e) {
console.log("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.log(` console.error(`
{ {
"google": { "google": {
"clientId": "xxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", "clientId": "xxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
@@ -29,4 +31,6 @@ catch(e) {
`); `);
process.exit(0); process.exit(0);
} }
console.log("Environment Checking Complete.")

View File

@@ -1,6 +1,8 @@
import {MongoInternals} from 'meteor/mongo'; import {MongoInternals} from 'meteor/mongo';
import {Meteor} from 'meteor/meteor'; import {Meteor} from 'meteor/meteor';
console.log("Setting up data collection database connection...");
let uri = process.env.MONGO_URL2; //"mongodb://localhost:27017/avusd_data_collection"; let uri = process.env.MONGO_URL2; //"mongodb://localhost:27017/avusd_data_collection";
//uri = "mongodb://localhost:27017/avusd_data_collection"; //uri = "mongodb://localhost:27017/avusd_data_collection";
//console.log(uri); //console.log(uri);
@@ -11,3 +13,5 @@ Meteor.Records = collection;
// let results = collection.find({deviceId: "1e3e99ef-adf4-4aa2-8784-205bc60f0ce3"}).fetch(); // let results = collection.find({deviceId: "1e3e99ef-adf4-4aa2-8784-205bc60f0ce3"}).fetch();
// console.log(results); // console.log(results);
console.log("Database connection setup.")

View File

@@ -4,6 +4,8 @@
* Loads the information from the /private/settings.json file. * Loads the information from the /private/settings.json file.
*/ */
console.log("Setting up Google OAuth...");
try { try {
let settings = Assets.getText('settings.json'); let settings = Assets.getText('settings.json');
@@ -48,3 +50,5 @@ ServiceConfiguration.configurations.upsert(
} }
); );
*/ */
console.log("Finished OAuth setup.")

View File

@@ -3,6 +3,8 @@ import winston from "winston";
import moment from "moment"; import moment from "moment";
import _ from 'underscore'; import _ from 'underscore';
// console.log("Setting up logging....");
let production = (process.env.NODE_ENV === "production"); let production = (process.env.NODE_ENV === "production");
let logPath = process.env.LOG_PATH; let logPath = process.env.LOG_PATH;
@@ -88,3 +90,5 @@ console.warn = function(d) {
console.error = function(e) { console.error = function(e) {
logger.log("error", e.stack || e); logger.log("error", e.stack || e);
} }
// console.log("Logger setup.");