diff --git a/src/common/__tests__/catalog-entity-registry.test.ts b/src/common/__tests__/catalog-entity-registry.test.ts new file mode 100644 index 0000000000..da85af3e3d --- /dev/null +++ b/src/common/__tests__/catalog-entity-registry.test.ts @@ -0,0 +1,63 @@ +import { observable, reaction } from "mobx"; +import { WebLink } from "../catalog-entities"; +import { CatalogEntityRegistry } from "../catalog-entity-registry"; + +describe("CatalogEntityRegistry", () => { + let registry: CatalogEntityRegistry; + const entity = new WebLink({ + apiVersion: "entity.k8slens.dev/v1alpha1", + kind: "WebLink", + metadata: { + uid: "test", + name: "test-link", + source: "test", + labels: {} + }, + spec: { + url: "https://k8slens.dev" + }, + status: { + phase: "ok" + } + }); + + beforeEach(() => { + registry = new CatalogEntityRegistry(); + }); + + describe("addSource", () => { + it ("allows to add an observable source", () => { + const source = observable.array([]); + + registry.addSource("test", source); + expect(registry.items.length).toEqual(0); + + source.push(entity); + + expect(registry.items.length).toEqual(1); + }); + + it ("added source change triggers reaction", (done) => { + const source = observable.array([]); + + registry.addSource("test", source); + reaction(() => registry.items, () => { + done(); + }); + + source.push(entity); + }); + }); + + describe("removeSource", () => { + it ("removes source", () => { + const source = observable.array([]); + + registry.addSource("test", source); + source.push(entity); + registry.removeSource("test"); + + expect(registry.items.length).toEqual(0); + }); + }); +}); diff --git a/src/common/catalog-entities/web-link.ts b/src/common/catalog-entities/web-link.ts index a8523408a3..db52fe0eb6 100644 --- a/src/common/catalog-entities/web-link.ts +++ b/src/common/catalog-entities/web-link.ts @@ -1,5 +1,5 @@ import { observable } from "mobx"; -import { CatalogCategory, CatalogEntity, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity"; +import { CatalogCategory, CatalogEntity, CatalogEntityData, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity"; import { catalogCategoryRegistry } from "../catalog-category-registry"; export interface WebLinkStatus extends CatalogEntityStatus { @@ -17,6 +17,12 @@ export class WebLink implements CatalogEntity { @observable public status: WebLinkStatus; @observable public spec: WebLinkSpec; + constructor(data: CatalogEntityData) { + this.metadata = data.metadata; + this.status = data.status as WebLinkStatus; + this.spec = data.spec as WebLinkSpec; + } + getId() { return this.metadata.uid; } diff --git a/src/common/catalog-entity-registry.ts b/src/common/catalog-entity-registry.ts index e800fa88f9..28afa55bac 100644 --- a/src/common/catalog-entity-registry.ts +++ b/src/common/catalog-entity-registry.ts @@ -1,10 +1,10 @@ -import { action, computed, observable } from "mobx"; +import { action, computed, observable, IObservableArray } from "mobx"; import { CatalogEntity } from "./catalog-entity"; export class CatalogEntityRegistry { - protected sources = observable.map([], { deep: true }); + protected sources = observable.map>([], { deep: true }); - @action addSource(id: string, source: CatalogEntity[]) { + @action addSource(id: string, source: IObservableArray) { this.sources.set(id, source); } @@ -12,14 +12,8 @@ export class CatalogEntityRegistry { this.sources.delete(id); } - @computed get items() { - const catalogItems: CatalogEntity[] = []; - - for (const items of this.sources.values()) { - items.forEach((item) => catalogItems.push(item)); - } - - return catalogItems; + @computed get items(): CatalogEntity[] { + return Array.from(this.sources.values()).flat(); } getItemsForApiKind(apiVersion: string, kind: string): T[] { diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 1cfd3105b0..0ebb3d90f4 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -4,6 +4,7 @@ import { WindowManager } from "../main/window-manager"; import { getExtensionPageUrl } from "./registries/page-registry"; import { catalogEntityRegistry } from "../common/catalog-entity-registry"; import { CatalogEntity } from "../common/catalog-entity"; +import { IObservableArray } from "mobx"; export class LensMainExtension extends LensExtension { appMenus: MenuRegistration[] = []; @@ -19,7 +20,7 @@ export class LensMainExtension extends LensExtension { await windowManager.navigate(pageUrl, frameId); } - addCatalogSource(id: string, source: CatalogEntity[]) { + addCatalogSource(id: string, source: IObservableArray) { catalogEntityRegistry.addSource(`${this.name}:${id}`, source); } diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index c0ba24cc5d..047fb0ca95 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -14,7 +14,7 @@ import { catalogEntityRegistry } from "../common/catalog-entity-registry"; const clusterOwnerRef = "ClusterManager"; export class ClusterManager extends Singleton { - @observable.deep catalogSource: CatalogEntity[] = []; + catalogSource = observable.array([]); constructor(public readonly port: number) { super();