|
|
@@ -53,19 +53,29 @@
|
|
|
if ("barcode" in target) this.barcode = target["barcode"];
|
|
|
if ("thumbnail" in target) this.thumbnail = target["thumbnail"];
|
|
|
if ("on_stock" in target) this.on_stock = target["on_stock"];
|
|
|
+ try {
|
|
|
+ this.stock_count = Number(this.stock_count);
|
|
|
+ } catch {
|
|
|
+ this.stock_count = 0;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.on_stock = Number(this.on_stock);
|
|
|
+ } catch {
|
|
|
+ this.on_stock = 0;
|
|
|
+ }
|
|
|
}
|
|
|
get dump() {
|
|
|
const dumped = {
|
|
|
- "name": this.name,
|
|
|
- "description": this.description,
|
|
|
- "author": this.author,
|
|
|
- "image": this.image,
|
|
|
- "stock_count": this.stock_count,
|
|
|
- "barcode": this.barcode,
|
|
|
- "thumbnail": this.thumbnail
|
|
|
+ "name": new String(this.name),
|
|
|
+ "description": new String(this.description),
|
|
|
+ "author": new String(this.author),
|
|
|
+ "image": new String(this.image),
|
|
|
+ "barcode": new String(this.barcode),
|
|
|
+ "thumbnail": new String(this.thumbnail),
|
|
|
+ "stock_count": new String(this.stock_count)
|
|
|
};
|
|
|
if (this.on_stock !== null) {
|
|
|
- dumped["on_stock"] = this.on_stock;
|
|
|
+ dumped["on_stock"] = new String(this.on_stock);
|
|
|
}
|
|
|
return dumped;
|
|
|
}
|
|
|
@@ -412,11 +422,18 @@
|
|
|
// application/scripts/request.js
|
|
|
var request = class {
|
|
|
get settings() {
|
|
|
- return {
|
|
|
+ const settings = {
|
|
|
"method": this.method,
|
|
|
- "headers": this.headers,
|
|
|
- "body": this.body
|
|
|
+ "headers": this.headers
|
|
|
};
|
|
|
+ if (this.method === "GET" || this.method === "HEAD") {
|
|
|
+ return settings;
|
|
|
+ }
|
|
|
+ if (this.body === null) {
|
|
|
+ return settings;
|
|
|
+ }
|
|
|
+ settings.body = this.body;
|
|
|
+ return settings;
|
|
|
}
|
|
|
get _apikey() {
|
|
|
const manager = new login_manager();
|
|
|
@@ -432,16 +449,24 @@
|
|
|
throw new TypeError("It must be overwrite.");
|
|
|
}
|
|
|
get headers() {
|
|
|
- if (this.method === "GET") {
|
|
|
+ if (this.method === "GET" || this.method === "HEAD") {
|
|
|
return {};
|
|
|
}
|
|
|
+ if (typeof this.data === "string") {
|
|
|
+ return {
|
|
|
+ "Content-Type": "text/plain"
|
|
|
+ };
|
|
|
+ }
|
|
|
return {
|
|
|
"Content-Type": "application/json"
|
|
|
};
|
|
|
}
|
|
|
get body() {
|
|
|
if (this.data === null) {
|
|
|
- return "";
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (typeof this.data === "string") {
|
|
|
+ return this.data;
|
|
|
}
|
|
|
return JSON.stringify(this.data);
|
|
|
}
|
|
|
@@ -695,7 +720,7 @@
|
|
|
title.appendChild(title_content);
|
|
|
const form = document.createElement("form");
|
|
|
center.appendChild(form);
|
|
|
- form.addEventListener("click", () => {
|
|
|
+ form.addEventListener("change", () => {
|
|
|
this._clear_results();
|
|
|
});
|
|
|
this.#form = document.createElement("div");
|
|
|
@@ -758,7 +783,10 @@
|
|
|
throw new Error("Screen is not visible yet!");
|
|
|
}
|
|
|
this._append_child(container);
|
|
|
- return () => {
|
|
|
+ return (target = null) => {
|
|
|
+ if (target !== null) {
|
|
|
+ input.value = target;
|
|
|
+ }
|
|
|
return input.value;
|
|
|
};
|
|
|
}
|
|
|
@@ -816,16 +844,20 @@
|
|
|
this.barcode = this._extract(target, "barcode");
|
|
|
this.stock_count = this._extract(target, "stock_count");
|
|
|
if (this.stock_count !== null) {
|
|
|
- this.stock_count = Number(this.stock_count);
|
|
|
+ try {
|
|
|
+ this.stock_count = Number(this.stock_count);
|
|
|
+ } catch {
|
|
|
+ this.stock_count = 0;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
get dump() {
|
|
|
return {
|
|
|
- "name": this.name,
|
|
|
- "description": this.description,
|
|
|
- "author": this.author,
|
|
|
- "barcode": this.barcode,
|
|
|
- "stock_count": this.stock_count
|
|
|
+ "name": new String(this.name),
|
|
|
+ "description": new String(this.description),
|
|
|
+ "author": new String(this.author),
|
|
|
+ "barcode": new String(this.barcode),
|
|
|
+ "stock_count": new String(this.stock_count)
|
|
|
};
|
|
|
}
|
|
|
_extract(dict, name) {
|
|
|
@@ -902,6 +934,9 @@
|
|
|
#barcode;
|
|
|
#stock_count;
|
|
|
#image;
|
|
|
+ #loaded_image_type;
|
|
|
+ #loaded_image;
|
|
|
+ #image_preview;
|
|
|
constructor(target) {
|
|
|
super();
|
|
|
this.#target = target;
|
|
|
@@ -913,6 +948,8 @@
|
|
|
return "Product editor";
|
|
|
}
|
|
|
_build_form() {
|
|
|
+ this.#loaded_image = null;
|
|
|
+ this.#loaded_image_type = null;
|
|
|
this.#name = this._create_input(
|
|
|
"name",
|
|
|
"Name:",
|
|
|
@@ -963,21 +1000,42 @@
|
|
|
this.#image = input;
|
|
|
input.type = "file";
|
|
|
input.accept = "image/*";
|
|
|
+ input.addEventListener("change", () => {
|
|
|
+ this.#load_image_from_file();
|
|
|
+ });
|
|
|
}
|
|
|
);
|
|
|
+ this.#image_preview = document.createElement("img");
|
|
|
+ this.#image_preview.style.opacity = "1";
|
|
|
+ this.#image_preview.src = this.#target.image;
|
|
|
+ this._append_child(this.#image_preview);
|
|
|
+ }
|
|
|
+ get #ready_image() {
|
|
|
+ return this.#loaded_image;
|
|
|
+ }
|
|
|
+ #update_image_preview() {
|
|
|
+ this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
|
|
|
+ this.#image_preview.style.opacity = "1";
|
|
|
}
|
|
|
- async #code_image() {
|
|
|
+ #reset_image() {
|
|
|
+ this.#loaded_image = null;
|
|
|
+ this.#loaded_image_type = null;
|
|
|
+ this.#image_preview.style.opacity = "0";
|
|
|
+ this.#image_preview.src = "";
|
|
|
+ }
|
|
|
+ async #load_image_from_file() {
|
|
|
if (this.#image.files.length === 0) {
|
|
|
- return null;
|
|
|
+ this.#reset_image();
|
|
|
}
|
|
|
const file = this.#image.files.item(0);
|
|
|
const buffer = await file.arrayBuffer();
|
|
|
- const list = new Uint8Array(buffer);
|
|
|
- let content = new String();
|
|
|
- list.forEach((code) => {
|
|
|
- content += String.fromCharCode(code);
|
|
|
+ let as_string = new String();
|
|
|
+ new Uint8Array(buffer).forEach((letter) => {
|
|
|
+ as_string += String.fromCharCode(letter);
|
|
|
});
|
|
|
- return btoa(content);
|
|
|
+ this.#loaded_image = btoa(as_string);
|
|
|
+ this.#loaded_image_type = file.type;
|
|
|
+ this.#update_image_preview();
|
|
|
}
|
|
|
async #submit() {
|
|
|
const copy = this.#target.copy();
|
|
|
@@ -994,7 +1052,7 @@
|
|
|
this.#target = copy;
|
|
|
}
|
|
|
async #image_submit() {
|
|
|
- const image = await this.#code_image();
|
|
|
+ const image = await this.#ready_image;
|
|
|
if (image === null) {
|
|
|
return;
|
|
|
}
|
|
|
@@ -1511,6 +1569,7 @@
|
|
|
image.classList.add("image");
|
|
|
image.src = this.#target.thumbnail + this.#cache_bypass;
|
|
|
image.alt = this.#target.name;
|
|
|
+ image.loading = "lazy";
|
|
|
image.addEventListener("click", () => {
|
|
|
new product_fullscreen(this.#target).show();
|
|
|
});
|
|
|
@@ -1635,6 +1694,47 @@
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ // application/scripts/autocomplete_response.js
|
|
|
+ var autocomplete_response = class extends bool_response {
|
|
|
+ #found;
|
|
|
+ constructor(target) {
|
|
|
+ super(target);
|
|
|
+ this.#found = null;
|
|
|
+ if (this.result) {
|
|
|
+ this.#found = target["found"];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ get found() {
|
|
|
+ if (this.#found === null) {
|
|
|
+ throw new Error("Server response is not complete.");
|
|
|
+ }
|
|
|
+ return this.#found;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/autocomplete_request.js
|
|
|
+ var autocomplete_request = class extends request {
|
|
|
+ #barcode;
|
|
|
+ constructor(barcode) {
|
|
|
+ super();
|
|
|
+ this.#barcode = barcode;
|
|
|
+ }
|
|
|
+ get _response() {
|
|
|
+ return autocomplete_response;
|
|
|
+ }
|
|
|
+ get data() {
|
|
|
+ return {
|
|
|
+ "apikey": this._apikey
|
|
|
+ };
|
|
|
+ }
|
|
|
+ get method() {
|
|
|
+ return "POST";
|
|
|
+ }
|
|
|
+ get url() {
|
|
|
+ return "/complete/barcode/" + this.#barcode;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
// application/scripts/product_adder.js
|
|
|
var product_adder = class extends formscreen {
|
|
|
#name;
|
|
|
@@ -1643,10 +1743,59 @@
|
|
|
#barcode;
|
|
|
#stock_count;
|
|
|
#image;
|
|
|
+ #loaded_image_type;
|
|
|
+ #loaded_image;
|
|
|
+ #image_preview;
|
|
|
get _name() {
|
|
|
return "Add product";
|
|
|
}
|
|
|
+ async #autocomplete() {
|
|
|
+ const barcode = this.#barcode();
|
|
|
+ if (barcode.length === 0) {
|
|
|
+ this._info = "Fill barcode first.";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this._info = "Searching in the web...";
|
|
|
+ try {
|
|
|
+ const request2 = new autocomplete_request(barcode);
|
|
|
+ const response = await request2.connect();
|
|
|
+ if (!response.result) {
|
|
|
+ throw new Error(response.cause);
|
|
|
+ }
|
|
|
+ const product2 = response.found;
|
|
|
+ this.#name(product2.title);
|
|
|
+ this.#description(product2.description);
|
|
|
+ this.#author(product2.author);
|
|
|
+ this.#barcode(product2.barcode);
|
|
|
+ this.#loaded_image = product2.image;
|
|
|
+ this.#loaded_image_type = product2.image_type;
|
|
|
+ this.#update_image_preview();
|
|
|
+ this._info = "Ready. Check results.";
|
|
|
+ } catch (error) {
|
|
|
+ this._error = new String(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #update_image_preview() {
|
|
|
+ this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
|
|
|
+ this.#image_preview.style.opacity = "1";
|
|
|
+ }
|
|
|
+ get #autocomplete_button() {
|
|
|
+ const button = document.createElement("div");
|
|
|
+ button.classList.add("autocomplete-button");
|
|
|
+ button.classList.add("button");
|
|
|
+ const icon = document.createElement("span");
|
|
|
+ icon.classList.add("material-icons");
|
|
|
+ icon.innerText = "auto_fix_normal";
|
|
|
+ button.appendChild(icon);
|
|
|
+ const text = document.createElement("span");
|
|
|
+ text.classList.add("text");
|
|
|
+ text.innerText = "Autocomplete";
|
|
|
+ button.appendChild(text);
|
|
|
+ return button;
|
|
|
+ }
|
|
|
_build_form() {
|
|
|
+ this.#loaded_image = null;
|
|
|
+ this.#loaded_image_type = null;
|
|
|
this.#name = this._create_input(
|
|
|
"name",
|
|
|
"Name:",
|
|
|
@@ -1686,21 +1835,45 @@
|
|
|
this.#image = input;
|
|
|
input.type = "file";
|
|
|
input.accept = "image/*";
|
|
|
+ input.addEventListener("change", () => {
|
|
|
+ this.#load_image_from_file();
|
|
|
+ });
|
|
|
}
|
|
|
);
|
|
|
+ this.#image_preview = document.createElement("img");
|
|
|
+ this.#image_preview.style.opacity = "0";
|
|
|
+ this._append_child(this.#image_preview);
|
|
|
+ const autocomplete = this.#autocomplete_button;
|
|
|
+ this._append_child(autocomplete);
|
|
|
+ autocomplete.addEventListener("click", () => {
|
|
|
+ this.#autocomplete();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ #reset_image() {
|
|
|
+ this.#loaded_image = null;
|
|
|
+ this.#loaded_image_type = null;
|
|
|
+ this.#image_preview.style.opacity = "0";
|
|
|
+ this.#image_preview.src = "";
|
|
|
}
|
|
|
- async #code_image() {
|
|
|
+ async #load_image_from_file() {
|
|
|
if (this.#image.files.length === 0) {
|
|
|
- throw new Error("Upload image for product.");
|
|
|
+ this.#reset_image();
|
|
|
}
|
|
|
const file = this.#image.files.item(0);
|
|
|
const buffer = await file.arrayBuffer();
|
|
|
- const list = new Uint8Array(buffer);
|
|
|
- let content = new String();
|
|
|
- list.forEach((code) => {
|
|
|
- content += String.fromCharCode(code);
|
|
|
+ let as_string = new String();
|
|
|
+ new Uint8Array(buffer).forEach((letter) => {
|
|
|
+ as_string += String.fromCharCode(letter);
|
|
|
});
|
|
|
- return btoa(content);
|
|
|
+ this.#loaded_image = btoa(as_string);
|
|
|
+ this.#loaded_image_type = file.type;
|
|
|
+ this.#update_image_preview();
|
|
|
+ }
|
|
|
+ get #ready_image() {
|
|
|
+ if (this.#loaded_image === null) {
|
|
|
+ throw new Error("Loady any image first.");
|
|
|
+ }
|
|
|
+ return this.#loaded_image;
|
|
|
}
|
|
|
async #submit() {
|
|
|
const product2 = new product_base();
|
|
|
@@ -1709,8 +1882,7 @@
|
|
|
product2.author = this.#author();
|
|
|
product2.stock_count = this.#stock_count();
|
|
|
product2.barcode = this.#barcode();
|
|
|
- const image = await this.#code_image();
|
|
|
- const request2 = new create_request(product2, image);
|
|
|
+ const request2 = new create_request(product2, this.#ready_image);
|
|
|
const response = await request2.connect();
|
|
|
if (!response.result) {
|
|
|
throw new Error(response.cause);
|
|
|
@@ -1731,6 +1903,314 @@
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ // application/scripts/import_process_fail.js
|
|
|
+ var import_process_fail = class {
|
|
|
+ #product;
|
|
|
+ #error;
|
|
|
+ constructor(product2, error) {
|
|
|
+ this.#product = product2;
|
|
|
+ this.#error = error;
|
|
|
+ }
|
|
|
+ get error() {
|
|
|
+ return this.#error;
|
|
|
+ }
|
|
|
+ get product() {
|
|
|
+ return this.#product;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/database.js
|
|
|
+ var database = class {
|
|
|
+ #content;
|
|
|
+ #processed;
|
|
|
+ #on_skip;
|
|
|
+ constructor(content) {
|
|
|
+ this.#content = content;
|
|
|
+ this.#processed = /* @__PURE__ */ new Map();
|
|
|
+ this.#on_skip = null;
|
|
|
+ }
|
|
|
+ #append(target) {
|
|
|
+ if (this.#processed.has(target.barcode)) {
|
|
|
+ this.#processed.get(target.barcode).stock_count += 1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.#processed.set(target.barcode, target);
|
|
|
+ }
|
|
|
+ #validate(target) {
|
|
|
+ if (!("id" in target)) {
|
|
|
+ throw new Error("One of item has no ID.");
|
|
|
+ }
|
|
|
+ if (!("title" in target)) {
|
|
|
+ throw new Error("Product " + target.barcode + " has no title.");
|
|
|
+ }
|
|
|
+ if (!("author" in target)) {
|
|
|
+ throw new Error("Product " + target.barcode + " has no author.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #convert(target) {
|
|
|
+ this.#validate(target);
|
|
|
+ const product2 = new product_base();
|
|
|
+ product2.name = target.title;
|
|
|
+ product2.description = "";
|
|
|
+ product2.author = target.author;
|
|
|
+ product2.stock_count = 1;
|
|
|
+ product2.barcode = target.id;
|
|
|
+ return product2;
|
|
|
+ }
|
|
|
+ on_skip(target) {
|
|
|
+ this.#on_skip = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ process() {
|
|
|
+ this.#processed.clear();
|
|
|
+ if (!(this.#content instanceof Array)) {
|
|
|
+ throw new Error("Database woud be array of objects.");
|
|
|
+ }
|
|
|
+ this.#content.forEach((count) => {
|
|
|
+ try {
|
|
|
+ const product2 = this.#convert(count);
|
|
|
+ this.#append(product2);
|
|
|
+ } catch (error) {
|
|
|
+ if (this.#on_skip === null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.#on_skip(new import_process_fail(count, error));
|
|
|
+ } catch (fail) {
|
|
|
+ console.log(fail);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ results() {
|
|
|
+ return Array.from(this.#processed.values());
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/product_response.js
|
|
|
+ var product_response = class extends bool_response {
|
|
|
+ #product;
|
|
|
+ constructor(target) {
|
|
|
+ super(target);
|
|
|
+ this.#product = null;
|
|
|
+ if (this.result) {
|
|
|
+ if (!("product" in target)) {
|
|
|
+ throw new Error("Incomplete response with good status.");
|
|
|
+ }
|
|
|
+ this.#product = new product(target.product);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ get product() {
|
|
|
+ return this.#product;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/product_get_request.js
|
|
|
+ var product_get_request = class extends request {
|
|
|
+ #barcode;
|
|
|
+ constructor(barcode) {
|
|
|
+ super();
|
|
|
+ this.#barcode = barcode;
|
|
|
+ }
|
|
|
+ get _response() {
|
|
|
+ return product_response;
|
|
|
+ }
|
|
|
+ get data() {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ get method() {
|
|
|
+ return "GET";
|
|
|
+ }
|
|
|
+ get url() {
|
|
|
+ return "/product/get/barcode/" + new String(this.#barcode);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/import_loop.js
|
|
|
+ var import_loop = class {
|
|
|
+ #content;
|
|
|
+ #failed;
|
|
|
+ #on_autocomplete;
|
|
|
+ #on_create;
|
|
|
+ #on_single_fail;
|
|
|
+ #on_skip;
|
|
|
+ #on_single_success;
|
|
|
+ #finally;
|
|
|
+ on_autocomplete(target) {
|
|
|
+ this.#on_autocomplete = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ on_create(target) {
|
|
|
+ this.#on_create = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ on_single_fail(target) {
|
|
|
+ this.#on_single_fail = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ on_skip(target) {
|
|
|
+ this.#on_skip = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ on_single_success(target) {
|
|
|
+ this.#on_single_success = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ finally(target) {
|
|
|
+ this.#finally = target;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ constructor(dataset) {
|
|
|
+ this.#content = dataset;
|
|
|
+ this.#failed = new Array();
|
|
|
+ this.#on_autocomplete = null;
|
|
|
+ this.#on_create = null;
|
|
|
+ this.#on_single_fail = null;
|
|
|
+ this.#on_skip = null;
|
|
|
+ this.#on_single_success = null;
|
|
|
+ this.#finally = null;
|
|
|
+ }
|
|
|
+ async #autocomplete(target) {
|
|
|
+ if (this.#on_autocomplete !== null) {
|
|
|
+ try {
|
|
|
+ this.#on_autocomplete(target);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const request2 = new autocomplete_request(target.barcode);
|
|
|
+ const response = await request2.connect();
|
|
|
+ if (!response.result) {
|
|
|
+ throw new Error(response.cause);
|
|
|
+ }
|
|
|
+ const found = response.found;
|
|
|
+ target.description = found.description;
|
|
|
+ if (found.image.length === 0) {
|
|
|
+ throw new Error("Image for " + target.barcode + " not found.");
|
|
|
+ }
|
|
|
+ return new create_request(target, found.image);
|
|
|
+ }
|
|
|
+ async process() {
|
|
|
+ for (const count of this.#content) {
|
|
|
+ try {
|
|
|
+ await this.#create(count);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ if (this.#on_single_fail !== null) {
|
|
|
+ try {
|
|
|
+ this.#on_single_fail(count);
|
|
|
+ } catch (error2) {
|
|
|
+ console.log(error2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.#failed.push(count);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this.#finally !== null) {
|
|
|
+ try {
|
|
|
+ this.#finally(this.#failed);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ async #exists(target) {
|
|
|
+ const request2 = new product_get_request(target.barcode);
|
|
|
+ const response = await request2.connect();
|
|
|
+ return response.product !== null;
|
|
|
+ }
|
|
|
+ async #create(target) {
|
|
|
+ if (await this.#exists(target)) {
|
|
|
+ try {
|
|
|
+ this.#on_skip(target);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const request2 = await this.#autocomplete(target);
|
|
|
+ if (this.on_create !== null) {
|
|
|
+ try {
|
|
|
+ this.#on_create(target);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const response = await request2.connect();
|
|
|
+ if (!response.result) {
|
|
|
+ throw new Error(response.cause);
|
|
|
+ }
|
|
|
+ if (this.#on_single_success !== null) {
|
|
|
+ try {
|
|
|
+ this.#on_single_success(target);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // application/scripts/import_products.js
|
|
|
+ var import_products = class extends formscreen {
|
|
|
+ #file;
|
|
|
+ #content;
|
|
|
+ get _name() {
|
|
|
+ return "Import products JSON";
|
|
|
+ }
|
|
|
+ _build_form() {
|
|
|
+ this._create_input("file", "Database:", "", (input) => {
|
|
|
+ this.#file = input;
|
|
|
+ input.type = "file";
|
|
|
+ input.accept = "application/json";
|
|
|
+ });
|
|
|
+ }
|
|
|
+ async #load_file() {
|
|
|
+ if (this.#file.files.length === 0) {
|
|
|
+ throw new Error("Select JSON products database first.");
|
|
|
+ }
|
|
|
+ const file = this.#file.files.item(0);
|
|
|
+ const text = await file.text();
|
|
|
+ return JSON.parse(text);
|
|
|
+ }
|
|
|
+ async _process() {
|
|
|
+ try {
|
|
|
+ this._info = "Loading file...";
|
|
|
+ this.#content = await this.#load_file();
|
|
|
+ this._info = "Parsing file to dataset...";
|
|
|
+ const dataset = new database(this.#content).on_skip((fail) => {
|
|
|
+ this._info = "Skipping " + fail.product.barcode + "...";
|
|
|
+ }).process().results();
|
|
|
+ const loop = new import_loop(dataset).on_autocomplete((target) => {
|
|
|
+ this._info = "Searching for " + target.barcode + "...";
|
|
|
+ }).on_create((target) => {
|
|
|
+ this._info = "Creating " + target.barcode + "...";
|
|
|
+ }).on_single_fail((target) => {
|
|
|
+ this._info = "Can not add " + target.barcode + "...";
|
|
|
+ }).on_skip((target) => {
|
|
|
+ this._info = "Skipping " + target.barcode + "...";
|
|
|
+ }).on_single_success((target) => {
|
|
|
+ this._info = "Created " + target.barcode + " success.";
|
|
|
+ }).finally((broken) => {
|
|
|
+ searcher.reload();
|
|
|
+ if (broken.length === 0) {
|
|
|
+ this._success = "All items imported.";
|
|
|
+ setTimeout(() => {
|
|
|
+ this.hide();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ console.log(broken);
|
|
|
+ this._success = "Not all items imported...";
|
|
|
+ }
|
|
|
+ }).process();
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ this._error = new String(error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
// application/scripts/login_bar.js
|
|
|
var login_bar = class {
|
|
|
#manager;
|
|
|
@@ -1772,9 +2252,17 @@
|
|
|
add_product_button.classList.add("add-product-button");
|
|
|
add_product_button.classList.add("material-icons");
|
|
|
target.appendChild(add_product_button);
|
|
|
+ const import_products_button = document.createElement("button");
|
|
|
+ import_products_button.innerText = "dataset_linked";
|
|
|
+ import_products_button.classList.add("material-icons");
|
|
|
+ import_products_button.classList.add("import-products-button");
|
|
|
+ target.appendChild(import_products_button);
|
|
|
add_product_button.addEventListener("click", () => {
|
|
|
new product_adder().show();
|
|
|
});
|
|
|
+ import_products_button.addEventListener("click", () => {
|
|
|
+ new import_products().show();
|
|
|
+ });
|
|
|
logout_button.addEventListener("click", () => {
|
|
|
this.#manager.logout();
|
|
|
location.reload();
|