partdb/public/partdb.js

278 lines
7.8 KiB
JavaScript

/* frontend for the part database
* Copyright (C) 2023 King Kévin <kingkevin@cuvoodoo.info>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
"use strict";
// the last search query
var last_search = null;
// the collection of parts
var parts = null;
// part field to populate
const fields = ["name", "description", "details", "package", "pincount", "manufacturer", "mpn", "family", "datasheet", "page", "location", "stock"];
// URLs to set
const urls = ["page","datasheet"];
function search()
{
const terms = document.getElementById('terms');
if (terms && terms.value && terms.value.length >= 3) {
} else {
return;
}
last_search = '/search/' + terms.value;
let xhr = new XMLHttpRequest();
xhr.open('GET', last_search, true);
xhr.onload = function() {
if (this.responseURL.endsWith(last_search)) {
parts = JSON.parse(this.response)
results();
}
};
xhr.onerror = function() {
console.log("search call failed");
};
xhr.send();
}
function results()
{
const results = document.getElementById('results');
let part_id = -1;
if (results.selectedIndex >= 0) {
part_id = parseInt(results.options[results.selectedIndex].value);
}
results.innerHTML = null;
for (const part of parts) {
const option = document.createElement('option');
option.setAttribute('value', part.id);
option.innerHTML = part.name;
if (part.description) {
option.innerHTML += " (" + part.description + ")";
if (part_id == part.id) {
option.selected = "selected";
}
}
results.appendChild(option);
}
select_part(); // in case we reselected
}
function clear()
{
// clear part fields
for (const field of fields) {
const input = document.getElementById('part_' + field);
if (input.tagName == "INPUT") {
input.value = "";
} else if (input.tagName == "TEXTAREA") {
input.innerHTML = null;
}
}
// clear URLs
for (const field of urls) {
const a = document.getElementById('url_' + field);
a.href = null;
}
// clear distributors
const distributors = document.getElementById('distributors');
distributors.innerHTML = null;
// clear properties
const properties = document.getElementById('properties');
properties.innerHTML = null;
// clear attachments
const attachments = document.getElementById('attachments');
attachments.innerHTML = null;
}
function select_part()
{
const results = document.getElementById('results');
if (results.selectedIndex >= 0) {
let part_selected = parseInt(results.options[results.selectedIndex].value);
for (const part of parts) {
if (part.id == part_selected) {
//console.log(part);
// populate part fields
for (const field of fields) {
const input = document.getElementById('part_' + field);
if (input.tagName == "INPUT") {
if (undefined === part[field]) {
input.value = "";
} else {
input.value = part[field];
}
} else if (input.tagName == "TEXTAREA") {
if (undefined === part[field]) {
input.innerHTML = null;
} else {
input.innerHTML = part[field];
}
}
}
// set URLs
for (const field of urls) {
const span = document.getElementById('url_' + field);
const text = span.innerText;
span.innerHTML = null;
if (undefined === part[field] || null == part[field]) {
span.innerHTML = text;
} else {
const a = document.createElement('a');
a.href = part[field];
a.innerText = text;
span.appendChild(a);
}
}
// set distributors
const distributors = document.getElementById('distributors');
distributors.innerHTML = null;
for (const distributor of part["distributors"]) {
const tr = document.createElement('tr');
const td_name = document.createElement('td');
td_name.innerText = distributor.name;
tr.appendChild(td_name);
const td_sku = document.createElement('td');
const input = document.createElement('input');
input.type = "text";
input.style.width = "95%";
if (distributor.sku) {
input.value = distributor.sku;
}
td_sku.appendChild(input);
tr.appendChild(td_sku);
const td_url = document.createElement('td');
if (distributor.url) {
td_url.innerHTML = "<a href='" + distributor.url + "'>link</a>";
}
tr.appendChild(td_url);
distributors.appendChild(tr);
}
// add properties
const properties = document.getElementById('properties');
properties.innerHTML = null;
for (const prop in part["properties"]) {
const tr = document.createElement('tr');
let td = document.createElement('td');
let input = document.createElement('input');
input.type = "text";
input.style.width = "95%";
input.value = prop;
td.appendChild(input);
tr.appendChild(td);
td = document.createElement('td');
input = document.createElement('input');
input.type = "text";
input.style.width = "95%";
input.value = part["properties"][prop].join(",");
td.appendChild(input);
tr.appendChild(td);
properties.appendChild(tr);
}
// add empty property field
let tr = document.createElement('tr');
let td = document.createElement('td');
let input = document.createElement('input');
input.type = "text";
input.style.width = "95%";
td.appendChild(input);
tr.appendChild(td);
td = document.createElement('td');
input = document.createElement('input');
input.type = "text";
input.style.width = "95%";
td.appendChild(input);
tr.appendChild(td);
properties.appendChild(tr);
// add attachments
const attachments = document.getElementById('attachments');
attachments.innerHTML = null;
for (const attachment of part["attachments"]) {
const a = document.createElement('a');
a.href = attachment;
const img = document.createElement('img');
img.alt = attachment.split("/").slice(-1);
img.src = attachment;
a.appendChild(img);
attachments.appendChild(a);
}
}
}
}
}
function delete_part()
{
if (null == parts) {
return;
}
const results = document.getElementById('results');
if (results.selectedIndex < 0) {
return;
}
const part_selected = parseInt(results.options[results.selectedIndex].value);
const xhr = new XMLHttpRequest();
xhr.open('GET', '/delete/' + part_selected, true);
xhr.onload = function() {
clear();
search(); // refresh search
};
xhr.onerror = function() {
console.log("delete part failed");
};
xhr.send();
}
function update_part()
{
// the part to update
let part = {};
// its id
const results = document.getElementById('results');
if (results.selectedIndex >= 0) {
part.id = parseInt(results.options[results.selectedIndex].value);
}
// the fields
for (const field of fields) {
const input = document.getElementById('part_' + field);
if (input.tagName == "INPUT") {
part[field] = input.value;
} else if (input.tagName == "TEXTAREA") {
part[field] = input.innerHTML;
}
}
if (part["name"].length == 0) {
return;
}
// get distributors
part.distributors = [];
const distributors = document.getElementById('distributors');
for (const distributor of distributors.rows) {
part.distributors.push({"distributor": distributor.cells[0].innerText, "sku": distributor.cells[1].firstChild.value});
}
// get properties
part.properties = {};
const properties = document.getElementById('properties');
for (const prop of properties.rows) {
const name = prop.cells[0].firstChild.value;
const value = prop.cells[1].firstChild.value;
if (name && name.length > 0 && value && value.length > 0) {
part.properties[name] = value.split(",");
}
}
console.log(part);
var post = new XMLHttpRequest();
post.open("POST", "part");
post.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
post.onload = function() {
clear();
search(); // refresh search
};
post.onerror = function() {
console.log("update part failed");
};
post.send(JSON.stringify(part));
}