diff --git a/packages/core/src/common/catalog/category-registry.ts b/packages/core/src/common/catalog/category-registry.ts index 75c33d8a10..e4de26b322 100644 --- a/packages/core/src/common/catalog/category-registry.ts +++ b/packages/core/src/common/catalog/category-registry.ts @@ -34,6 +34,10 @@ export class CatalogCategoryRegistry { }; } + getById(id: string) { + return iter.find(this.categories.values(), (category) => category.getId() === id); + } + @computed get items() { return Array.from(this.categories); } diff --git a/packages/core/src/renderer/api/catalog/entity/get-by-id.injectable.ts b/packages/core/src/renderer/api/catalog/entity/get-by-id.injectable.ts new file mode 100644 index 0000000000..e87228c345 --- /dev/null +++ b/packages/core/src/renderer/api/catalog/entity/get-by-id.injectable.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import type { CatalogEntity } from "../../catalog-entity"; +import catalogEntityRegistryInjectable from "./registry.injectable"; + +export type GetEntityById = (id: string) => CatalogEntity | undefined; + +const getEntityByIdInjectable = getInjectable({ + id: "get-entity-by-id", + instantiate: (di): GetEntityById => { + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + + return (id) => catalogEntityRegistry.getById(id); + }, +}); + +export default getEntityByIdInjectable; diff --git a/packages/core/src/renderer/components/+catalog/__tests__/catalog-entity-store.test.ts b/packages/core/src/renderer/components/+catalog/__tests__/catalog-entity-store.test.ts index 6794fed899..5a70657ca2 100644 --- a/packages/core/src/renderer/components/+catalog/__tests__/catalog-entity-store.test.ts +++ b/packages/core/src/renderer/components/+catalog/__tests__/catalog-entity-store.test.ts @@ -3,12 +3,16 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { DiContainer } from "@ogre-tools/injectable"; import type { CatalogCategoryMetadata, CatalogCategorySpec } from "../../../../common/catalog"; import { CatalogEntity, categoryVersion } from "../../../../common/catalog"; +import catalogCategoryRegistryInjectable from "../../../../common/catalog/category-registry.injectable"; import { CatalogCategory } from "../../../api/catalog-entity"; +import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable"; +import { getDiForUnitTesting } from "../../../getDiForUnitTesting"; import { noop } from "../../../utils"; -import type { CatalogEntityStore } from "../catalog-entity-store/catalog-entity.store"; -import { catalogEntityStore } from "../catalog-entity-store/catalog-entity.store"; +import type { CatalogEntityStore } from "../catalog-entity-store.injectable"; +import catalogEntityStoreInjectable from "../catalog-entity-store.injectable"; class TestEntityOne extends CatalogEntity { public static readonly apiVersion: string = "entity.k8slens.dev/v1alpha1"; @@ -63,6 +67,12 @@ class TestCategoryTwo extends CatalogCategory { } describe("CatalogEntityStore", () => { + let di: DiContainer; + + beforeEach(() => { + di = getDiForUnitTesting({ doGeneralOverrides: true }); + }); + describe("getTotalCount", () => { let store: CatalogEntityStore; let testCategoryOne: TestCategoryOne; @@ -129,21 +139,22 @@ describe("CatalogEntityStore", () => { testCategoryOne = new TestCategoryOne(); testCategoryTwo = new TestCategoryTwo(); - store = catalogEntityStore({ - catalogRegistry: { - items: [ - testCategoryOne, - testCategoryTwo, - ], + + di.override(catalogCategoryRegistryInjectable, () => ({ + items: [ + testCategoryOne, + testCategoryTwo, + ], + })); + di.override(catalogEntityRegistryInjectable, () => ({ + onRun: noop, + filteredItems: entityItems, + getItemsForCategory: (category: CatalogCategory): T[] => { + return entityItems.filter(item => category.spec.versions.some(version => item instanceof version.entityClass)) as T[]; }, - entityRegistry: { - onRun: noop, - filteredItems: entityItems, - getItemsForCategory: (category: CatalogCategory): T[] => { - return entityItems.filter(item => category.spec.versions.some(version => item instanceof version.entityClass)) as T[]; - }, - }, - }); + } as any)); + + store = di.inject(catalogEntityStoreInjectable); }); it("given no active category, returns count of all kinds", () => { diff --git a/packages/core/src/renderer/components/+catalog/catalog-entity-store.injectable.ts b/packages/core/src/renderer/components/+catalog/catalog-entity-store.injectable.ts new file mode 100644 index 0000000000..9f9d2e4999 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/catalog-entity-store.injectable.ts @@ -0,0 +1,74 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; + +import type { IComputedValue, IObservableValue } from "mobx"; +import { computed, observable, reaction } from "mobx"; +import type { CatalogEntity } from "../../api/catalog-entity"; +import type { CatalogCategory } from "../../../common/catalog"; +import type { Disposer } from "../../../common/utils"; +import { disposer } from "../../../common/utils"; +import type { ItemListStore } from "../item-object-list"; +import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable"; +import selectedCatalogEntityParamInjectable from "./entity-details/selected-uid.injectable"; + +export type CatalogEntityStore = ItemListStore & { + readonly entities: IComputedValue; + readonly activeCategory: IObservableValue; + watch(): Disposer; + onRun(entity: CatalogEntity): void; +}; + +const catalogEntityStoreInjectable = getInjectable({ + id: "catalog-entity-store", + + instantiate: (di): CatalogEntityStore => { + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + const catalogCategoryRegistry = di.inject(catalogCategoryRegistryInjectable); + const selectedCatalogEntityParam = di.inject(selectedCatalogEntityParamInjectable); + + const activeCategory = observable.box(undefined); + const entities = computed(() => { + const category = activeCategory.get(); + + return category + ? catalogEntityRegistry.getItemsForCategory(category, { filtered: true }) + : catalogEntityRegistry.filteredItems; + }); + const loadAll = () => { + const category = activeCategory.get(); + + if (category) { + category.emit("load"); + } else { + for (const category of catalogCategoryRegistry.items) { + category.emit("load"); + } + } + }; + + return { + entities, + activeCategory, + watch: () => disposer( + reaction(() => entities.get(), loadAll), + reaction(() => activeCategory.get(), loadAll, { delay: 100 }), + ), + onRun: entity => catalogEntityRegistry.onRun(entity), + failedLoading: false, + getTotalCount: () => entities.get().length, + isLoaded: true, + isSelected: (item) => item.getId() === selectedCatalogEntityParam.get(), + isSelectedAll: () => false, + pickOnlySelected: () => [], + toggleSelection: () => {}, + toggleSelectionAll: () => {}, + removeSelectedItems: async () => {}, + }; + }, +}); + +export default catalogEntityStoreInjectable; diff --git a/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity-store.injectable.ts b/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity-store.injectable.ts deleted file mode 100644 index 6e3cb979e4..0000000000 --- a/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity-store.injectable.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { catalogEntityStore } from "./catalog-entity.store"; -import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable"; -import catalogCategoryRegistryInjectable from "../../../../common/catalog/category-registry.injectable"; - -const catalogEntityStoreInjectable = getInjectable({ - id: "catalog-entity-store", - - instantiate: (di) => catalogEntityStore({ - entityRegistry: di.inject(catalogEntityRegistryInjectable), - catalogRegistry: di.inject(catalogCategoryRegistryInjectable), - }), -}); - -export default catalogEntityStoreInjectable; diff --git a/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity.store.tsx b/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity.store.tsx deleted file mode 100644 index 3209428cba..0000000000 --- a/packages/core/src/renderer/components/+catalog/catalog-entity-store/catalog-entity.store.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import type { IComputedValue, IObservableValue } from "mobx"; -import { computed, observable, reaction } from "mobx"; -import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry"; -import type { CatalogEntity } from "../../../api/catalog-entity"; -import type { CatalogCategory, CatalogCategoryRegistry } from "../../../../common/catalog"; -import type { Disposer } from "../../../../common/utils"; -import { disposer } from "../../../../common/utils"; -import type { ItemListStore } from "../../item-object-list"; - -type EntityRegistry = Pick; -type CatalogRegistry = Pick; - -interface Dependencies { - entityRegistry: EntityRegistry; - catalogRegistry: CatalogRegistry; -} - -export type CatalogEntityStore = ItemListStore & { - readonly entities: IComputedValue; - readonly activeCategory: IObservableValue; - readonly selectedItemId: IObservableValue; - readonly selectedItem: IComputedValue; - watch(): Disposer; - onRun(entity: CatalogEntity): void; -}; - -export function catalogEntityStore({ - entityRegistry, - catalogRegistry, -}: Dependencies): CatalogEntityStore { - const activeCategory = observable.box(undefined); - const selectedItemId = observable.box(undefined); - const entities = computed(() => { - const category = activeCategory.get(); - - return category - ? entityRegistry.getItemsForCategory(category, { filtered: true }) - : entityRegistry.filteredItems; - }); - const selectedItem = computed(() => { - const id = selectedItemId.get(); - - if (!id) { - return undefined; - } - - return entities.get().find(entity => entity.getId() === id); - }); - const loadAll = () => { - const category = activeCategory.get(); - - if (category) { - category.emit("load"); - } else { - for (const category of catalogRegistry.items) { - category.emit("load"); - } - } - }; - - return { - entities, - selectedItem, - activeCategory, - selectedItemId, - watch: () => disposer( - reaction(() => entities.get(), loadAll), - reaction(() => activeCategory.get(), loadAll, { delay: 100 }), - ), - onRun: entity => entityRegistry.onRun(entity), - failedLoading: false, - getTotalCount: () => entities.get().length, - isLoaded: true, - isSelected: (item) => item.getId() === selectedItemId.get(), - isSelectedAll: () => false, - pickOnlySelected: () => [], - toggleSelection: () => {}, - toggleSelectionAll: () => {}, - removeSelectedItems: async () => {}, - }; -} diff --git a/packages/core/src/renderer/components/+catalog/catalog.test.tsx b/packages/core/src/renderer/components/+catalog/catalog.test.tsx index 334970e166..ec35fb1d4a 100644 --- a/packages/core/src/renderer/components/+catalog/catalog.test.tsx +++ b/packages/core/src/renderer/components/+catalog/catalog.test.tsx @@ -10,10 +10,10 @@ import { Catalog } from "./catalog"; import type { CatalogEntityActionContext, CatalogEntityData } from "../../../common/catalog"; import { CatalogEntity } from "../../../common/catalog"; import type { CatalogEntityOnBeforeRun, CatalogEntityRegistry } from "../../api/catalog/entity/registry"; -import type { CatalogEntityStore } from "./catalog-entity-store/catalog-entity.store"; +import type { CatalogEntityStore } from "./catalog-entity-store.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; import type { DiContainer } from "@ogre-tools/injectable"; -import catalogEntityStoreInjectable from "./catalog-entity-store/catalog-entity-store.injectable"; +import catalogEntityStoreInjectable from "./catalog-entity-store.injectable"; import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; import type { DiRender } from "../test-utils/renderFor"; import { renderFor } from "../test-utils/renderFor"; diff --git a/packages/core/src/renderer/components/+catalog/catalog.tsx b/packages/core/src/renderer/components/+catalog/catalog.tsx index acd5346b17..c1ec710d47 100644 --- a/packages/core/src/renderer/components/+catalog/catalog.tsx +++ b/packages/core/src/renderer/components/+catalog/catalog.tsx @@ -10,7 +10,7 @@ import { disposeOnUnmount, observer } from "mobx-react"; import { ItemListLayout } from "../item-object-list"; import type { IComputedValue } from "mobx"; import { action, computed, makeObservable, observable, reaction, runInAction, when } from "mobx"; -import type { CatalogEntityStore } from "./catalog-entity-store/catalog-entity.store"; +import type { CatalogEntityStore } from "./catalog-entity-store.injectable"; import { MenuItem, MenuActions } from "../menu"; import type { CatalogEntityContextMenu } from "../../api/catalog-entity"; import type { CatalogCategory, CatalogCategoryRegistry, CatalogEntity } from "../../../common/catalog"; @@ -19,7 +19,6 @@ import type { ShowNotification } from "../notifications"; import { MainLayout } from "../layout/main-layout"; import type { StorageLayer } from "../../utils"; import { prevDefault } from "../../utils"; -import { CatalogEntityDetails } from "./entity-details/view"; import { CatalogMenu } from "./catalog-menu"; import { RenderDelay } from "../render-delay/render-delay"; import { Icon } from "../icon"; @@ -27,7 +26,7 @@ import { HotbarToggleMenuItem } from "./hotbar-toggle-menu-item"; import { Avatar } from "../avatar"; import { withInjectables } from "@ogre-tools/injectable-react"; import catalogPreviousActiveTabStorageInjectable from "./catalog-previous-active-tab-storage/catalog-previous-active-tab-storage.injectable"; -import catalogEntityStoreInjectable from "./catalog-entity-store/catalog-entity-store.injectable"; +import catalogEntityStoreInjectable from "./catalog-entity-store.injectable"; import type { GetCategoryColumnsParams, CategoryColumns } from "./columns/get.injectable"; import getCategoryColumnsInjectable from "./columns/get.injectable"; import type { RegisteredCustomCategoryViewDecl } from "./custom-views.injectable"; @@ -51,6 +50,10 @@ import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.inj import type { Logger } from "../../../common/logger"; import loggerInjectable from "../../../common/logger.injectable"; import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable"; +import type { ShowEntityDetails } from "./entity-details/show.injectable"; +import showEntityDetailsInjectable from "./entity-details/show.injectable"; +import type { OnCatalogEntityListClick } from "./entity-details/on-catalog-click.injectable"; +import onCatalogEntityListClickInjectable from "./entity-details/on-catalog-click.injectable"; interface Dependencies { catalogPreviousActiveTabStorage: StorageLayer; @@ -58,6 +61,8 @@ interface Dependencies { getCategoryColumns: (params: GetCategoryColumnsParams) => CategoryColumns; customCategoryViews: IComputedValue>>; emitEvent: EmitAppEvent; + showEntityDetails: ShowEntityDetails; + onCatalogEntityListClick: OnCatalogEntityListClick; routeParameters: { group: IComputedValue; kind: IComputedValue; @@ -161,26 +166,16 @@ class NonInjectedCatalog extends React.Component { this.props.hotbarStore.removeFromHotbar(entity.getId()); } - onDetails = (entity: CatalogEntity) => { - if (this.props.catalogEntityStore.selectedItemId.get()) { - this.props.catalogEntityStore.selectedItemId.set(undefined); - } else { - this.props.catalogEntityStore.onRun(entity); - } - }; - - get categories() { - return this.props.catalogCategoryRegistry.items; - } - onTabChange = action((tabId: string | null) => { - const activeCategory = this.categories.find(category => category.getId() === tabId); + const activeCategory = tabId + ? this.props.catalogCategoryRegistry.getById(tabId) + : undefined; this.props.emitEvent({ name: "catalog", action: "change-category", params: { - category: activeCategory ? activeCategory.getName() : "Browse", + category: activeCategory?.getName() ?? "Browse", }, }); @@ -211,7 +206,7 @@ class NonInjectedCatalog extends React.Component { this.props.catalogEntityStore.selectedItemId.set(entity.getId())} + onClick={() => this.props.showEntityDetails(entity.getId())} > View Details @@ -309,7 +304,7 @@ class NonInjectedCatalog extends React.Component { disabled: !entity.isEnabled(), })} {...getCategoryColumns({ activeCategory })} - onDetails={this.onDetails} + onDetails={this.props.onCatalogEntityListClick} renderItemMenu={this.renderItemMenu} data-testid={`catalog-list-for-${activeCategory?.metadata.name ?? "browse-all"}`} /> @@ -318,7 +313,6 @@ class NonInjectedCatalog extends React.Component { render() { const activeCategory = this.props.catalogEntityStore.activeCategory.get(); - const selectedItem = this.props.catalogEntityStore.selectedItem.get(); return ( { {this.renderViews(activeCategory)} { - selectedItem + activeCategory ? ( - this.props.catalogEntityStore.selectedItemId.set(undefined)} - onRun={() => this.props.catalogEntityStore.onRun(selectedItem)} - /> + + + ) - : activeCategory - ? ( - - - - ) - : null + : null } ); @@ -371,5 +357,7 @@ export const Catalog = withInjectables(NonInjectedCatalog, { normalizeMenuItem: di.inject(normalizeCatalogEntityContextMenuInjectable), logger: di.inject(loggerInjectable), showErrorNotification: di.inject(showErrorNotificationInjectable), + showEntityDetails: di.inject(showEntityDetailsInjectable), + onCatalogEntityListClick: di.inject(onCatalogEntityListClickInjectable), }), }); diff --git a/packages/core/src/renderer/components/+catalog/entity-details/component.injectable.tsx b/packages/core/src/renderer/components/+catalog/entity-details/component.injectable.tsx new file mode 100644 index 0000000000..71ab008280 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/component.injectable.tsx @@ -0,0 +1,65 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { IComputedValue } from "mobx"; +import { computed } from "mobx"; +import { observer } from "mobx-react"; +import React from "react"; +import type { CatalogEntity } from "../../../api/catalog-entity"; +import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry"; +import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable"; +import { rootFrameChildComponentInjectionToken } from "../../../frames/root-frame/root-frame-child-component-injection-token"; +import type { HideEntityDetails } from "./hide.injectable"; +import hideEntityDetailsInjectable from "./hide.injectable"; +import selectedCatalogEntityInjectable from "./selected-entity.injectable"; +import { CatalogEntityDetails } from "./view"; + +interface Dependencies { + selectedCatalogEntity: IComputedValue; + hideEntityDetails: HideEntityDetails; + catalogEntityRegistry: CatalogEntityRegistry; +} + +const NonInjectedCatalogEntityDetailsComponent = observer(({ + selectedCatalogEntity, + hideEntityDetails, + catalogEntityRegistry, +}: Dependencies) => { + const entity = selectedCatalogEntity.get(); + + if (!entity) { + return null; + } + + return ( + catalogEntityRegistry.onRun(entity)} + /> + ); +}); + +const CatalogEntityDetailsComponent = withInjectables(NonInjectedCatalogEntityDetailsComponent, { + getProps: (di, props) => ({ + ...props, + selectedCatalogEntity: di.inject(selectedCatalogEntityInjectable), + catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable), + hideEntityDetails: di.inject(hideEntityDetailsInjectable), + }), +}); + +const catalogEntityDetailsComponentInjectable = getInjectable({ + id: "catalog-entity-details-component", + instantiate: () => ({ + id: "catalog-entity-details-component", + Component: CatalogEntityDetailsComponent, + shouldRender: computed(() => true), + }), + injectionToken: rootFrameChildComponentInjectionToken, +}); + +export default catalogEntityDetailsComponentInjectable; diff --git a/packages/core/src/renderer/components/+catalog/entity-details/hide.injectable.ts b/packages/core/src/renderer/components/+catalog/entity-details/hide.injectable.ts new file mode 100644 index 0000000000..8151f7eed3 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/hide.injectable.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectable } from "@ogre-tools/injectable"; +import selectedCatalogEntityParamInjectable from "./selected-uid.injectable"; + +export type HideEntityDetails = () => void; + +const hideEntityDetailsInjectable = getInjectable({ + id: "hide-entity-details", + instantiate: (di) => { + const selectedCatalogEntityParam = di.inject(selectedCatalogEntityParamInjectable); + + return () => selectedCatalogEntityParam.clear(); + }, +}); + +export default hideEntityDetailsInjectable; diff --git a/packages/core/src/renderer/components/+catalog/entity-details/on-catalog-click.injectable.ts b/packages/core/src/renderer/components/+catalog/entity-details/on-catalog-click.injectable.ts new file mode 100644 index 0000000000..bae2121f57 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/on-catalog-click.injectable.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { action } from "mobx"; +import type { CatalogEntity } from "../../../api/catalog-entity"; +import catalogEntityRegistryInjectable from "../../../api/catalog/entity/registry.injectable"; +import selectedCatalogEntityParamInjectable from "./selected-uid.injectable"; + +export type OnCatalogEntityListClick = (entity: CatalogEntity) => void; + +const onCatalogEntityListClickInjectable = getInjectable({ + id: "on-catalog-entity-list-click", + instantiate: (di): OnCatalogEntityListClick => { + const selectedCatalogEntityParam = di.inject(selectedCatalogEntityParamInjectable); + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + + return action(entity => { + if (selectedCatalogEntityParam.get() === entity.getId()) { + selectedCatalogEntityParam.clear(); + } else if (selectedCatalogEntityParam.get() === undefined) { + catalogEntityRegistry.onRun(entity); + } else { + selectedCatalogEntityParam.set(entity.getId()); + } + }); + }, +}); + +export default onCatalogEntityListClickInjectable; diff --git a/packages/core/src/renderer/components/+catalog/entity-details/selected-entity.injectable.ts b/packages/core/src/renderer/components/+catalog/entity-details/selected-entity.injectable.ts new file mode 100644 index 0000000000..bcafe7c0e1 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/selected-entity.injectable.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import getEntityByIdInjectable from "../../../api/catalog/entity/get-by-id.injectable"; +import selectedCatalogEntityParamInjectable from "./selected-uid.injectable"; + +const selectedCatalogEntityInjectable = getInjectable({ + id: "selected-catalog-entity", + instantiate: (di) => { + const getEntityById = di.inject(getEntityByIdInjectable); + const selectedCatalogEntityParam = di.inject(selectedCatalogEntityParamInjectable); + + return computed(() => { + const id = selectedCatalogEntityParam.get(); + + if (!id) { + return undefined; + } + + return getEntityById(id); + }); + }, +}); + +export default selectedCatalogEntityInjectable; diff --git a/packages/core/src/renderer/components/+catalog/entity-details/selected-uid.injectable.ts b/packages/core/src/renderer/components/+catalog/entity-details/selected-uid.injectable.ts new file mode 100644 index 0000000000..5846f5aa28 --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/selected-uid.injectable.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import createPageParamInjectable from "../../../navigation/create-page-param.injectable"; + +const selectedCatalogEntityParamInjectable = getInjectable({ + id: "selected-catalog-entity-param", + instantiate: (di) => { + const createPageParam = di.inject(createPageParamInjectable); + + return createPageParam({ + name: "catalog-entity-details", + }); + }, +}); + +export default selectedCatalogEntityParamInjectable; diff --git a/packages/core/src/renderer/components/+catalog/entity-details/show.injectable.ts b/packages/core/src/renderer/components/+catalog/entity-details/show.injectable.ts new file mode 100644 index 0000000000..02b71c4bdc --- /dev/null +++ b/packages/core/src/renderer/components/+catalog/entity-details/show.injectable.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import selectedCatalogEntityParamInjectable from "./selected-uid.injectable"; + +export type ShowEntityDetails = (id: string) => void; + +const showEntityDetailsInjectable = getInjectable({ + id: "show-entity-details", + instantiate: (di): ShowEntityDetails => { + const selectedCatalogEntityParam = di.inject(selectedCatalogEntityParamInjectable); + + return (id) => selectedCatalogEntityParam.set(id); + }, +}); + +export default showEntityDetailsInjectable;