feat(JavaScript): Updated architecture for TableBasePage object with static row ID attribute attached for adding ID against each row added to DOM

This commit is contained in:
2024-10-18 22:25:07 +01:00
parent 697963e28a
commit 7b6266e2f6
116 changed files with 7534 additions and 3840 deletions

View File

@@ -139,6 +139,51 @@ export default class API {
dataRequest[flagComment] = comment;
return await API.request(hashSaveStoreStockItem, 'POST', dataRequest);
}
// suppliers
static async getSuppliers() {
return await API.request(hashGetStoreSupplier);
}
static async getSuppliersByFilters(filtersJson) {
API.goToHash(hashPageStoreSuppliers, filtersJson);
}
static async saveSuppliers(suppliers, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);
dataRequest[flagSupplier] = suppliers;
dataRequest[flagComment] = comment;
return await API.request(hashSaveStoreSupplier, 'POST', dataRequest);
}
// supplier purchase orders
static async getSupplierPurchaseOrders() {
return await API.request(hashGetStoreSupplierPurchaseOrder);
}
static async getSupplierPurchaseOrdersByFilters(filtersJson) {
API.goToHash(hashPageStoreSupplierPurchaseOrders, filtersJson);
}
static async saveSupplierPurchaseOrders(supplierPurchaseOrders, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);
dataRequest[flagSupplierPurchaseOrder] = supplierPurchaseOrders;
dataRequest[flagComment] = comment;
return await API.request(hashSaveStoreSupplierPurchaseOrder, 'POST', dataRequest);
}
// manufacturing purchase orders
static async getManufacturingPurchaseOrders() {
return await API.request(hashGetStoreManufacturingPurchaseOrder);
}
static async getManufacturingPurchaseOrdersByFilters(filtersJson) {
API.goToHash(hashPageStoreManufacturingPurchaseOrders, filtersJson);
}
static async saveManufacturingPurchaseOrders(manufacturingPurchaseOrders, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);
dataRequest[flagManufacturingPurchaseOrder] = manufacturingPurchaseOrders;
dataRequest[flagComment] = comment;
return await API.request(hashSaveStoreManufacturingPurchaseOrder, 'POST', dataRequest);
}
}
/*

View File

@@ -91,6 +91,10 @@ export default class DOM {
if (container == null) return false;
return container.querySelector('.' + flagDirty) != null;
}
static hasDirtyChildrenNotDeletedContainer(container) {
if (container == null) return false;
return container.querySelector('.' + flagDirty + ':not(.' + flagDelete + ')') != null;
}
static getElementValueCurrent(element) {
let returnVal = '';
@@ -117,6 +121,7 @@ export default class DOM {
return returnVal;
}
static getElementAttributeValueCurrent(element) {
if (Validation.isEmpty(element)) return null;
return element.getAttribute(attrValueCurrent);
if (!Validation.isEmpty(value) && element.type === "checkbox") {
value = (value === 'true');
@@ -124,6 +129,7 @@ export default class DOM {
return value;
}
static getElementAttributeValuePrevious(element) {
if (Validation.isEmpty(element)) return null;
return element.getAttribute(attrValuePrevious);
if (!Validation.isEmpty(value) && element.type === "checkbox") {
value = (value === 'true');
@@ -134,13 +140,13 @@ export default class DOM {
static updateAndCheckIsTableElementDirty(element) {
let wasDirty = DOM.isElementDirty(element);
let row = DOM.getRowFromElement(element);
let wasDirtyRow = DOM.hasDirtyChildrenContainer(row);
let wasDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
let isDirty = DOM.updateAndCheckIsElementDirty(element);
let cell = DOM.getCellFromElement(element);
console.log({element, row, cell, isDirty, wasDirty});
if (isDirty != wasDirty) {
DOM.handleDirtyElement(cell, isDirty);
let isDirtyRow = DOM.hasDirtyChildrenContainer(row);
let isDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
console.log({isDirtyRow, wasDirtyRow});
if (isDirtyRow != wasDirtyRow) {
DOM.handleDirtyElement(row, isDirtyRow);

View File

@@ -45,6 +45,7 @@ export default class BasePage {
// hookupVideos();
this.hookupNavigation();
this.hookupImagesLogo();
this.hookupOverlays();
}
hookupNavigation() {
@@ -75,8 +76,11 @@ export default class BasePage {
this.hookupButtonsNavUserLogout();
this.hookupButtonsNavUserLogin();
this.hookupButtonsNavStoreHome();
this.hookupButtonsNavStoreManufacturingPurchaseOrders();
this.hookupButtonsNavStoreProductPermutations();
this.hookupButtonsNavStoreStockItems();
this.hookupButtonsNavStoreSuppliers();
this.hookupButtonsNavStoreSupplierPurchaseOrders();
this.hookupButtonsNavAdminHome();
}
hookupEventHandler(eventType, selector, callback) {
@@ -131,6 +135,9 @@ export default class BasePage {
hookupButtonsNavStoreHome() {
this.hookupButtonsNav('.' + flagNavStoreHome, hashPageStoreHome);
}
hookupButtonsNavStoreManufacturingPurchaseOrders() {
this.hookupButtonsNav('.' + flagNavStoreManufacturingPurchaseOrders, hashPageStoreManufacturingPurchaseOrders);
}
hookupButtonsNavStoreProductCategories() {
this.hookupButtonsNav('.' + flagNavStoreProductCategories, hashPageStoreProductCategories);
}
@@ -152,14 +159,25 @@ export default class BasePage {
hookupButtonsNavAdminHome() {
this.hookupButtonsNav('.' + flagNavAdminHome, hashPageAdminHome);
}
hookupButtonsNavStoreSuppliers() {
this.hookupButtonsNav('.' + flagNavStoreSuppliers, hashPageStoreSuppliers);
}
hookupButtonsNavStoreSupplierPurchaseOrders() {
this.hookupButtonsNav('.' + flagNavStoreSupplierPurchaseOrders, hashPageStoreSupplierPurchaseOrders);
}
hookupImagesLogo() {
this.hookupButtonsNav("img." + flagImageLogo, hashPageHome);
}
hookupOverlays() {
this.hookupOverlayFromId(idOverlayConfirm);
this.hookupOverlayFromId(idOverlayError);
}
hookupOverlayFromId(idOverlay) {
Events.initialiseEventHandler(idOverlay, flagInitialised, (overlay) => {
overlay.querySelector('button.' + flagClose).addEventListener("click", (event) => {
overlay.querySelector('button.' + flagCancel).addEventListener("click", (event) => {
event.stopPropagation();
overlay.css('display', 'none');
});

View File

@@ -168,10 +168,10 @@ export default class TableBasePage extends BasePage {
.catch(error => console.error('Error:', error));
}
getTableRecords(dirtyOnly = false) {
let table = this.getTableMain();
// let table = this.getTableMain();
let records = [];
let record;
table.querySelectorAll('tbody tr').forEach((row) => {
document.querySelectorAll(idTableMain + ' > tbody > tr').forEach((row) => {
if (dirtyOnly && !row.classList.contains(flagDirty)) return;
record = this.getJsonRow(row);
records.push(record);
@@ -221,6 +221,8 @@ export default class TableBasePage extends BasePage {
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
element.classList.remove(flagInitialised);
});
let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;
row.setAttribute(this.constructor.attrIdRowObject, -1 - countRows);
/* Shared nethods
let newDisplayOrder = parseInt(tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider).getAttribute(attrValueCurrent)) + 1;
let slider = tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
@@ -285,19 +287,19 @@ export default class TableBasePage extends BasePage {
input.addEventListener("change", (event) => {
handler(event, input);
});
this.handleChangeElementCellTable(null, input);
handler(null, input);
});
// this.hookupEventHandler("change", inputSelector, handler);
}
handleChangeElementCellTable(event, element) {
let row = DOM.getRowFromElement(element);
let td = DOM.getCellFromElement(element);
let wasDirtyRow = DOM.hasDirtyChildrenContainer(row);
let wasDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
let wasDirtyElement = element.classList.contains(flagDirty);
let isDirtyElement = DOM.updateAndCheckIsElementDirty(element);
if (isDirtyElement != wasDirtyElement) {
DOM.handleDirtyElement(td, isDirtyElement);
let isNowDirtyRow = DOM.hasDirtyChildrenContainer(row);
let isNowDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
if (isNowDirtyRow != wasDirtyRow) {
DOM.handleDirtyElement(row, isNowDirtyRow);
let rows = this.getTableRecords(true);
@@ -419,7 +421,7 @@ export default class TableBasePage extends BasePage {
let row = DOM.getRowFromElement(ddl);
let td = DOM.getCellFromElement(ddl);
console.log("td: ", td);
let wasDirtyRow = DOM.hasDirtyChildrenContainer(row);
let wasDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
let wasDirtyElement = ddl.classList.contains(flagDirty);
let isDirtyElement = DOM.updateAndCheckIsElementDirty(ddl);
console.log("isDirtyElement: ", isDirtyElement);
@@ -428,7 +430,7 @@ export default class TableBasePage extends BasePage {
DOM.handleDirtyElement(td, isDirtyElement);
let optionSelected = ddl.options[ddl.selectedIndex];
DOM.setElementAttributeValueCurrent(td, optionSelected.value);
let isNowDirtyRow = DOM.hasDirtyChildrenContainer(row);
let isNowDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);
console.log("isNowDirtyRow: ", isNowDirtyRow);
console.log("wasDirtyRow: ", wasDirtyRow);
if (isNowDirtyRow != wasDirtyRow) {
@@ -460,13 +462,16 @@ export default class TableBasePage extends BasePage {
let thead = document.createElement("thead");
let tr = document.createElement("tr");
let thVariationType = document.createElement("th");
thVariationType.classList.add(flagProductVariationType);
thVariationType.textContent = 'Type';
let thNameVariation = document.createElement("th");
thNameVariation.classList.add(flagProductVariation);
thNameVariation.textContent = 'Name';
let buttonAdd = document.createElement("button");
buttonAdd.classList.add(flagAdd);
buttonAdd.textContent = '+';
let thAddDelete = document.createElement("th");
thAddDelete.classList.add(flagAdd);
thAddDelete.appendChild(buttonAdd);
tr.appendChild(thVariationType);
tr.appendChild(thNameVariation);
@@ -484,9 +489,10 @@ export default class TableBasePage extends BasePage {
});
}
tblVariations.appendChild(tbody);
let parent = element.parentElement;
parent.innerHTML = '';
parent.appendChild(tblVariations);
let cellParent = element.closest(idTableMain + ' tbody tr td.' + flagProductVariations);
cellParent.innerHTML = '';
cellParent.appendChild(tblVariations);
console.log("tblVariations: ", tblVariations);
let selectorButtonAdd = idTableMain + ' td.' + flagProductVariations + ' button.' + flagAdd;
this.hookupEventHandler("click", selectorButtonAdd, this.handleClickButtonProductPermutationVariationsAdd);
@@ -496,6 +502,9 @@ export default class TableBasePage extends BasePage {
toggleColumnCollapsed(flagColumn, isCollapsed) {
this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagCollapsed);
}
toggleColumnHeaderCollapsed(flagColumn, isCollapsed) {
this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagCollapsed);
}
getElementProductVariations(element) {
let permutationVariations = element.getAttribute(attrValueCurrent);
let objVariations = [];
@@ -636,6 +645,10 @@ export default class TableBasePage extends BasePage {
return variationPairsString;
}
hookupCurrencyFields() {
this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagCurrency, Utils.getListFromDict(currencies));
}
leave() {
if (this.constructor === TableBasePage) {
throw new Error("Must implement leave() method.");
@@ -653,12 +666,17 @@ export default class TableBasePage extends BasePage {
let columnTh = table.querySelector('th.' + columnFlag);
let columnThHasFlag = columnTh.classList.contains(classnameFlag);
if (isRequiredFlag == columnThHasFlag) return;
let columnTds = table.querySelectorAll('td.' + columnFlag);
DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);
let columnTds = table.querySelectorAll('td.' + columnFlag);
columnTds.forEach((columnTd) => {
DOM.toggleElementHasClassnameFlag(columnTd, isRequiredFlag, classnameFlag);
});
}
toggleColumnHeaderHasClassnameFlag(columnFlag, isRequiredFlag, classnameFlag) {
let table = this.getTableMain();
let columnTh = table.querySelector('th.' + columnFlag);
DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);
}
}
@@ -669,7 +687,9 @@ import DOM from "../dom.js";
export class PageStoreProductCategories extends TableBasePage {
static hash = hashPageStoreProductCategories;
static attrIdRowObject = attrIdProductCategory;
callFilterTableContent = API.getCategoriesByFilters;
callSaveTableContent = API.saveCategories;
constructor() {}
initialize() {}

View File

@@ -0,0 +1,82 @@
import API from "../../api.js";
import BusinessObjects from "../../lib/business_objects.js";
import DOM from "../../dom.js";
import Events from "../../lib/events.js";
import TableBasePage from "../base_table.js";
import Utils from "../../lib/utils.js";
import Validation from "../../lib/validation.js";
import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreSupplierPurchaseOrders extends TableBasePage {
static hash = hashPageStoreSupplierPurchaseOrders;
static attrIdRowObject = attrIdSupplierPurchaseOrder;
callFilterTableContent = API.getSupplierPurchaseOrdersByFilters;
callSaveTableContent = API.saveSupplierPurchaseOrders;
constructor(router) {
super(router);
this.storeMixin = new StoreTableMixinPage(this);
}
initialize() {
this.sharedInitialize();
}
hookupFilters() {
this.sharedHookupFilters();
this.hookupFilterActive();
}
loadRowTable(rowJson) {
}
getJsonRow(row) {
if (row == null) return;
let tdCurrency = row.querySelector('td.' + flagCurrency);
let inputCostTotalLocalVatExcl = row.querySelector('td.' + flagCostTotalLocalVatExcl + ' input');
let inputCostTotalLocalVatIncl = row.querySelector('td.' + flagCostTotalLocalVatIncl + ' input');
let inputPriceTotalLocalVatExcl = row.querySelector('td.' + flagPriceTotalLocalVatExcl + ' input');
let inputPriceTotalLocalVatIncl = row.querySelector('td.' + flagPriceTotalLocalVatIncl + ' input');
let tdItems = row.querySelector('td.' + flagItems);
let checkboxActive = row.querySelector('td.' + flagActive + ' textarea');
let jsonRow = {};
jsonRow[attrIdSupplierPurchaseOrder] = row.getAttribute(attrIdSupplierPurchaseOrder);
jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency);
jsonRow[flagCostTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatExcl);
jsonRow[flagCostTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatIncl);
jsonRow[flagPriceTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputPriceTotalLocalVatExcl);
jsonRow[flagPriceTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputPriceTotalLocalVatIncl);
jsonRow[flagItems] = DOM.getElementAttributeValueCurrent(tdItems);
jsonRow[flagActive] = DOM.getElementAttributeValueCurrent(checkboxActive);
return jsonRow;
}
initialiseRowNew(row) {
super.initialiseRowNew(row);
}
hookupTableMain() {
super.hookupTableMain();
this.hookupCurrencyFields();
this.hookupCostInputs();
this.hookupOrderItemsFields();
this.hookupActiveCheckboxes();
}
hookupCostInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatExcl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatIncl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPriceTotalLocalVatExcl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPriceTotalLocalVatIncl + ' input');
}
hookupOrderItemsFields() {
}
hookupActiveCheckboxes(){
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagActive + ' input');
}
leave() {
super.leave();
}
}

View File

@@ -7,6 +7,7 @@ import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreProductCategories extends TableBasePage {
static hash = hashPageStoreProductCategories;
static attrIdRowObject = attrIdProductCategory;
callFilterTableContent = API.getCategoriesByFilters;
callSaveTableContent = API.saveCategories;

View File

@@ -10,6 +10,7 @@ import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreProductPermutations extends TableBasePage {
static hash = hashPageStoreProductPermutations;
static attrIdRowObject = attrIdProductPermutation;
callFilterTableContent = API.getProductPermutationsByFilters;
callSaveTableContent = API.saveProductPermutations;

View File

@@ -8,6 +8,7 @@ import Utils from "../../lib/utils.js";
export default class PageStoreProducts extends TableBasePage {
static hash = hashPageStoreProducts;
static attrIdRowObject = attrIdProduct;
callFilterTableContent = API.getProductsByFilters;
callSaveTableContent = API.saveProducts;

View File

@@ -10,6 +10,7 @@ import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreStockItems extends TableBasePage {
static hash = hashPageStoreStockItems;
static attrIdRowObject = attrIdStockItem;
callFilterTableContent = API.getStockItemsByFilters;
callSaveTableContent = API.saveStockItems;
@@ -73,8 +74,8 @@ export default class PageStoreStockItems extends TableBasePage {
let tdProduct = row.querySelector('td.' + flagProduct);
let tdProductVariations = row.querySelector('td.' + flagProductVariations);
let tdCurrencyCost = row.querySelector('td.' + flagCurrencyCost);
let inputCostLocalVatExcl = row.querySelector('td.' + flagCostLocalVatExcl + ' input');
let inputCostLocalVatIncl = row.querySelector('td.' + flagCostLocalVatIncl + ' input');
let inputCostLocalVatExcl = row.querySelector('td.' + flagCostUnitLocalVatExcl + ' input');
let inputCostLocalVatIncl = row.querySelector('td.' + flagCostUnitLocalVatIncl + ' input');
let inputDatePurchased = row.querySelector('td.' + flagDatePurchased + ' input');
let inputDateReceived = row.querySelector('td.' + flagDateReceived + ' input');
let tdStorageLocation = row.querySelector('td.' + flagStorageLocation);
@@ -93,8 +94,8 @@ export default class PageStoreStockItems extends TableBasePage {
jsonRow[flagProductVariations] = DOM.getElementAttributeValueCurrent(tdProductVariations);
jsonRow[flagHasVariations] = jsonRow[flagProductVariations] != '';
jsonRow[flagCurrencyCost] = DOM.getElementAttributeValueCurrent(tdCurrencyCost);
jsonRow[flagCostLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatExcl);
jsonRow[flagCostLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatIncl);
jsonRow[flagCostUnitLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatExcl);
jsonRow[flagCostUnitLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatIncl);
jsonRow[flagDatePurchased] = DOM.getElementAttributeValueCurrent(inputDatePurchased);
jsonRow[flagDateReceived] = DOM.getElementAttributeValueCurrent(inputDateReceived);
jsonRow[attrIdStorageLocation] = DOM.getElementAttributeValueCurrent(tdStorageLocation);
@@ -189,8 +190,8 @@ export default class PageStoreStockItems extends TableBasePage {
this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagCurrencyCost, Utils.getListFromDict(currencies));
}
hookupCostInputs(){
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostLocalVatExcl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostLocalVatIncl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostUnitLocalVatExcl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostUnitLocalVatIncl + ' input');
}
hookupOrderDateInputs(){
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDatePurchased + ' input');

View File

@@ -0,0 +1,82 @@
import API from "../../api.js";
import BusinessObjects from "../../lib/business_objects.js";
import DOM from "../../dom.js";
import Events from "../../lib/events.js";
import TableBasePage from "../base_table.js";
import Utils from "../../lib/utils.js";
import Validation from "../../lib/validation.js";
import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreSupplierPurchaseOrders extends TableBasePage {
static hash = hashPageStoreSupplierPurchaseOrders;
static attrIdRowObject = attrIdSupplierPurchaseOrder;
callFilterTableContent = API.getSupplierPurchaseOrdersByFilters;
callSaveTableContent = API.saveSupplierPurchaseOrders;
constructor(router) {
super(router);
this.storeMixin = new StoreTableMixinPage(this);
}
initialize() {
this.sharedInitialize();
}
hookupFilters() {
this.sharedHookupFilters();
this.hookupFilterActive();
}
loadRowTable(rowJson) {
}
getJsonRow(row) {
if (row == null) return;
let tdSupplier = row.querySelector('td.' + flagSupplier);
let tdCurrency = row.querySelector('td.' + flagCurrency);
let inputCostTotalLocalVatExcl = row.querySelector('td.' + flagCostTotalLocalVatExcl + ' input');
let inputCostTotalLocalVatIncl = row.querySelector('td.' + flagCostTotalLocalVatIncl + ' input');
let tdItems = row.querySelector('td.' + flagItems);
let checkboxActive = row.querySelector('td.' + flagActive + ' textarea');
let jsonRow = {};
jsonRow[attrIdSupplierPurchaseOrder] = row.getAttribute(attrIdSupplierPurchaseOrder);
jsonRow[attrIdSupplier] = DOM.getElementAttributeValueCurrent(tdSupplier);
jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency);
jsonRow[flagCostTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatExcl);
jsonRow[flagCostTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatIncl);
jsonRow[flagItems] = DOM.getElementAttributeValueCurrent(tdItems);
jsonRow[flagActive] = DOM.getElementAttributeValueCurrent(checkboxActive);
return jsonRow;
}
initialiseRowNew(row) {
super.initialiseRowNew(row);
}
hookupTableMain() {
super.hookupTableMain();
this.hookupSupplierFields();
this.hookupCurrencyFields();
this.hookupCostInputs();
this.hookupOrderItemsFields();
this.hookupActiveCheckboxes();
}
hookupSupplierFields() {
this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagSupplier, Utils.getListFromDict(suppliers));
}
hookupCostInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatExcl + ' input');
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatIncl + ' input');
}
hookupOrderItemsFields() {
}
hookupActiveCheckboxes(){
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagActive + ' input');
}
leave() {
super.leave();
}
}

View File

@@ -0,0 +1,388 @@
import API from "../../api.js";
import BusinessObjects from "../../lib/business_objects.js";
import DOM from "../../dom.js";
import Events from "../../lib/events.js";
import TableBasePage from "../base_table.js";
import Utils from "../../lib/utils.js";
import Validation from "../../lib/validation.js";
import StoreTableMixinPage from "./mixin_table.js";
export default class PageStoreSuppliers extends TableBasePage {
static hash = hashPageStoreSuppliers;
static attrIdRowObject = attrIdSupplier;
callFilterTableContent = API.getSuppliersByFilters;
callSaveTableContent = API.saveSuppliers;
constructor(router) {
super(router);
this.storeMixin = new StoreTableMixinPage(this);
}
initialize() {
this.sharedInitialize();
}
hookupFilters() {
this.sharedHookupFilters();
this.hookupFilterActive();
}
loadRowTable(rowJson) {
}
getJsonRow(row) {
if (row == null) return;
let textareaNameCompany = row.querySelector('td.' + flagNameCompany + ' textarea');
let textareaNameContact = row.querySelector('td.' + flagNameContact + ' textarea');
let textareaDepartmentContact = row.querySelector('td.' + flagDepartmentContact + ' textarea');
let tdAddress = row.querySelector('td.' + flagAddress);
let textareaPhoneNumber = row.querySelector('td.' + flagPhoneNumber + ' textarea');
let textareaFax = row.querySelector('td.' + flagFax + ' textarea');
let textareaEmail = row.querySelector('td.' + flagEmail + ' textarea');
let textareaWebsite = row.querySelector('td.' + flagWebsite + ' textarea');
let tdCurrency = row.querySelector('td.' + flagCurrency);
let checkboxActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
let jsonRow = {};
jsonRow[attrIdSupplier] = row.getAttribute(attrIdSupplier);
jsonRow[flagNameCompany] = DOM.getElementAttributeValueCurrent(textareaNameCompany);
jsonRow[flagNameContact] = DOM.getElementAttributeValueCurrent(textareaNameContact);
jsonRow[flagDepartmentContact] = DOM.getElementAttributeValueCurrent(textareaDepartmentContact);
jsonRow[attrIdSupplierAddress] = DOM.getElementAttributeValueCurrent(tdAddress);
jsonRow[flagSupplierAddress] = this.getSupplierAddressesFromRow(row);
jsonRow[flagPhoneNumber] = DOM.getElementAttributeValueCurrent(textareaPhoneNumber);
jsonRow[flagFax] = DOM.getElementAttributeValueCurrent(textareaFax);
jsonRow[flagEmail] = DOM.getElementAttributeValueCurrent(textareaEmail);
jsonRow[flagWebsite] = DOM.getElementAttributeValueCurrent(textareaWebsite);
jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency);
jsonRow[flagActive] = DOM.getElementAttributeValueCurrent(checkboxActive);
return jsonRow;
}
getSupplierAddressesFromRow(row) {
let supplierAddresses = [];
let trs = row.querySelectorAll('td.' + flagAddress + ' tr');
let address, inputPostcode, inputAddressLine1, inputAddressLine2, inputCity, inputCounty, ddlRegion, inputActive;
trs.forEach((tr) => {
inputPostcode = tr.querySelector('td.' + flagPostcode + ' textarea');
inputAddressLine1 = tr.querySelector('td.' + flagAddressLine1 + ' textarea');
inputAddressLine2 = tr.querySelector('td.' + flagAddressLine2 + ' textarea');
inputCity = tr.querySelector('td.' + flagCity + ' textarea');
inputCounty = tr.querySelector('td.' + flagCounty + ' textarea');
ddlRegion = tr.querySelector('td.' + flagRegion + ' select');
inputActive = tr.querySelector('td.' + flagActive + ' input');
address = {
[attrIdSupplierAddress]: tr.getAttribute(attrIdSupplierAddress),
[flagPostcode]: DOM.getElementAttributeValueCurrent(inputPostcode),
[flagAddressLine1]: DOM.getElementAttributeValueCurrent(inputAddressLine1),
[flagAddressLine2]: DOM.getElementAttributeValueCurrent(inputAddressLine2),
[flagCity]: DOM.getElementAttributeValueCurrent(inputCity),
[flagCounty]: DOM.getElementAttributeValueCurrent(inputCounty),
[attrIdRegion]: DOM.getElementAttributeValueCurrent(ddlRegion),
[flagActive]: DOM.getElementAttributeValueCurrent(inputActive),
};
supplierAddresses.push(address);
});
return supplierAddresses;
}
initialiseRowNew(row) {
super.initialiseRowNew(row);
}
hookupTableMain() {
super.hookupTableMain();
this.hookupNameCompanyInputs();
this.hookupNameContactInputs();
this.hookupDepartmentContactInputs();
this.hookupAddressFields();
this.hookupPhoneNumberInputs();
this.hookupFaxInputs();
this.hookupEmailInputs();
this.hookupWebsiteInputs();
this.hookupCurrencyFields();
this.hookupActiveCheckboxes();
}
hookupNameCompanyInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagNameCompany + ' textarea');
}
hookupNameContactInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagNameContact + ' textarea');
}
hookupDepartmentContactInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDepartmentContact + ' textarea');
}
hookupAddressFields() {
this.hookupAddressPreviews();
this.hookupAddressPostcodeInputs();
this.hookupAddressLine1Inputs();
this.hookupAddressLine2Inputs();
this.hookupAddressCityInputs();
this.hookupAddressCountyInputs();
this.hookupAddressRegionDdls();
this.hookupAddressActiveCheckboxes();
this.hookupAddressDeleteButtons();
this.hookupAddressUndeleteButtons();
this.hookupAddressAddButtons();
}
hookupAddressPreviews() {
this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress, (event, td) => {
if (!td.classList.contains(flagCollapsed)) return;
this.handleClickAddressPreview(event, td);
});
}
handleClickAddressPreview(event, element) {
console.log("click address preview");
this.toggleColumnHeaderCollapsed(flagAddress, false);
element.classList.remove(flagCollapsed);
let row = DOM.getRowFromElement(element);
let idSupplier = row.getAttribute(attrIdSupplier);
let supplierAddressList = idSupplier > 0 ? supplierAddresses[idSupplier] : [];
let tblAddresses = document.createElement("table");
tblAddresses.classList.add(flagAddress);
let thead = document.createElement("thead");
let tr = document.createElement("tr");
let thPostcode = document.createElement("th");
thPostcode.classList.add(flagPostcode);
thPostcode.textContent = 'Postcode';
let thAddressLine1 = document.createElement("th");
thAddressLine1.classList.add(flagAddressLine1);
thAddressLine1.textContent = 'Address Line 1';
let thAddressLine2 = document.createElement("th");
thAddressLine2.classList.add(flagAddressLine2);
thAddressLine2.textContent = 'Address Line 2';
let thCity = document.createElement("th");
thCity.classList.add(flagCity);
thCity.textContent = 'City';
let thCounty = document.createElement("th");
thCounty.classList.add(flagCounty);
thCounty.textContent = 'County';
let thRegion = document.createElement("th");
thRegion.classList.add(flagRegion);
thRegion.textContent = 'Region';
let thActive = document.createElement("th");
thActive.classList.add(flagActive);
thActive.textContent = 'Active';
let thAddDelete = document.createElement("th");
thAddDelete.classList.add(flagAdd);
let buttonAdd = document.createElement("button");
buttonAdd.classList.add(flagAdd);
buttonAdd.textContent = '+';
thAddDelete.appendChild(buttonAdd);
tr.appendChild(thPostcode);
tr.appendChild(thAddressLine1);
tr.appendChild(thAddressLine2);
tr.appendChild(thCity);
tr.appendChild(thCounty);
tr.appendChild(thRegion);
tr.appendChild(thActive);
tr.appendChild(thAddDelete);
thead.appendChild(tr);
tblAddresses.appendChild(thead);
let tbody = document.createElement("tbody");
let regionOptions = Utils.getListFromDict(regions);
supplierAddressList.forEach((supplierAddress, index) => {
this.addRowSupplierAddress(tbody, supplierAddress, regionOptions);
});
tblAddresses.appendChild(tbody);
let cell = DOM.getCellFromElement(element);
let cellNew = cell.cloneNode(false);
cellNew.appendChild(tblAddresses);
row.replaceChild(cellNew, cell);
console.log("tblAddresses: ", tblAddresses);
this.hookupAddressFields();
}
addRowSupplierAddress(tbody, supplierAddress, regionOptions) {
console.log("addRowSupplierAddress: ", supplierAddress);
let tdPostcode = document.createElement("td");
tdPostcode.classList.add(flagPostcode);
let textareaPostcode = document.createElement("textarea");
textareaPostcode.classList.add(flagPostcode);
DOM.setElementValuesCurrentAndPrevious(textareaPostcode, supplierAddress[flagPostcode]);
tdPostcode.appendChild(textareaPostcode);
let tdAddressLine1 = document.createElement("td");
tdAddressLine1.classList.add(flagAddressLine1);
let textareaAddressLine1 = document.createElement("textarea");
textareaAddressLine1.classList.add(flagAddressLine1);
DOM.setElementValuesCurrentAndPrevious(textareaAddressLine1, supplierAddress[flagAddressLine1]);
tdAddressLine1.appendChild(textareaAddressLine1);
let tdAddressLine2 = document.createElement("td");
tdAddressLine2.classList.add(flagAddressLine2);
let textareaAddressLine2 = document.createElement("textarea");
textareaAddressLine2.classList.add(flagAddressLine2);
DOM.setElementValuesCurrentAndPrevious(textareaAddressLine2, supplierAddress[flagAddressLine2]);
tdAddressLine2.appendChild(textareaAddressLine2);
let tdCity = document.createElement("td");
tdCity.classList.add(flagCity);
let textareaCity = document.createElement("textarea");
textareaCity.classList.add(flagCity);
DOM.setElementValuesCurrentAndPrevious(textareaCity, supplierAddress[flagCity]);
tdCity.appendChild(textareaCity);
let tdCounty = document.createElement("td");
tdCounty.classList.add(flagCounty);
let textareaCounty = document.createElement("textarea");
textareaCounty.classList.add(flagCounty);
DOM.setElementValuesCurrentAndPrevious(textareaCounty, supplierAddress[flagCounty]);
tdCounty.appendChild(textareaCounty);
let region = supplierAddress[flagRegion];
if (!region) region = {[attrIdRegion]: ''};
let tdRegion = document.createElement("td");
tdRegion.classList.add(flagRegion);
DOM.setElementAttributesValuesCurrentAndPrevious(tdRegion, region[attrIdRegion]);
let ddlRegion = document.createElement("select");
ddlRegion.classList.add(flagRegion);
let optionJson, option;
regionOptions.forEach((regionOption) => {
optionJson = BusinessObjects.getOptionJsonFromObjectJson(regionOption);
option = DOM.createOption(optionJson);
ddlRegion.appendChild(option);
});
DOM.setElementValuesCurrentAndPrevious(ddlRegion, region[attrIdRegion]);
tdRegion.appendChild(ddlRegion);
let tdActive = document.createElement("td");
tdActive.classList.add(flagActive);
let checkboxActive = document.createElement("input");
checkboxActive.classList.add(flagActive);
checkboxActive.type = 'checkbox';
DOM.setElementValuesCurrentAndPrevious(checkboxActive, supplierAddress[flagActive]);
tdActive.appendChild(checkboxActive);
let tdDelete = document.createElement("td");
tdDelete.classList.add(flagDelete);
let buttonDelete = document.createElement("button");
buttonDelete.classList.add(flagDelete);
buttonDelete.textContent = 'x';
tdDelete.appendChild(buttonDelete);
let tr = document.createElement("tr");
tr.setAttribute(attrIdSupplierAddress, supplierAddress[attrIdSupplierAddress]);
tr.appendChild(tdPostcode);
tr.appendChild(tdAddressLine1);
tr.appendChild(tdAddressLine2);
tr.appendChild(tdCity);
tr.appendChild(tdCounty);
tr.appendChild(tdRegion);
tr.appendChild(tdActive);
tr.appendChild(tdDelete);
tbody.appendChild(tr);
}
hookupAddressPostcodeInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagPostcode);
}
hookupAddressLine1Inputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagAddressLine1);
}
hookupAddressLine2Inputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagAddressLine2);
}
hookupAddressCityInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagCity);
}
hookupAddressCountyInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagCounty);
}
hookupAddressRegionDdls() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' select.' + flagRegion);
}
hookupAddressActiveCheckboxes() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' input.' + flagActive, (event, element) => {
let rowSupplierAddress = element.closest('tr');
let idAddress = rowSupplierAddress.getAttribute(attrIdSupplierAddress);
DOM.setElementAttributeValueCurrent(rowSupplierAddress, idAddress);
let rowSupplier = rowSupplierAddress.closest(idTableMain + ' > tbody > tr');
let checkboxesActive = rowSupplier.querySelectorAll('td.' + flagAddress + ' input.' + flagActive);
let isActive = element.checked;
if (isActive) {
checkboxesActive.forEach((checkbox) => {
if (checkbox == element) return;
DOM.setElementValueCurrent(checkbox, false);
});
}
/*
else if (checkboxesActive.length > 0) {
DOM.setElementValueCurrent(checkboxesActive[0], false);
}
*/
});
}
hookupAddressDeleteButtons() {
this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' button.' + flagDelete, (event, element) => {
let row = DOM.getRowFromElement(element);
row.classList.add(flagDelete);
let buttonAdd = document.createElement("button");
buttonAdd.classList.add(flagAdd);
buttonAdd.textContent = '+';
element.replaceWith(buttonAdd);
this.hookupAddressUndeleteButtons();
});
}
hookupAddressUndeleteButtons() {
this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' td button.' + flagAdd, (event, element) => {
let row = DOM.getRowFromElement(element);
row.classList.remove(flagDelete);
let buttonDelete = document.createElement("button");
buttonDelete.classList.add(flagDelete);
buttonDelete.textContent = 'x';
element.replaceWith(buttonDelete);
this.hookupAddressDeleteButtons();
});
}
hookupAddressAddButtons() {
this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' th button.' + flagAdd, (event, element) => {
let row = element.closest(idTableMain + ' > tbody > tr');
let idSupplier = row.getAttribute(attrIdSupplier);
let hasActiveAddress = row.querySelectorAll('td.' + flagAddress + ' input.' + flagActive + ':checked').length > 0;
let countSupplierAddresses = row.querySelectorAll('td.' + flagAddress + ' td.' + flagAddress).length;
let supplierAddress = {
[attrIdSupplier]: idSupplier,
[attrIdSupplierAddress]: -1 - countSupplierAddresses,
[flagPostcode]: '',
[flagAddressLine1]: '',
[flagAddressLine2]: '',
[flagCity]: '',
[flagCounty]: '',
[attrIdRegion]: '',
[flagActive]: !hasActiveAddress,
};
let tbody = row.querySelector('td.' + flagAddress + ' table tbody');
this.addRowSupplierAddress(tbody, supplierAddress, Utils.getListFromDict(regions));
if (!hasActiveAddress) {
let tdAddress = row.querySelector('td.' + flagAddress);
// tdAddress.setAttribute(attrIdSupplierAddress, supplierAddress[attrIdSupplierAddress]);
DOM.setElementAttributeValueCurrent(tdAddress, supplierAddress[attrIdSupplierAddress]);
}
this.hookupAddressFields();
});
}
hookupPhoneNumberInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPhoneNumber + ' textarea');
}
hookupFaxInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagFax + ' textarea');
}
hookupEmailInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagEmail + ' textarea');
}
hookupWebsiteInputs() {
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagWebsite + ' textarea');
}
hookupActiveCheckboxes(){
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagActive + ' input');
}
leave() {
super.leave();
}
}

View File

@@ -12,12 +12,15 @@ import PageLicense from './pages/legal/license.js';
// Store
import PageStoreBasket from './pages/store/basket.js';
import PageStoreHome from './pages/store/home.js';
import PageStoreManufacturingPurchaseOrders from './pages/store/manufacturing_purchase_orders.js';
import PageStoreProductCategories from './pages/store/product_categories.js';
import PageStoreProductPermutations from './pages/store/product_permutations.js';
// import PageStoreProductPrices from './pages/store/product_prices.js';
import PageStoreProducts from './pages/store/products.js';
// import PageStoreProductVariations from './pages/store/product_variations.js';
import PageStoreStockItems from './pages/store/stock_items.js';
import PageStoreSuppliers from './pages/store/suppliers.js';
import PageStoreSupplierPurchaseOrders from './pages/store/supplier_purchase_orders.js';
// User
// import PageUserLogin from './pages/user/login.js';
// import PageUserLogout from './pages/user/logout.js';
@@ -77,12 +80,15 @@ export default class Router {
this.pages[hashPageLicense] = { name: 'PageLicense', module: PageLicense }; // pathModule: './pages/legal/license.js' };
this.pages[hashPagePrivacyPolicy] = { name: 'PagePrivacyPolicy', module: PagePrivacyPolicy }; // pathModule: './pages/legal/privacy_policy.js' }; // importModule: () => {return import(/* webpackChunkName: "page_privacy_policy" */ './pages/legal/privacy_policy.js'); }
// Store
this.pages[hashPageStoreManufacturingPurchaseOrders] = { name: 'PageManufacturingPurchaseOrders', module: PageStoreManufacturingPurchaseOrders }; // pathModule
this.pages[hashPageStoreProductCategories] = { name: 'PageStoreProductCategories', module: PageStoreProductCategories }; // pathModule: './pages/store/product_categories.js' };
this.pages[hashPageStoreProductPermutations] = { name: 'PageStoreProductPermutations', module: PageStoreProductPermutations }; // pathModule: './pages/store/product_permutations.js' };
// this.pages[hashPageStoreProductPrices] = { name: 'PageStoreProductPrices', module: PageStoreProductPrices }; // pathModule: './pages/store/product_prices.js' };
this.pages[hashPageStoreProducts] = { name: 'PageStoreProducts', module: PageStoreProducts }; // pathModule: './pages/store/products.js' };
// this.pages[hashPageStoreProductVariations] = { name: 'PageStoreProductVariations', module: PageStoreProductVariations }; // pathModule: './pages/store/product_variations.js' };
this.pages[hashPageStoreStockItems] = { name: 'PageStoreStockItems', module: PageStoreStockItems };
this.pages[hashPageStoreSuppliers] = { name: 'PageStoreSuppliers', module: PageStoreSuppliers };
this.pages[hashPageStoreSupplierPurchaseOrders] = { name: 'PageSupplierPurchaseOrders', module: PageStoreSupplierPurchaseOrders };
// User
// this.pages[hashPageUserLogin] = { name: 'PageUserLogin', module: PageUserLogin }; // pathModule: './pages/user/login.js' };
// this.pages[hashPageUserLogout] = { name: 'PageUserLogout', module: PageUserLogout }; // pathModule: './pages/user/logout.js' };
@@ -101,12 +107,15 @@ export default class Router {
this.routes[hashPageLicense] = (isPopState = false) => this.navigateToHash(hashPageLicense, isPopState);
this.routes[hashPagePrivacyPolicy] = (isPopState = false) => this.navigateToHash(hashPagePrivacyPolicy, isPopState);
// Store
this.routes[hashPageStoreManufacturingPurchaseOrders] = (isPopState = false) => this.navigateToHash(hashPageStoreManufacturingPurchaseOrders, isPopState);
this.routes[hashPageStoreProductCategories] = (isPopState = false) => this.navigateToHash(hashPageStoreProductCategories, isPopState);
this.routes[hashPageStoreProductPermutations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPermutations, isPopState);
// this.routes[hashPageStoreProductPrices] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPrices, isPopState);
this.routes[hashPageStoreProducts] = (isPopState = false) => this.navigateToHash(hashPageStoreProducts, isPopState);
// this.routes[hashPageStoreProductVariations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductVariations, isPopState);
this.routes[hashPageStoreStockItems] = (isPopState = false) => this.navigateToHash(hashPageStoreStockItems, isPopState);
this.routes[hashPageStoreSuppliers] = (isPopState = false) => this.navigateToHash(hashPageStoreSuppliers, isPopState);
this.routes[hashPageStoreSupplierPurchaseOrders] = (isPopState = false) => this.navigateToHash(hashPageStoreSupplierPurchaseOrders, isPopState);
// User
// this.routes[hashPageUserLogin] = (isPopState = false) => this.navigateToHash(hashPageUserLogin, isPopState);
// this.routes[hashPageUserLogout] = (isPopState = false) => this.navigateToHash(hashPageUserLogout, isPopState);