update
This commit is contained in:
@@ -1,207 +0,0 @@
|
|||||||
/**
|
|
||||||
* taggcodeApp.js
|
|
||||||
* Dynamische AssetMenu implementatie met TagcodeApp API
|
|
||||||
* Vervangt de statische assetData met calls naar REST-endpoints.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class TagcodeApp {
|
|
||||||
constructor(baseURL = 'https://pimmoerman.nl/rdlab/tagcode.app/v2.1/api') {
|
|
||||||
this.baseURL = baseURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchData(path, params = {}) {
|
|
||||||
const url = new URL(`${this.baseURL}/${path}`);
|
|
||||||
Object.entries(params).forEach(([key, value]) => {
|
|
||||||
url.searchParams.append(key, value);
|
|
||||||
});
|
|
||||||
const response = await fetch(url);
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
||||||
const json = await response.json();
|
|
||||||
if (!json.success) throw new Error(json.error || json.message);
|
|
||||||
return json.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Asset endpoints
|
|
||||||
getAllAssets() {
|
|
||||||
return this.fetchData('asset/get_all_assets.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetDetail(tag_code) {
|
|
||||||
return this.fetchData('asset/get_detail_asset.php', { tag_code });
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetHistory(asset_tag_number) {
|
|
||||||
return this.fetchData('asset/get_history_asset.php', { asset_tag_number });
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetHierarchy(asset_tag_number) {
|
|
||||||
return this.fetchData('asset/get_asset_hierarchy.php', { asset_tag_number });
|
|
||||||
}
|
|
||||||
|
|
||||||
createOrUpdateAsset(params) {
|
|
||||||
// Bij create/update worden alle velden via query params meegegeven
|
|
||||||
return this.fetchData('asset/create_asset.php', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Product & vendor endpoints
|
|
||||||
getVendors() {
|
|
||||||
return this.fetchData('vendor/get_vendors.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
getSubtypes(vendor_name) {
|
|
||||||
return this.fetchData('product/get_subtypesFromVendor.php', { vendor_name });
|
|
||||||
}
|
|
||||||
|
|
||||||
getProductModels(vendor_name, product_subtype_name) {
|
|
||||||
return this.fetchData('product/get_product_models.php', { vendor_name, product_subtype_name });
|
|
||||||
}
|
|
||||||
|
|
||||||
getLocations() {
|
|
||||||
return this.fetchData('location/get_locations.php');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DynamicAssetMenu {
|
|
||||||
constructor(nodeName, api = new TagcodeApp()) {
|
|
||||||
this.nodeName = nodeName;
|
|
||||||
this.api = api;
|
|
||||||
this.data = {
|
|
||||||
vendors: [],
|
|
||||||
subtypes: {}, // per vendor
|
|
||||||
models: {} // per vendor+subtype
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialiseer: haal vendors en locaties eenmalig op
|
|
||||||
*/
|
|
||||||
async init() {
|
|
||||||
this.data.vendors = await this.api.getVendors();
|
|
||||||
this.data.locations = await this.api.getLocations();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injecteer HTML, data en events
|
|
||||||
*/
|
|
||||||
getClientInitCode() {
|
|
||||||
const node = this.nodeName;
|
|
||||||
return `
|
|
||||||
// --- DynamicAssetMenu voor ${node} ---
|
|
||||||
window.TagcodeApp = window.TagcodeApp || ${TagcodeApp.toString()};
|
|
||||||
window.assetAPI = window.assetAPI || new TagcodeApp();
|
|
||||||
|
|
||||||
// Helper populate
|
|
||||||
function populate(el, opts, sel) {
|
|
||||||
const old = el.value;
|
|
||||||
el.innerHTML = '<option value="">Select…</option>';
|
|
||||||
(opts||[]).forEach(o=>{
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = o; opt.textContent = o;
|
|
||||||
el.appendChild(opt);
|
|
||||||
});
|
|
||||||
el.value = sel || '';
|
|
||||||
if (el.value !== old) el.dispatchEvent(new Event('change'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitEditor
|
|
||||||
window.EVOLV.nodes.${node}.assetMenu.initEditor = async function(node) {
|
|
||||||
this.injectHtml();
|
|
||||||
// eerst: laad vendor-lijst
|
|
||||||
const vendors = await window.assetAPI.getVendors();
|
|
||||||
const vendorNames = vendors.map(v=>v.name);
|
|
||||||
populate(document.getElementById('node-input-supplier'), vendorNames, node.supplier);
|
|
||||||
|
|
||||||
// wire events
|
|
||||||
const elems = {
|
|
||||||
supplier: document.getElementById('node-input-supplier'),
|
|
||||||
category: document.getElementById('node-input-category'),
|
|
||||||
type: document.getElementById('node-input-assetType'),
|
|
||||||
model: document.getElementById('node-input-model'),
|
|
||||||
unit: document.getElementById('node-input-unit')
|
|
||||||
};
|
|
||||||
|
|
||||||
elems.supplier.addEventListener('change', async ()=>{
|
|
||||||
const v = elems.supplier.value;
|
|
||||||
if (!v) return populate(elems.category, [], '');
|
|
||||||
const subs = await window.assetAPI.getSubtypes(v);
|
|
||||||
const names = subs.map(s=>s.name);
|
|
||||||
populate(elems.category, names, node.category);
|
|
||||||
});
|
|
||||||
|
|
||||||
elems.category.addEventListener('change', async ()=>{
|
|
||||||
const v = elems.supplier.value, c = elems.category.value;
|
|
||||||
if (!v||!c) return populate(elems.type, [], '');
|
|
||||||
const models = await window.assetAPI.getProductModels(v, c);
|
|
||||||
window._currentModels = models; // tijdelijk cachen
|
|
||||||
const types = Array.from(new Set(models.map(m=>m.product_model_type)));
|
|
||||||
populate(elems.type, types, node.assetType);
|
|
||||||
});
|
|
||||||
|
|
||||||
elems.type.addEventListener('change', ()=>{
|
|
||||||
const t = elems.type.value;
|
|
||||||
const models = window._currentModels || [];
|
|
||||||
const filtered = models.filter(m=>m.product_model_type===t);
|
|
||||||
const names = filtered.map(m=>m.name);
|
|
||||||
window._filteredModels = filtered;
|
|
||||||
populate(elems.model, names, node.model);
|
|
||||||
});
|
|
||||||
|
|
||||||
elems.model.addEventListener('change', ()=>{
|
|
||||||
const m = elems.model.value;
|
|
||||||
const models = window._filteredModels || [];
|
|
||||||
const entry = models.find(x=>x.name===m);
|
|
||||||
const units = entry && entry.product_model_meta ? Object.keys(entry.product_model_meta) : [];
|
|
||||||
populate(elems.unit, units, node.unit);
|
|
||||||
});
|
|
||||||
|
|
||||||
// laadt opgeslagen waarden
|
|
||||||
if (node.supplier) elems.supplier.dispatchEvent(new Event('change'));
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getHtmlTemplate() {
|
|
||||||
return `
|
|
||||||
<!-- Asset Properties -->
|
|
||||||
<hr />
|
|
||||||
<h3>Asset selection</h3>
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-supplier"><i class="fa fa-industry"></i> Supplier</label>
|
|
||||||
<select id="node-input-supplier" style="width:70%;"></select>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-category"><i class="fa fa-sitemap"></i> Category</label>
|
|
||||||
<select id="node-input-category" style="width:70%;"></select>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-assetType"><i class="fa fa-puzzle-piece"></i> Type</label>
|
|
||||||
<select id="node-input-assetType" style="width:70%;"></select>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-model"><i class="fa fa-wrench"></i> Model</label>
|
|
||||||
<select id="node-input-model" style="width:70%;"></select>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-unit"><i class="fa fa-balance-scale"></i> Unit</label>
|
|
||||||
<select id="node-input-unit" style="width:70%;"></select>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getHtmlInjectionCode() {
|
|
||||||
const tmpl = this.getHtmlTemplate().replace(/`/g, '\\`').replace(/\$/g, '\\\$');
|
|
||||||
return `
|
|
||||||
// Asset HTML injection voor ${this.nodeName}
|
|
||||||
window.EVOLV.nodes.${this.nodeName}.assetMenu.injectHtml = function() {
|
|
||||||
const placeholder = document.getElementById('asset-fields-placeholder');
|
|
||||||
if (placeholder && !placeholder.hasChildNodes()) {
|
|
||||||
placeholder.innerHTML = \`${tmpl}\`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exporteer voor gebruik in Node-RED
|
|
||||||
module.exports = { TagcodeApp, DynamicAssetMenu };
|
|
||||||
Reference in New Issue
Block a user