Fixed a number of bugs; added a few fields.
This commit is contained in:
@@ -60,12 +60,14 @@ Meteor.methods({
|
||||
check(assigneeType, String);
|
||||
check(assetId, String);
|
||||
|
||||
if(assigneeType !== 'Student' || assigneeType !== 'Staff') {
|
||||
|
||||
if(assigneeType !== 'Student' && assigneeType !== 'Staff') {
|
||||
// Should never happen.
|
||||
console.error("Error: Received incorrect assignee type in adding an assignment.");
|
||||
console.error(assigneeType);
|
||||
}
|
||||
else if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
||||
AssetAssignments.insert({assetId, assigneeType: assigneeType === "Student" ? 0 : 1, assigneeId});
|
||||
AssetAssignments.insert({assetId, assigneeType, assigneeId});
|
||||
}
|
||||
},
|
||||
'AssetAssignments.remove'(_id) {
|
||||
|
||||
@@ -42,25 +42,27 @@ if (Meteor.isServer) {
|
||||
|
||||
// This code only runs on the server
|
||||
Meteor.publish('assetTypes', function() {
|
||||
return AssetTypes.find({}, {sort: {name: 1}});
|
||||
return AssetTypes.find({});
|
||||
});
|
||||
}
|
||||
Meteor.methods({
|
||||
'assetTypes.add'(name, description) {
|
||||
'assetTypes.add'(name, description, year) {
|
||||
check(name, String);
|
||||
check(description, String);
|
||||
check(year, String);
|
||||
|
||||
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
||||
AssetTypes.insert({name, description});
|
||||
AssetTypes.insert({name, description, year});
|
||||
}
|
||||
},
|
||||
'assetTypes.update'(_id, name, description) {
|
||||
'assetTypes.update'(_id, name, description, year) {
|
||||
check(_id, String);
|
||||
check(name, String);
|
||||
check(description, String);
|
||||
check(year, String);
|
||||
|
||||
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
||||
AssetTypes.update({_id}, {$set: {name, description}});
|
||||
AssetTypes.update({_id}, {$set: {name, description, year}});
|
||||
}
|
||||
},
|
||||
'assetTypes.remove'(_id) {
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
|
||||
const assetTypesColumns = [
|
||||
{
|
||||
key: "year",
|
||||
title: "Year",
|
||||
value: v => v.year,
|
||||
minWidth: 100,
|
||||
weight: 1,
|
||||
cls: "year",
|
||||
}, {
|
||||
key: "name",
|
||||
title: "Name",
|
||||
value: v => v.name,
|
||||
@@ -43,17 +50,17 @@
|
||||
}
|
||||
let dirtyAssetType;
|
||||
// Copy the edited value when ever it changes, set some defaults for a new value object (to make the view happy).
|
||||
editedAssetType.subscribe(v => {dirtyAssetType = Object.assign({name: "", description: ""}, v)});
|
||||
editedAssetType.subscribe(v => {dirtyAssetType = Object.assign({name: "", description: "", year: ""}, v)});
|
||||
// Load the sites (reactive).
|
||||
let assetTypes = AssetTypes.find({});
|
||||
let assetTypes = AssetTypes.find({}, {sort: {year: -1}});
|
||||
const deleteAssetType = assetType => {
|
||||
//TODO:
|
||||
};
|
||||
const applyAssetTypeChanges = () => {
|
||||
if(dirtyAssetType._id)
|
||||
Meteor.call("assetTypes.update", dirtyAssetType._id, dirtyAssetType.name, dirtyAssetType.description);
|
||||
Meteor.call("assetTypes.update", dirtyAssetType._id, dirtyAssetType.name, dirtyAssetType.description, dirtyAssetType.year);
|
||||
else
|
||||
Meteor.call("assetTypes.add", dirtyAssetType.name, dirtyAssetType.description);
|
||||
Meteor.call("assetTypes.add", dirtyAssetType.name, dirtyAssetType.description, dirtyAssetType.year);
|
||||
editedAssetType.set(null);
|
||||
dirtyAssetType = null;
|
||||
}
|
||||
@@ -68,6 +75,9 @@
|
||||
{#if dirtyAssetType}
|
||||
<div class="editorContainer">
|
||||
<div style="grid-column: 1/span 1">
|
||||
<TextField type="text" style="width: 100%" bind:value={dirtyAssetType.year} label="Year">
|
||||
<HelperText slot="helper">The manufacture or purchase year. Used for sorting assets so most recent ones appear on top.</HelperText>
|
||||
</TextField>
|
||||
<TextField type="text" style="width: 100%" bind:value={dirtyAssetType.name} label="Name">
|
||||
<HelperText slot="helper">Provide a unique name for the asset type.</HelperText>
|
||||
</TextField>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
import {Meteor} from "meteor/meteor";
|
||||
import {onMount} from "svelte";
|
||||
import AssetList from "/imports/ui/Assets/AssetList.svelte";
|
||||
import AssetDataEntry from "/imports/ui/Assets/AssetDataEntry.svelte";
|
||||
import AddAssets from "/imports/ui/Assets/AddAssets.svelte";
|
||||
import {useTracker} from "meteor/rdb:svelte-meteor-data";
|
||||
import Assign from "/imports/ui/Assets/Assign.svelte";
|
||||
import AssignAssets from "/imports/ui/Assets/AssignAssets.svelte";
|
||||
import Assignments from "/imports/ui/Assets/Assignments.svelte";
|
||||
|
||||
let canManageLaptops = false;
|
||||
@@ -23,12 +23,12 @@
|
||||
let tabs = [];
|
||||
|
||||
if(canManageLaptops) {
|
||||
tabs.push({id: 'assignments', label: 'Assignments'});
|
||||
tabs.push({id: 'assignment', label: 'Assign'});
|
||||
tabs.push({id: 'listAssignments', label: 'Assignment List'});
|
||||
tabs.push({id: 'assignAssets', label: 'Assign Assets'});
|
||||
}
|
||||
if(isAdmin) {
|
||||
tabs.push({id: 'list', label: 'Asset List'});
|
||||
tabs.push({id: 'entry', label: 'Data Entry'});
|
||||
tabs.push({id: 'listAssets', label: 'Asset List'});
|
||||
tabs.push({id: 'addAssets', label: 'Add Assets'});
|
||||
}
|
||||
let activeTab = tabs[0];
|
||||
</script>
|
||||
@@ -39,13 +39,13 @@
|
||||
<Label>{tab.label}</Label>
|
||||
</Tab>
|
||||
</TabBar>
|
||||
{#if activeTab && activeTab.id === 'list'}
|
||||
{#if activeTab && activeTab.id === 'listAssets'}
|
||||
<AssetList></AssetList>
|
||||
{:else if activeTab && activeTab.id === 'entry'}
|
||||
<AssetDataEntry></AssetDataEntry>
|
||||
{:else if activeTab && activeTab.id === 'assignment'}
|
||||
<Assign></Assign>
|
||||
{:else if activeTab && activeTab.id === 'assignments'}
|
||||
{:else if activeTab && activeTab.id === 'addAssets'}
|
||||
<AddAssets></AddAssets>
|
||||
{:else if activeTab && activeTab.id === 'assignAssets'}
|
||||
<AssignAssets></AssignAssets>
|
||||
{:else if activeTab && activeTab.id === 'listAssignments'}
|
||||
<Assignments></Assignments>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import TextField from '@smui/textfield';
|
||||
import u from 'umbrellajs';
|
||||
import {AssetTypes} from "/imports/api/asset-types";
|
||||
import Paper from '@smui/paper';
|
||||
|
||||
onMount(async () => {
|
||||
Meteor.subscribe('assetTypes');
|
||||
@@ -17,7 +18,7 @@
|
||||
let assetTypes;
|
||||
//$m: assetTypes = AssetTypes.find({}).fetch();
|
||||
//$: assetTypes = useTracker(() => AssetTypes.find({}).fetch());
|
||||
$: assetTypes = AssetTypes.find({});
|
||||
$: assetTypes = AssetTypes.find({}, {sort: {year: -1}});
|
||||
let selectedAssetTypes = [];
|
||||
|
||||
let selectedType = null;
|
||||
@@ -116,10 +117,11 @@
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
<h3 style="display: inline-block">Asset Types</h3>
|
||||
<h3 style="display: block">Asset Types</h3>
|
||||
<Button class="addBtn" on:click={openAssetTypesDialog}>
|
||||
<Label>Add...</Label>
|
||||
</Button>
|
||||
<Paper>
|
||||
<List class="assetTypeList" singleSelection dense>
|
||||
{#each selectedAssetTypes as type}
|
||||
<Item on:SMUI:action={() => (selectedAssetType = type)} selected={selectedAssetType === type}>
|
||||
@@ -127,6 +129,7 @@
|
||||
</Item>
|
||||
{/each}
|
||||
</List>
|
||||
</Paper>
|
||||
<div style="grid-column: 1/span 1">
|
||||
<TextField id="assetIdField" type="text" style="width: 100%" bind:value={assetId} label="AssetId">
|
||||
</TextField>
|
||||
@@ -147,7 +150,7 @@
|
||||
}
|
||||
|
||||
:global(.addBtn) {
|
||||
margin-left: 4rem;
|
||||
/*margin-left: 4rem;*/
|
||||
}
|
||||
|
||||
:global(.assetTypeList) {
|
||||
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import {Meteor} from "meteor/meteor";
|
||||
import {onMount} from "svelte";
|
||||
import {writable} from "svelte/store";
|
||||
import {writable, derived} from "svelte/store";
|
||||
import TextField from '@smui/textfield';
|
||||
import HelperText from '@smui/textfield/helper-text';
|
||||
import Select, { Option } from '@smui/select';
|
||||
@@ -16,7 +16,12 @@
|
||||
Meteor.subscribe('assets');
|
||||
});
|
||||
let assetTypes;
|
||||
$: assetTypes = AssetTypes.find({});
|
||||
$: assetTypes = AssetTypes.find({}, {sort: {year: -1}});
|
||||
$: assetTypeNameMap = derived(assetTypes, $assetTypes => $assetTypes.reduce((map, obj) => {
|
||||
map[obj._id] = obj.name;
|
||||
return map;
|
||||
}, {}));
|
||||
|
||||
|
||||
// Asset Table //
|
||||
|
||||
@@ -35,6 +40,17 @@
|
||||
minWidth: 100,
|
||||
weight: 1,
|
||||
cls: "serial",
|
||||
}, {
|
||||
key: "asset",
|
||||
title: "Asset Type",
|
||||
value: v => {
|
||||
$: {
|
||||
return v.assetTypeId ? $assetTypeNameMap[v.assetTypeId] : "-"
|
||||
}
|
||||
},
|
||||
minWidth: 100,
|
||||
weight: 1,
|
||||
cls: "serial",
|
||||
},
|
||||
];
|
||||
const assetActions = {
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
const createAssignment = () => {
|
||||
if(assetId && assetId.length && selectedAssignee) {
|
||||
Meteor.call("AssetAssignments.add", assetId, selectedCategory === 'Student' ? "Student" : "Staff", selectedAssignee._id)
|
||||
// TODO: Set focus to the asset ID field.
|
||||
assetId = "";
|
||||
}
|
||||
}
|
||||
@@ -105,7 +106,7 @@
|
||||
<TextField bind:this={assetIdWidget} style="flex-grow: 999;" type="text" bind:value={assetId} label="Asset ID">
|
||||
|
||||
</TextField>
|
||||
<Button variant="raised" color="secondary" on:click={createAssignment()} disabled={!assetId || assetId.length === 0 || !selectedAssignee}>
|
||||
<Button variant="raised" color="secondary" on:click={createAssignment} disabled={!assetId || assetId.length === 0 || !selectedAssignee}>
|
||||
<Label style="color: white">Create</Label>
|
||||
</Button>
|
||||
</div>
|
||||
@@ -2,14 +2,9 @@
|
||||
import {Meteor} from "meteor/meteor";
|
||||
import {onMount} from "svelte";
|
||||
import {Sites} from "../../api/sites";
|
||||
import GridTable from "./../GridTable.svelte";
|
||||
import {writable} from "svelte/store";
|
||||
import TextField from '@smui/textfield';
|
||||
import HelperText from '@smui/textfield/helper-text';
|
||||
import {Students} from "../../api/students";
|
||||
import Select, { Option } from '@smui/select';
|
||||
import Dialog, { Title, Content, Actions } from '@smui/dialog';
|
||||
import Button, { Label } from '@smui/button';
|
||||
import {Staff} from "/imports/api/staff";
|
||||
import List, {Item, Graphic, Meta, Text, PrimaryText, SecondaryText} from '@smui/list';
|
||||
import Paper from '@smui/paper';
|
||||
@@ -30,12 +25,14 @@
|
||||
let selectedSiteId;
|
||||
let categories = ['Email', 'First Name', 'Last Name'];
|
||||
let selectedCategory = 'Email';
|
||||
let selectedGrade = 'All';
|
||||
let selectedGrade = 'All Grades';
|
||||
let searchText = "";
|
||||
let searchResults = [];
|
||||
let searchResults;
|
||||
let selectedResult;
|
||||
|
||||
$: {
|
||||
console.log("Site ID")
|
||||
console.log(selectedSiteId)
|
||||
if(selectedSiteId) {
|
||||
Meteor.subscribe('students', selectedSiteId);
|
||||
Meteor.subscribe('staff', selectedSiteId);
|
||||
@@ -44,34 +41,37 @@
|
||||
|
||||
$: {
|
||||
selectedResult = null;
|
||||
console.log("Starting search")
|
||||
|
||||
// Require at least two characters in the search field before we start filtering.
|
||||
if(selectedSiteId && selectedGrade && selectedCategory && searchText && searchText.length > 1) {
|
||||
if(selectedSiteId && selectedGrade && selectedCategory) {
|
||||
let query = {};
|
||||
|
||||
if(selectedCategory === 'Email') {
|
||||
if(searchText && searchText.length > 0) {
|
||||
if (selectedCategory === 'Email') {
|
||||
query.email = {$regex: searchText, $options: 'i'};
|
||||
}
|
||||
else if(selectedCategory === 'First Name') {
|
||||
} else if (selectedCategory === 'First Name') {
|
||||
query.firstName = {$regex: searchText, $options: 'i'};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
query.lastName = {$regex: searchText, $options: 'i'};
|
||||
}
|
||||
}
|
||||
|
||||
if(selectedCategory === "Staff") {
|
||||
searchResults = Staff.find(query);
|
||||
}
|
||||
else {
|
||||
if(selectedGrade !== 'All') {
|
||||
if(selectedGrade !== 'All Grades') {
|
||||
query.grade = selectedGrade;
|
||||
}
|
||||
|
||||
searchResults = Students.find(query).fetch();
|
||||
console.log("Searching")
|
||||
console.log(query)
|
||||
searchResults = Students.find(query);
|
||||
}
|
||||
}
|
||||
else {
|
||||
searchResults = [];
|
||||
searchResults = undefined;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -117,7 +117,8 @@
|
||||
<!-- </Button>-->
|
||||
</div>
|
||||
<List twoLine singleSelection>
|
||||
{#each searchResults as result}
|
||||
{#if searchResults}
|
||||
{#each $searchResults as result}
|
||||
<Item selected={selectedResult === result}>
|
||||
<Text>
|
||||
<PrimaryText>{result.firstName} {result.lastName}</PrimaryText>
|
||||
@@ -125,6 +126,7 @@
|
||||
</Text>
|
||||
</Item>
|
||||
{/each}
|
||||
{/if}
|
||||
</List>
|
||||
</div>
|
||||
|
||||
|
||||
3795
package-lock.json
generated
3795
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,9 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "meteor run",
|
||||
"build": "npm install --product && meteor build --architecture os.linux.x86_64 --server-only ../",
|
||||
"update": "npx browserslist@latest --update-db",
|
||||
"build": "npm install --omit=dev && meteor build --architecture os.linux.x86_64 --server-only ../",
|
||||
"build_old": "npm install --product && meteor build --architecture os.linux.x86_64 --server-only ../",
|
||||
"test": "meteor test --once --driver-package meteortesting:mocha",
|
||||
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
|
||||
"visualize": "meteor --production --extra-packages bundle-visualizer",
|
||||
@@ -21,6 +23,7 @@
|
||||
"meteor-node-stubs": "^1.0.0",
|
||||
"moment": "^2.29.2",
|
||||
"mongodb": "^4.4.1",
|
||||
"smui-theme": "^6.0.0-beta.16",
|
||||
"svelte": "^3.46.4",
|
||||
"svelte-material-ui": "^6.0.0-beta.16",
|
||||
"tinro": "^0.6.12",
|
||||
@@ -61,7 +64,6 @@
|
||||
"@smui/textfield": "^6.0.0-beta.16",
|
||||
"chai": "^4.2.0",
|
||||
"rollup-plugin-css-only": "^3.1.0",
|
||||
"smui-theme": "^6.0.0-beta.16",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user