193 lines
5.9 KiB
Svelte
193 lines
5.9 KiB
Svelte
<script>
|
|
import {Meteor} from "meteor/meteor";
|
|
import {onMount} from "svelte";
|
|
import {writable, derived} 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";
|
|
import u from 'umbrellajs';
|
|
|
|
onMount(async () => {
|
|
Meteor.subscribe('assetTypes');
|
|
Meteor.subscribe('assets');
|
|
});
|
|
let assetTypes;
|
|
$: assetTypes = AssetTypes.find({}, {sort: {year: -1}});
|
|
$: assetTypeNameMap = derived(assetTypes, $assetTypes => $assetTypes.reduce((map, obj) => {
|
|
map[obj._id] = obj.name;
|
|
return map;
|
|
}, {}));
|
|
|
|
|
|
// 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 ? v.serial : "-",
|
|
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 = {
|
|
title: "",
|
|
headerWidgets: [
|
|
{icon: "add_box", action: () => {editedAsset.update((v) => {return v ? null : {}})}, tooltip: "Add a new asset."}
|
|
],
|
|
rowWidgets: [
|
|
{icon: "add_circle", action: (v) => {editedAsset.set(v)}},
|
|
{icon: "delete", action: (v) => {deleteAsset(v)}}
|
|
],
|
|
};
|
|
const deleteAsset = asset => {
|
|
if(asset && asset._id) {
|
|
if(confirm("Delete Asset? This is permanent.")) Meteor.call("assets.remove", asset._id);
|
|
}
|
|
};
|
|
// 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;
|
|
let conditions = ['New', 'Like New', 'Good', 'Okay', 'Damaged'];
|
|
// Copy the edited site when ever it changes, set some defaults for a new site object (to make the view happy).
|
|
editedAsset.subscribe(site => {
|
|
if(site) {
|
|
dirtyAsset = Object.assign({serial: "", assetId: "", assetTypeId: ""}, site);
|
|
//document.getElementsByClassName('select').focus();
|
|
}
|
|
else dirtyAsset = null;
|
|
});
|
|
// Load the sites (reactive).
|
|
let assets = Assets.find({});
|
|
const applyAssetChanges = () => {
|
|
if(dirtyAsset._id)
|
|
Meteor.call("assets.update", dirtyAsset._id, dirtyAsset.assetId, dirtyAsset.serial);
|
|
else
|
|
Meteor.call("assets.add", dirtyAsset.assetTypeId, dirtyAsset.assetId, dirtyAsset.serial);
|
|
editedAsset.set(null);
|
|
}
|
|
const rejectAssetChanges = () => {
|
|
editedAsset.set(null);
|
|
}
|
|
let selectedAsset = null;
|
|
const onAssetSelection = (e) => {
|
|
selectedAsset = Assets.findOne({_id: e.detail});
|
|
}
|
|
let editorFirstComponent = null;
|
|
$: if(editorFirstComponent) editorFirstComponent.focus();
|
|
const initEditor = (e) => {
|
|
//editorFirstComponent.focus();
|
|
//document.getElementsByClassName("focusMe")[0].children[0].children[2].focus();
|
|
// u('.focusMe .mdc-select__selected-text').first().focus();
|
|
//$('.select').focus();
|
|
}
|
|
|
|
// End Asset Table //
|
|
</script>
|
|
|
|
<div class="container">
|
|
<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" use:initEditor>
|
|
<div style="grid-column: 1/span 1">
|
|
<Select class="focusMe select" bind:value={dirtyAsset.assetTypeId} label="Asset Type" bind:this={editorFirstComponent}>
|
|
{#each $assetTypes as assetType}
|
|
<Option value={assetType._id}>{assetType.name}</Option>
|
|
{/each}
|
|
</Select>
|
|
</div>
|
|
<div style="grid-column: 1/span 1">
|
|
<TextField type="text" style="width: 100%" bind:value={dirtyAsset.assetId} label="AssetId">
|
|
</TextField>
|
|
</div>
|
|
<div style="grid-column: 1/span 1">
|
|
<TextField type="text" style="width: 100%" bind:value={dirtyAsset.serial} label="Serial">
|
|
</TextField>
|
|
</div>
|
|
<Select bind:value={dirtyAsset.condition} label="Condition">
|
|
{#each conditions as next}
|
|
<Option value={next}>{next}</Option>
|
|
{/each}
|
|
</Select>
|
|
<div style="grid-column: 1/span 1">
|
|
<TextField type="text" style="width: 100%" bind:value={dirtyAsset.conditionDetails} label="Condition Details">
|
|
</TextField>
|
|
</div>
|
|
|
|
<div style="grid-column: 1/span 1; white-space: nowrap; text-align: right; margin-top: 0.5rem">
|
|
<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>
|
|
</div>
|
|
{/if}
|
|
</GridTable>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.assetsContainer {
|
|
display: block;
|
|
}
|
|
.editorContainer {
|
|
display: grid;
|
|
grid-template-columns: minmax(10px, 1fr);
|
|
column-gap: 2rem;
|
|
background-color: #e0e3e7;
|
|
padding: 1rem;
|
|
}
|
|
:global(.select) {
|
|
width: 100%;
|
|
}
|
|
.accept-button, .reject-button {
|
|
font-size: .8rem;
|
|
padding: .6rem;
|
|
margin: auto;
|
|
color: white;
|
|
border-radius: 50%;
|
|
border: 0;
|
|
font-weight: 800;
|
|
alignment: center;
|
|
cursor: pointer;
|
|
}
|
|
.accept-button {
|
|
background-color: rgba(61, 148, 61, 0.91);
|
|
}
|
|
.reject-button {
|
|
background-color: rgba(176, 64, 64, 0.61);
|
|
}
|
|
.accept-button:hover {
|
|
background-color: rgb(61, 148, 61);
|
|
}
|
|
.reject-button:hover {
|
|
background-color: rgb(176, 64, 64);
|
|
}
|
|
</style> |