diff --git a/src/renderer/components/+catalog/catalog-add-button.tsx b/src/renderer/components/+catalog/catalog-add-button.tsx index 75cbe6ed23..cd0055ff51 100644 --- a/src/renderer/components/+catalog/catalog-add-button.tsx +++ b/src/renderer/components/+catalog/catalog-add-button.tsx @@ -23,21 +23,24 @@ import "./catalog-add-button.scss"; import React from "react"; import { SpeedDial, SpeedDialAction } from "@material-ui/lab"; import { Icon } from "../icon"; -import { disposeOnUnmount, observer } from "mobx-react"; -import { observable, reaction, makeObservable } from "mobx"; +import { observer } from "mobx-react"; +import { observable, makeObservable, action } from "mobx"; import { boundMethod } from "../../../common/utils"; import type { CatalogCategory, CatalogEntityAddMenuContext, CatalogEntityAddMenu } from "../../api/catalog-entity"; import { EventEmitter } from "events"; import { navigate } from "../../navigation"; +import { catalogCategoryRegistry } from "../../api/catalog-category-registry"; export type CatalogAddButtonProps = { category: CatalogCategory }; +type CategoryId = string; + @observer export class CatalogAddButton extends React.Component { @observable protected isOpen = false; - protected menuItems = observable.array([]); + @observable menuItems = new Map(); constructor(props: CatalogAddButtonProps) { super(props); @@ -45,22 +48,49 @@ export class CatalogAddButton extends React.Component { } componentDidMount() { - disposeOnUnmount(this, [ - reaction(() => this.props.category, (category) => { - this.menuItems.clear(); - - if (category && category instanceof EventEmitter) { - const context: CatalogEntityAddMenuContext = { - navigate: (url: string) => navigate(url), - menuItems: this.menuItems - }; - - category.emit("catalogAddMenu", context); - } - }, { fireImmediately: true }) - ]); + this.updateMenuItems(); } + componentDidUpdate(prevProps: CatalogAddButtonProps) { + if (prevProps.category != this.props.category) { + this.updateMenuItems(); + } + } + + get categories() { + return catalogCategoryRegistry.filteredItems; + } + + @action + updateMenuItems() { + this.menuItems.clear(); + + if (this.props.category) { + this.updateCategoryItems(this.props.category); + } else { + // Show menu items from all categories + this.categories.forEach(this.updateCategoryItems); + } + } + + @action + updateCategoryItems = (category: CatalogCategory) => { + if (category instanceof EventEmitter) { + const menuItems: CatalogEntityAddMenu[] = []; + const context: CatalogEntityAddMenuContext = { + navigate: (url: string) => navigate(url), + menuItems + }; + + category.emit("catalogAddMenu", context); + this.menuItems.set(category.getId(), menuItems); + } + }; + + getCategoryFilteredItems = (category: CatalogCategory) => { + return category.filteredItems(this.menuItems.get(category.getId()) || []); + }; + @boundMethod onOpen() { this.isOpen = true; @@ -73,17 +103,21 @@ export class CatalogAddButton extends React.Component { @boundMethod onButtonClick() { - const filteredItems = this.props.category ? this.props.category.filteredItems(this.menuItems) : []; - const defaultAction = filteredItems.find(item => item.defaultAction)?.onClick; - const clickAction = defaultAction || (filteredItems.length === 1 ? filteredItems[0].onClick : null); + const defaultAction = this.items.find(item => item.defaultAction)?.onClick; + const clickAction = defaultAction || (this.items.length === 1 ? this.items[0].onClick : null); clickAction?.(); } - render() { - const filteredItems = this.props.category ? this.props.category.filteredItems(this.menuItems) : []; + get items() { + const { category } = this.props; - if (filteredItems.length === 0) { + return category ? this.getCategoryFilteredItems(category) : + this.categories.map(this.getCategoryFilteredItems).flat(); + } + + render() { + if (this.items.length === 0) { return null; } @@ -98,7 +132,7 @@ export class CatalogAddButton extends React.Component { direction="up" onClick={this.onButtonClick} > - {filteredItems.map((menuItem, index) => { + {this.items.map((menuItem, index) => { return }