Files
DistrictCentral/imports/ui/Assets.svelte

164 lines
5.7 KiB
Svelte

<script>
import {Meteor} from "meteor/meteor";
import {onMount} from "svelte";
import {writable} from "svelte/store";
import TextField from '@smui/textfield';
import HelperText from '@smui/textfield/helper-text';
import Select, { Option } from '@smui/select';
import {AssetTypes} from "../api/asset-types";
import { useTracker } from 'meteor/rdb:svelte-meteor-data';
import GridTable from "./GridTable.svelte";
import {Assets} from "../api/assets";
onMount(async () => {
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>
<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>
<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>