mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add CatalogCategory filter to the extension API (#3718)
* Add CatalogCategory filter to the extension API. Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com> * Fix test. Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
parent
e2b096fae1
commit
936927af98
@ -72,4 +72,34 @@ describe("CatalogCategoryRegistry", () => {
|
||||
d2();
|
||||
expect(registry.items.length).toBe(0);
|
||||
});
|
||||
|
||||
it("doesn't return items that are filtered out", () => {
|
||||
const registry = new TestCatalogCategoryRegistry();
|
||||
|
||||
registry.add(new TestCatalogCategory());
|
||||
registry.add(new TestCatalogCategory2());
|
||||
|
||||
expect(registry.items.length).toBe(2);
|
||||
expect(registry.filteredItems.length).toBe(2);
|
||||
|
||||
const disposer = registry.addCatalogCategoryFilter(category => category.metadata.name === "Test Category");
|
||||
|
||||
expect(registry.items.length).toBe(2);
|
||||
expect(registry.filteredItems.length).toBe(1);
|
||||
|
||||
const disposer2 = registry.addCatalogCategoryFilter(category => category.metadata.name === "foo");
|
||||
|
||||
expect(registry.items.length).toBe(2);
|
||||
expect(registry.filteredItems.length).toBe(0);
|
||||
|
||||
disposer();
|
||||
|
||||
expect(registry.items.length).toBe(2);
|
||||
expect(registry.filteredItems.length).toBe(0);
|
||||
|
||||
disposer2();
|
||||
|
||||
expect(registry.items.length).toBe(2);
|
||||
expect(registry.filteredItems.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
@ -20,12 +20,18 @@
|
||||
*/
|
||||
|
||||
import { action, computed, observable, makeObservable } from "mobx";
|
||||
import { Disposer, ExtendedMap } from "../utils";
|
||||
import { Disposer, ExtendedMap, iter } from "../utils";
|
||||
import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity";
|
||||
import { once } from "lodash";
|
||||
|
||||
export type CategoryFilter = (category: CatalogCategory) => any;
|
||||
|
||||
export class CatalogCategoryRegistry {
|
||||
protected categories = observable.set<CatalogCategory>();
|
||||
protected groupKinds = new ExtendedMap<string, ExtendedMap<string, CatalogCategory>>();
|
||||
protected filters = observable.set<CategoryFilter>([], {
|
||||
deep: false,
|
||||
});
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
@ -47,6 +53,17 @@ export class CatalogCategoryRegistry {
|
||||
return Array.from(this.categories);
|
||||
}
|
||||
|
||||
@computed get filteredItems() {
|
||||
return Array.from(
|
||||
iter.reduce(
|
||||
this.filters,
|
||||
iter.filter,
|
||||
this.items,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
getForGroupKind<T extends CatalogCategory>(group: string, kind: string): T | undefined {
|
||||
return this.groupKinds.get(group)?.get(kind) as T;
|
||||
}
|
||||
@ -80,6 +97,17 @@ export class CatalogCategoryRegistry {
|
||||
getByName(name: string) {
|
||||
return this.items.find(category => category.metadata?.name == name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new filter to the set of category filters
|
||||
* @param fn The function that should return a truthy value if that category should be displayed
|
||||
* @returns A function to remove that filter
|
||||
*/
|
||||
addCatalogCategoryFilter(fn: CategoryFilter): Disposer {
|
||||
this.filters.add(fn);
|
||||
|
||||
return once(() => void this.filters.delete(fn));
|
||||
}
|
||||
}
|
||||
|
||||
export const catalogCategoryRegistry = new CatalogCategoryRegistry();
|
||||
|
||||
@ -26,6 +26,7 @@ import { getExtensionPageUrl } from "./registries/page-registry";
|
||||
import type { CatalogEntity } from "../common/catalog";
|
||||
import type { Disposer } from "../common/utils";
|
||||
import { catalogEntityRegistry, EntityFilter } from "../renderer/api/catalog-entity-registry";
|
||||
import { catalogCategoryRegistry, CategoryFilter } from "../renderer/api/catalog-category-registry";
|
||||
|
||||
export class LensRendererExtension extends LensExtension {
|
||||
globalPages: registries.PageRegistration[] = [];
|
||||
@ -63,8 +64,8 @@ export class LensRendererExtension extends LensExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filtering function for the catalog. This will be removed if the extension is disabled.
|
||||
* @param fn The function which should return a truthy value for those entities which should be kepted
|
||||
* Add a filtering function for the catalog entities. This will be removed if the extension is disabled.
|
||||
* @param fn The function which should return a truthy value for those entities which should be kept.
|
||||
* @returns A function to clean up the filter
|
||||
*/
|
||||
addCatalogFilter(fn: EntityFilter): Disposer {
|
||||
@ -74,4 +75,17 @@ export class LensRendererExtension extends LensExtension {
|
||||
|
||||
return dispose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filtering function for the catalog catogries. This will be removed if the extension is disabled.
|
||||
* @param fn The function which should return a truthy value for those categories which should be kept.
|
||||
* @returns A function to clean up the filter
|
||||
*/
|
||||
addCatalogCategoryFilter(fn: CategoryFilter): Disposer {
|
||||
const dispose = catalogCategoryRegistry.addCatalogCategoryFilter(fn);
|
||||
|
||||
this[Disposers].push(dispose);
|
||||
|
||||
return dispose;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,3 +20,4 @@
|
||||
*/
|
||||
|
||||
export { catalogCategoryRegistry } from "../../common/catalog";
|
||||
export type { CategoryFilter } from "../../common/catalog";
|
||||
|
||||
@ -29,6 +29,7 @@ import { Icon } from "../icon";
|
||||
import { StylesProvider } from "@material-ui/core";
|
||||
import { cssNames } from "../../utils";
|
||||
import type { CatalogCategory } from "../../api/catalog-entity";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
type Props = {
|
||||
activeItem: string;
|
||||
@ -36,7 +37,7 @@ type Props = {
|
||||
};
|
||||
|
||||
function getCategories() {
|
||||
return catalogCategoryRegistry.items;
|
||||
return catalogCategoryRegistry.filteredItems;
|
||||
}
|
||||
|
||||
function getCategoryIcon(category: CatalogCategory) {
|
||||
@ -53,7 +54,7 @@ function Item(props: TreeItemProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function CatalogMenu(props: Props) {
|
||||
export const CatalogMenu = observer((props: Props) => {
|
||||
return (
|
||||
// Overwrite Material UI styles with injectFirst https://material-ui.com/guides/interoperability/#controlling-priority-4
|
||||
<StylesProvider injectFirst>
|
||||
@ -88,4 +89,4 @@ export function CatalogMenu(props: Props) {
|
||||
</div>
|
||||
</StylesProvider>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@ -90,8 +90,8 @@ export class Catalog extends React.Component<Props> {
|
||||
previousActiveTab.set(this.routeActiveTab);
|
||||
|
||||
try {
|
||||
await when(() => (routeTab === "" || !!catalogCategoryRegistry.items.find(i => i.getId() === routeTab)), { timeout: 5_000 }); // we need to wait because extensions might take a while to load
|
||||
const item = catalogCategoryRegistry.items.find(i => i.getId() === routeTab);
|
||||
await when(() => (routeTab === "" || !!catalogCategoryRegistry.filteredItems.find(i => i.getId() === routeTab)), { timeout: 5_000 }); // we need to wait because extensions might take a while to load
|
||||
const item = catalogCategoryRegistry.filteredItems.find(i => i.getId() === routeTab);
|
||||
|
||||
runInAction(() => {
|
||||
this.activeTab = routeTab;
|
||||
@ -103,6 +103,20 @@ export class Catalog extends React.Component<Props> {
|
||||
}
|
||||
}, {fireImmediately: true}),
|
||||
]);
|
||||
|
||||
// If active category is filtered out, automatically switch to the first category
|
||||
disposeOnUnmount(this, reaction(() => catalogCategoryRegistry.filteredItems, () => {
|
||||
if (!catalogCategoryRegistry.filteredItems.find(item => item.getId() === this.catalogEntityStore.activeCategory.getId())) {
|
||||
const item = catalogCategoryRegistry.filteredItems[0];
|
||||
|
||||
runInAction(() => {
|
||||
if (item) {
|
||||
this.activeTab = item.getId();
|
||||
this.catalogEntityStore.activeCategory = item;
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
addToHotbar(item: CatalogEntityItem<CatalogEntity>): void {
|
||||
HotbarStore.getInstance().addToHotbar(item.entity);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user