From 92e2c354fd35cace35e3bd3b9c28bf976ae908f6 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Fri, 28 May 2021 19:45:39 +0300 Subject: [PATCH] refactor Signed-off-by: Jari Kolehmainen --- .../__tests__/catalog-entity-registry.test.ts | 49 +++++++++++++- src/renderer/api/catalog-entity-registry.ts | 65 ++++++++++++++----- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/src/renderer/api/__tests__/catalog-entity-registry.test.ts b/src/renderer/api/__tests__/catalog-entity-registry.test.ts index 08e5d83a50..4c3bcb48c3 100644 --- a/src/renderer/api/__tests__/catalog-entity-registry.test.ts +++ b/src/renderer/api/__tests__/catalog-entity-registry.test.ts @@ -22,7 +22,8 @@ import { CatalogEntityRegistry } from "../catalog-entity-registry"; import "../../../common/catalog-entities"; import { catalogCategoryRegistry } from "../../../common/catalog/catalog-category-registry"; -import type { CatalogEntityData, CatalogEntityKindData } from "../catalog-entity"; +import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "../catalog-entity"; +import { WebLink } from "../../../common/catalog-entities"; class TestCatalogEntityRegistry extends CatalogEntityRegistry { replaceItems(items: Array) { @@ -30,6 +31,27 @@ class TestCatalogEntityRegistry extends CatalogEntityRegistry { } } +class FooBarCategory extends CatalogCategory { + public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; + public readonly kind = "CatalogCategory"; + public metadata = { + name: "FooBars", + icon: "broken" + }; + public spec = { + group: "entity.k8slens.dev", + versions: [ + { + name: "v1alpha1", + entityClass: WebLink + } + ], + names: { + kind: "FooBar" + } + }; +} + describe("CatalogEntityRegistry", () => { describe("updateItems", () => { it("adds new catalog item", () => { @@ -201,8 +223,31 @@ describe("CatalogEntityRegistry", () => { ]; catalog.replaceItems(items); - expect(catalog.items.length).toBe(1); }); }); + + it("does return items after matching category is added", () => { + const catalog = new TestCatalogEntityRegistry(catalogCategoryRegistry); + const items = [ + { + apiVersion: "entity.k8slens.dev/v1alpha1", + kind: "FooBar", + metadata: { + uid: "456", + name: "barbaz", + source: "test", + labels: {} + }, + status: { + phase: "disconnected" + }, + spec: {} + } + ]; + + catalog.replaceItems(items); + catalogCategoryRegistry.add(new FooBarCategory()); + expect(catalog.items.length).toBe(1); + }); }); diff --git a/src/renderer/api/catalog-entity-registry.ts b/src/renderer/api/catalog-entity-registry.ts index ba148ec142..0a30db31a2 100644 --- a/src/renderer/api/catalog-entity-registry.ts +++ b/src/renderer/api/catalog-entity-registry.ts @@ -27,8 +27,13 @@ import type { Cluster } from "../../main/cluster"; import { ClusterStore } from "../../common/cluster-store"; export class CatalogEntityRegistry { - protected _entities = observable.map([], { deep: true }); @observable.ref activeEntity: CatalogEntity; + protected _entities = observable.map([], { deep: true }); + + /** + * Buffer for keeping entities that don't yet have CatalogCategory synced + */ + protected rawEntities: (CatalogEntityData & CatalogEntityKindData)[] = []; constructor(private categoryRegistry: CatalogCategoryRegistry) { makeObservable(this); @@ -41,32 +46,58 @@ export class CatalogEntityRegistry { } @action updateItems(items: (CatalogEntityData & CatalogEntityKindData)[]) { - const newIds = items.map((item) => item.metadata.uid); + this.rawEntities.length = 0; - Array.from(this._entities.keys()).forEach((uid) => { - if (!newIds.includes(uid)) this._entities.delete(uid); - }); + const newIds = new Set(items.map((item) => item.metadata.uid)); - items.forEach((item) => { - const existing = this._entities.get(item.metadata.uid); - - if (!existing) { - const entity = this.categoryRegistry.getEntityForData(item); - - if (entity) this._entities.set(entity.metadata.uid, entity); - } else { - existing.metadata = item.metadata; - existing.spec = item.spec; - existing.status = item.status; + for (const uid of this._entities.keys()) { + if (!newIds.has(uid)) { + this._entities.delete(uid); } - }); + } + + for (const item of items) { + this.updateItem(item); + } + } + + @action protected updateItem(item: (CatalogEntityData & CatalogEntityKindData)) { + const existing = this._entities.get(item.metadata.uid); + + if (!existing) { + const entity = this.categoryRegistry.getEntityForData(item); + + if (entity) { + this._entities.set(entity.metadata.uid, entity); + } else { + this.rawEntities.push(item); + } + } else { + existing.metadata = item.metadata; + existing.spec = item.spec; + existing.status = item.status; + } + } + + protected processRawEntities() { + const items = [...this.rawEntities]; + + this.rawEntities.length = 0; + + for (const item of items) { + this.updateItem(item); + } } @computed get items() { + this.processRawEntities(); + return Array.from(this._entities.values()); } @computed get entities(): Map { + this.processRawEntities(); + return this._entities; }