Added Asset management code.
This commit is contained in:
@@ -7,7 +7,7 @@ import { Roles } from 'meteor/alanning:roles';
|
|||||||
//
|
//
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
export const AssetTypes = new Mongo.Collection('assetType');
|
export const AssetTypes = new Mongo.Collection('assetTypes');
|
||||||
/*
|
/*
|
||||||
|
|
||||||
const AssetTypesSchema = new SimpleSchema({
|
const AssetTypesSchema = new SimpleSchema({
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ Meteor.methods({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'assets.update'(_id, assetId, serial) {
|
||||||
|
//TODO:
|
||||||
|
},
|
||||||
'assets.remove'(_id) {
|
'assets.remove'(_id) {
|
||||||
check(_id, String);
|
check(_id, String);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
cls: "name",
|
cls: "name",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const actions = {
|
const siteActions = {
|
||||||
title: "Actions",
|
title: "Actions",
|
||||||
headerWidgets: [
|
headerWidgets: [
|
||||||
{icon: "add_box", action: () => {editedSite.set({name: ""});}, tooltip: "Add a new Site."}
|
{icon: "add_box", action: () => {editedSite.set({name: ""});}, tooltip: "Add a new Site."}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
let editedSite = writable(null);
|
let editedSite = writable(null);
|
||||||
let dirtySite = null;
|
let dirtySite = null;
|
||||||
// Copy the edited site when ever it changes, set some defaults for a new site object (to make the view happy).
|
// Copy the edited site when ever it changes, set some defaults for a new site object (to make the view happy).
|
||||||
editedSite.subscribe(site => {dirtySite = Object.assign({name: ""}, site)});
|
editedSite.subscribe(site => {dirtySite = Object.assign({}, site)});
|
||||||
// Load the sites (reactive).
|
// Load the sites (reactive).
|
||||||
let sites = Sites.find({});
|
let sites = Sites.find({});
|
||||||
const applySiteChanges = () => {
|
const applySiteChanges = () => {
|
||||||
@@ -66,6 +66,9 @@
|
|||||||
editedSite.set(null);
|
editedSite.set(null);
|
||||||
}
|
}
|
||||||
let selectedSite = null;
|
let selectedSite = null;
|
||||||
|
const onSiteSelection = (e) => {
|
||||||
|
selectedSite = Sites.findOne({_id: e.detail});
|
||||||
|
}
|
||||||
|
|
||||||
let students = null;
|
let students = null;
|
||||||
let staff = null;
|
let staff = null;
|
||||||
@@ -77,9 +80,6 @@
|
|||||||
staff = Staff.find({siteId: selectedSite._id});
|
staff = Staff.find({siteId: selectedSite._id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onSiteSelection = (e) => {
|
|
||||||
selectedSite = Sites.findOne({_id: e.detail});
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadStudents = () => {
|
const uploadStudents = () => {
|
||||||
// console.log(files);
|
// console.log(files);
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
const assetTypesActions = {
|
const assetTypesActions = {
|
||||||
title: "Actions",
|
title: "Actions",
|
||||||
headerWidgets: [
|
headerWidgets: [
|
||||||
{icon: "add_box", action: () => {editedAssetType.set({name: ""});}, tooltip: "Add a new asset type."}
|
{icon: "add_box", action: () => {editedAssetType.set({});}, tooltip: "Add a new asset type."}
|
||||||
],
|
],
|
||||||
rowWidgets: [
|
rowWidgets: [
|
||||||
{icon: "add_circle", action: (v) => {editedAssetType.set(v)}},
|
{icon: "add_circle", action: (v) => {editedAssetType.set(v)}},
|
||||||
|
|||||||
@@ -4,17 +4,161 @@
|
|||||||
import {writable} from "svelte/store";
|
import {writable} from "svelte/store";
|
||||||
import TextField from '@smui/textfield';
|
import TextField from '@smui/textfield';
|
||||||
import HelperText from '@smui/textfield/helper-text';
|
import HelperText from '@smui/textfield/helper-text';
|
||||||
|
import Select, { Option } from '@smui/select';
|
||||||
import {AssetTypes} from "../api/asset-types";
|
import {AssetTypes} from "../api/asset-types";
|
||||||
|
import { useTracker } from 'meteor/rdb:svelte-meteor-data';
|
||||||
|
import GridTable from "./GridTable.svelte";
|
||||||
import {Assets} from "../api/assets";
|
import {Assets} from "../api/assets";
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
Meteor.subscribe('assetTypes');
|
Meteor.subscribe('assetTypes');
|
||||||
});
|
});
|
||||||
|
let assetTypes;
|
||||||
|
//$m: assetTypes = AssetTypes.find({}).fetch();
|
||||||
|
//$: assetTypes = useTracker(() => AssetTypes.find({}).fetch());
|
||||||
|
$: assetTypes = AssetTypes.find({});
|
||||||
|
|
||||||
|
let selectedType = null;
|
||||||
|
const selectAssetType = (assetType) => {
|
||||||
|
selectedType = assetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asset Table //
|
||||||
|
|
||||||
|
const assetColumns = [
|
||||||
|
{
|
||||||
|
key: "assetId",
|
||||||
|
title: "Asset ID",
|
||||||
|
value: v => v.assetId,
|
||||||
|
minWidth: 100,
|
||||||
|
weight: 1,
|
||||||
|
cls: "assetId",
|
||||||
|
}, {
|
||||||
|
key: "serial",
|
||||||
|
title: "Serial",
|
||||||
|
value: v => v.serial,
|
||||||
|
minWidth: 100,
|
||||||
|
weight: 1,
|
||||||
|
cls: "serial",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const assetActions = {
|
||||||
|
title: "Actions",
|
||||||
|
headerWidgets: [
|
||||||
|
{icon: "add_box", action: () => {editedAsset.set({});}, tooltip: "Add a new asset."}
|
||||||
|
],
|
||||||
|
rowWidgets: [
|
||||||
|
{icon: "add_circle", action: (v) => {editedAsset.set(v)}},
|
||||||
|
{icon: "delete", action: (v) => {deleteAsset(v)}}
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const deleteAsset = asset => {
|
||||||
|
//TODO:
|
||||||
|
};
|
||||||
|
// Create a holder for the site being edited. This allows us to clear the editor when the user finishes, and allows the table or parent view to setup the editor.
|
||||||
|
let editedAsset = writable(null);
|
||||||
|
let dirtyAsset = null;
|
||||||
|
// Copy the edited site when ever it changes, set some defaults for a new site object (to make the view happy).
|
||||||
|
editedAsset.subscribe(site => {dirtyAsset = Object.assign({serial: "", assetId: "", assetTypeId: ""}, site)});
|
||||||
|
// Load the sites (reactive).
|
||||||
|
let assets = Assets.find({});
|
||||||
|
const applyAssetChanges = () => {
|
||||||
|
if(dirtyAsset._id)
|
||||||
|
Meteor.call("assets.update", dirtyAsset._id, dirtyAsset.serial, dirtyAsset.assetId);
|
||||||
|
else
|
||||||
|
Meteor.call("assets.add", dirtyAsset.serial, dirtyAsset.assetId, dirtyAsset.assetTypeId);
|
||||||
|
editedAsset.set(null);
|
||||||
|
}
|
||||||
|
const rejectAssetChanges = () => {
|
||||||
|
editedAsset.set(null);
|
||||||
|
}
|
||||||
|
let selectedAsset = null;
|
||||||
|
const onAssetSelection = (e) => {
|
||||||
|
selectedAsset = Assets.findOne({_id: e.detail});
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Asset Table //
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div class="listContainer">
|
||||||
|
<h2>Asset Types</h2>
|
||||||
|
<div class="list">
|
||||||
|
{#each $assetTypes as type}
|
||||||
|
<div class="listItem" class:selected={selectedType === type} on:click={(e) => {selectAssetType(type)}}>
|
||||||
|
<div class="listItemAssetTypeName">{type.name}</div>
|
||||||
|
<div class="listItemAssetTypeDescription">{type.description}</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="assetsContainer">
|
||||||
|
<h2>Assets</h2>
|
||||||
|
<GridTable bind:rows={assets} columns="{assetColumns}" actions="{assetActions}" rowKey="{(v) => {return v._id}}" bind:edited="{editedAsset}" on:selection={onAssetSelection}>
|
||||||
|
{#if dirtyAsset}
|
||||||
|
<div class="editorContainer">
|
||||||
|
<Select bind:value={dirtyAsset.assetTypeId} label="Select Menu">
|
||||||
|
{#each $assetTypes as assetType}
|
||||||
|
<Option value={assetType._id}>{assetType.name}</Option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
<div style="grid-column: 1/span 1">
|
||||||
|
<TextField type="text" style="width: 100%" bind:value={dirtyAsset.assetId} label="AssetId">
|
||||||
|
<HelperText slot="helper">Provide a unique asset ID string.</HelperText>
|
||||||
|
</TextField>
|
||||||
|
</div>
|
||||||
|
<div style="grid-column: 1/span 1">
|
||||||
|
<TextField type="text" style="width: 100%" bind:value={dirtyAsset.serial} label="Serial">
|
||||||
|
<HelperText slot="helper">Provide a unique serial string for the asset.</HelperText>
|
||||||
|
</TextField>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" style="grid-column: 2/span 1;" class="button accept-button material-icons material-symbols-outlined" on:click={applyAssetChanges}>
|
||||||
|
check
|
||||||
|
</button>
|
||||||
|
<button type="button" style="grid-column: 3/span 1;" class="button reject-button material-icons material-symbols-outlined" on:click={rejectAssetChanges}>
|
||||||
|
close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</GridTable>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.listContainer {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 1rem;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
div.listContainer h2 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
border: 2px solid #4f4e4e;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.listItem:nth-child(even) {
|
||||||
|
/*background: #f6f6f6;*/
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.listItem {
|
||||||
|
margin: 4px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
user-select: none;
|
||||||
|
border-bottom: 1px solid gray;
|
||||||
|
}
|
||||||
|
.listItem:last-child {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.listItem.selected {
|
||||||
|
background-color: rgba(255, 255, 0, 0.38);
|
||||||
|
}
|
||||||
|
|
||||||
|
.assetsContainer {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
3694
package-lock.json
generated
3694
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@smui/common": "^6.0.0-beta.16",
|
"@smui/common": "^6.0.0-beta.16",
|
||||||
|
"@smui/select": "^6.0.0-beta.16",
|
||||||
"@smui/textfield": "^6.0.0-beta.16",
|
"@smui/textfield": "^6.0.0-beta.16",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"rollup-plugin-css-only": "^3.1.0",
|
"rollup-plugin-css-only": "^3.1.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user