diff --git a/src/web/App.mjs b/src/web/App.mjs index 6a49f9f4..8f6484c6 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -434,9 +434,8 @@ class App { this.buildFavouritesCategory(isExpanded); - // update all op-lists to reflect the current recipe list ( selected ops ) and favourite category list ( favourite ops ) - this.manager.ops.updateListItemsClasses("#rec-list", "selected"); - this.manager.ops.updateListItemsClasses("#catFavourites > c-operation-list > ul.op-list", "favourite"); + window.dispatchEvent(this.manager.favouritesupdate); + this.manager.recipe.initDragAndDrop(); } diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index 7c4e30c9..607759f6 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -54,6 +54,10 @@ class Manager { * @event Manager#statechange */ this.statechange = new CustomEvent("statechange", {bubbles: true}); + /** + * @event Manager#favouritesupdate + */ + this.favouritesupdate = new CustomEvent("favouritesupdate", {bubbles: true}); // Define Waiter objects to handle various areas this.timing = new TimingWaiter(this.app, this); diff --git a/src/web/components/c-operation-list.mjs b/src/web/components/c-operation-list.mjs index 0584588a..7e367623 100644 --- a/src/web/components/c-operation-list.mjs +++ b/src/web/components/c-operation-list.mjs @@ -30,6 +30,28 @@ export class COperationList extends HTMLElement { this.isSortable = isSortable; this.isCloneable = isCloneable; this.icon = icon; + + window.addEventListener("operationadd", this.handleChange.bind(this)) + window.addEventListener("operationremove", this.handleChange.bind(this)) + window.addEventListener("favouritesupdate", this.handleChange.bind(this)) + } + + /** + * Remove listeners on disconnectedCallback + */ + disconnectedCallback() { + this.removeEventListener("operationadd", this.handleChange.bind(this)); + this.removeEventListener("operationremove", this.handleChange.bind(this)); + this.removeEventListener("favouritesupdate", this.handleChange.bind(this)); + } + + /** + * Handle change + * Fires on custom operationadd, operationremove, favouritesupdate events + */ + handleChange() { + this.updateListItemsClasses("#catFavourites c-operation-list ul", "favourite"); + this.updateListItemsClasses("#rec-list", "selected"); } /** @@ -142,6 +164,36 @@ export class COperationList extends HTMLElement { } }); } + + /** + * Update classes ( className ) on the li.operation elements in this list, based on the current state of a + * list of choice ( srcListSelector ) + * + * @param {string} srcListSelector - the selector of the UL that we want to use as source of truth + * @param {string} className - the className to update + */ + updateListItemsClasses(srcListSelector, className) { + const srcListItems= document.querySelectorAll(`${srcListSelector} li`); + const listItems = this.querySelectorAll("c-operation-li li.operation"); + + listItems.forEach((li => { + if (li.classList.contains(`${className}`)) { + li.classList.remove(`${className}`); + } + })) + + if (srcListItems.length !== 0) { + srcListItems.forEach((item => { + const targetDataName = item.getAttribute("data-name"); + + listItems.forEach((listItem) => { + if (targetDataName === listItem.getAttribute("data-name")) { + listItem.classList.add(`${className}`); + } + }); + })); + } + } } customElements.define("c-operation-list", COperationList); diff --git a/src/web/components/c-recipe-li.mjs b/src/web/components/c-recipe-li.mjs index 8e97cd03..b5eb63d6 100644 --- a/src/web/components/c-recipe-li.mjs +++ b/src/web/components/c-recipe-li.mjs @@ -106,7 +106,7 @@ export class CRecipeLi extends HTMLElement { this.remove(); log.debug("Operation removed from recipe"); window.dispatchEvent(this.app.manager.statechange); - this.app.manager.ops.updateListItemsClasses("#rec-list", "selected"); + window.dispatchEvent(this.app.manager.operationremove); } /** diff --git a/src/web/waiters/OperationsWaiter.mjs b/src/web/waiters/OperationsWaiter.mjs index 8bd1bf1b..61f165c6 100755 --- a/src/web/waiters/OperationsWaiter.mjs +++ b/src/web/waiters/OperationsWaiter.mjs @@ -113,8 +113,6 @@ class OperationsWaiter { cOpList.build(); searchResultsEl.append(cOpList); } - - this.manager.ops.updateListItemsClasses("#rec-list", "selected"); } } @@ -267,81 +265,6 @@ class OperationsWaiter { resetFavouritesClick() { this.app.resetFavourites(); } - - - /** - * Update classes in the #dropdown-operations op-lists based on the - * list items of a srcListSelector. - * - * e.g: update all list items to add or remove the 'selected' class based on the operations - * in the current recipe-list, or 'favourite' classes on the current list of favourites. - * - * @param {string} srcListSelector - the UL element list to compare to - * @param {string} className - the className to update - */ - updateListItemsClasses(srcListSelector, className) { - const listItems = document.querySelectorAll(`${srcListSelector} li`); - const ops = document.querySelectorAll("c-operation-li > li.operation"); - - this.removeClassFromOps(className); - - if (listItems.length !== 0) { - listItems.forEach((item => { - const targetDataName = item.getAttribute("data-name"); - - ops.forEach((op) => { - if (targetDataName === op.getAttribute("data-name")) { - this.addClassToOp(targetDataName, className); - } - }); - })); - } - } - - /** - * Generic function to remove a class from > ALL < operation list items - * - * @param {string} className - the class to remove - */ - removeClassFromOps(className) { - const ops = document.querySelectorAll("c-operation-li > li.operation"); - - ops.forEach((op => { - this.removeClassFromOp(op.getAttribute("data-name"), className); - })); - } - - - /** - * Generic function to remove a class from target operation list item. This operation li may occur twice ( when the op is in - * 'favourites' and in the category for instance ) - * - * @param {string} opName - operation name through data-name attribute of the target operation - * @param {string} className - the class to remove - */ - removeClassFromOp(opName, className) { - const ops = document.querySelectorAll(`c-operation-li > li.operation[data-name="${opName}"].${className}`); - - ops.forEach((op) => { - op.classList.remove(`${className}`); - }); - } - - - /** - * Generic function to add a class to a specific operation. This operation li may occur twice ( when the op is in - * 'favourites' and in the category for instance ) - * - * @param {string} opName - operation name through data-name attribute of the target operation - * @param {string} className - the class to add to the operation list item - */ - addClassToOp(opName, className) { - const ops = document.querySelectorAll(`c-operation-li > li.operation[data-name="${opName}"]`); - - ops.forEach((op => { - op.classList.add(`${className}`); - })); - } } export default OperationsWaiter; diff --git a/src/web/waiters/RecipeWaiter.mjs b/src/web/waiters/RecipeWaiter.mjs index ed824395..af9bd34e 100755 --- a/src/web/waiters/RecipeWaiter.mjs +++ b/src/web/waiters/RecipeWaiter.mjs @@ -250,8 +250,6 @@ class RecipeWaiter { item.dispatchEvent(this.manager.operationadd); document.dispatchEvent(this.app.manager.statechange); - - this.manager.ops.updateListItemsClasses("#rec-list", "selected"); return item; } @@ -269,8 +267,6 @@ class RecipeWaiter { recList.dispatchEvent(this.manager.operationremove); window.dispatchEvent(this.app.manager.statechange); - - this.app.manager.ops.updateListItemsClasses("#rec-list", "selected"); }