product_adder.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import { formscreen } from "./formscreen.js";
  2. import { create_request } from "./create_request.js";
  3. import { bool_response } from "./bool_response.js";
  4. import { product_base } from "./product_base.js";
  5. import { searcher } from "./searcher.js";
  6. import { autocomplete_request } from "./autocomplete_request.js";
  7. import { autocomplete_response } from "./autocomplete_response.js";
  8. import { product_give_back } from "./product_give_back.js";
  9. export class product_adder extends formscreen {
  10. #name;
  11. #description;
  12. #author;
  13. #barcode;
  14. #stock_count;
  15. #image;
  16. #loaded_image_type;
  17. #loaded_image;
  18. #image_preview;
  19. get _name() {
  20. return _("add-product");
  21. }
  22. async #autocomplete() {
  23. const barcode = this.#barcode();
  24. if (barcode.length === 0) {
  25. this._info = _("fill-barcode-first");
  26. return;
  27. }
  28. this._info = _("searching-in-the-web");
  29. try {
  30. const request = new autocomplete_request(barcode);
  31. const response = await request.connect();
  32. if (!response.result) {
  33. throw new Error(response.cause);
  34. }
  35. const product = response.found;
  36. this.#name(product.title);
  37. this.#description(product.description);
  38. this.#author(product.author);
  39. this.#barcode(product.barcode);
  40. this.#loaded_image = product.image;
  41. this.#loaded_image_type = product.image_type;
  42. this.#update_image_preview();
  43. this._info = _("autocomplete-ready-check-results");
  44. } catch (error) {
  45. this._error = new String(error);
  46. }
  47. }
  48. #update_image_preview() {
  49. this.#image_preview.src = (
  50. "data:"
  51. + this.#loaded_image_type
  52. + ";base64,"
  53. + this.#loaded_image
  54. );
  55. this.#image_preview.style.opacity = "1";
  56. }
  57. get #autocomplete_button() {
  58. const button = document.createElement("div");
  59. button.classList.add("autocomplete-button");
  60. button.classList.add("button");
  61. const icon = document.createElement("span");
  62. icon.classList.add("material-icons")
  63. icon.innerText = "auto_fix_normal";
  64. button.appendChild(icon);
  65. const text = document.createElement("span");
  66. text.classList.add("text");
  67. text.innerText = _("autocomplete");
  68. button.appendChild(text);
  69. return button;
  70. }
  71. _build_form() {
  72. this.#loaded_image = null;
  73. this.#loaded_image_type = null;
  74. this.#name = this._create_input(
  75. "name",
  76. _("name-prompt"),
  77. _("name-sample")
  78. );
  79. this.#description = this._create_input(
  80. "description",
  81. _("description-prompt"),
  82. _("description-sample")
  83. );
  84. this.#author = this._create_input(
  85. "author",
  86. _("author-prompt"),
  87. _("author-sample")
  88. );
  89. this.#barcode = this._create_input(
  90. "barcode",
  91. _("barcode-prompt"),
  92. _("barcode-sample"),
  93. (input) => { input.type = "number"; }
  94. );
  95. this.#stock_count = this._create_input(
  96. "stock_count",
  97. _("stock-count-prompt"),
  98. _("stock-count-sample"),
  99. (input) => { input.type = "number"; }
  100. );
  101. this._create_input(
  102. "image",
  103. _("image-prompt"),
  104. "",
  105. (input) => {
  106. this.#image = input;
  107. input.type = "file";
  108. input.accept = "image/*";
  109. input.addEventListener("change", () => {
  110. this.#load_image_from_file();
  111. });
  112. }
  113. );
  114. this.#image_preview = document.createElement("img");
  115. this.#image_preview.style.opacity = "0";
  116. this._append_child(this.#image_preview);
  117. const autocomplete = this.#autocomplete_button;
  118. this._append_child(autocomplete);
  119. autocomplete.addEventListener("click", () => {
  120. this.#autocomplete();
  121. });
  122. }
  123. #reset_image() {
  124. this.#loaded_image = null;
  125. this.#loaded_image_type = null;
  126. this.#image_preview.style.opacity = "0";
  127. this.#image_preview.src = "";
  128. }
  129. async #load_image_from_file() {
  130. if (this.#image.files.length === 0) {
  131. this.#reset_image();
  132. }
  133. const file = this.#image.files.item(0);
  134. const buffer = await file.arrayBuffer();
  135. let as_string = new String();
  136. new Uint8Array(buffer).forEach(letter => {
  137. as_string += String.fromCharCode(letter);
  138. });
  139. this.#loaded_image = btoa(as_string);
  140. this.#loaded_image_type = file.type;
  141. this.#update_image_preview();
  142. }
  143. get #ready_image() {
  144. if (this.#loaded_image === null) {
  145. throw new Error(_("load-any-image-first"));
  146. }
  147. return this.#loaded_image;
  148. }
  149. async #submit() {
  150. const product = new product_base();
  151. product.name = this.#name();
  152. product.description = this.#description();
  153. product.author = this.#author();
  154. product.stock_count = this.#stock_count();
  155. product.barcode = this.#barcode();
  156. const request = new create_request(product, this.#ready_image);
  157. const response = await request.connect();
  158. if (!response.result) {
  159. throw new Error(response.cause);
  160. }
  161. }
  162. async _process() {
  163. try {
  164. this._info = _("creating-new-product");
  165. await this.#submit();
  166. this._success = _("created-new-product-success");
  167. searcher.reload();
  168. setTimeout(() => {
  169. this.hide();
  170. }, 500);
  171. } catch (error) {
  172. this._error = new String(error);
  173. }
  174. }
  175. }