1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Add more tsconfig files, fix bug in <Catalog>

- Make all of history, navigation injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-22 09:59:26 -04:00
parent 7dde2326bf
commit 187850890a
12 changed files with 107 additions and 64 deletions

6
build/tsconfig.json Normal file
View File

@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*",
]
}

View File

@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*",
]
}

View File

@ -5,12 +5,14 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { catalogEntityStore } from "./catalog-entity.store"; import { catalogEntityStore } from "./catalog-entity.store";
import catalogEntityRegistryInjectable from "../../../api/catalog-entity-registry/catalog-entity-registry.injectable"; import catalogEntityRegistryInjectable from "../../../api/catalog-entity-registry/catalog-entity-registry.injectable";
import catalogCategoryRegistryInjectable from "../../../../common/catalog/category-registry.injectable";
const catalogEntityStoreInjectable = getInjectable({ const catalogEntityStoreInjectable = getInjectable({
id: "catalog-entity-store", id: "catalog-entity-store",
instantiate: (di) => catalogEntityStore({ instantiate: (di) => catalogEntityStore({
registry: di.inject(catalogEntityRegistryInjectable), entityRegistry: di.inject(catalogEntityRegistryInjectable),
catalogRegistry: di.inject(catalogCategoryRegistryInjectable),
}), }),
}); });

View File

@ -7,14 +7,14 @@ import type { IComputedValue, IObservableValue } from "mobx";
import { computed, observable, reaction } from "mobx"; import { computed, observable, reaction } from "mobx";
import type { CatalogEntityRegistry } from "../../../api/catalog-entity-registry"; import type { CatalogEntityRegistry } from "../../../api/catalog-entity-registry";
import type { CatalogEntity } from "../../../api/catalog-entity"; import type { CatalogEntity } from "../../../api/catalog-entity";
import type { CatalogCategory } from "../../../../common/catalog"; import type { CatalogCategory, CatalogCategoryRegistry } from "../../../../common/catalog";
import { catalogCategoryRegistry } from "../../../../common/catalog";
import type { Disposer } from "../../../../common/utils"; import type { Disposer } from "../../../../common/utils";
import { disposer } from "../../../../common/utils"; import { disposer } from "../../../../common/utils";
import type { ItemListStore } from "../../item-object-list"; import type { ItemListStore } from "../../item-object-list";
interface Dependencies { interface Dependencies {
registry: CatalogEntityRegistry; entityRegistry: CatalogEntityRegistry;
catalogRegistry: CatalogCategoryRegistry;
} }
export type CatalogEntityStore = ItemListStore<CatalogEntity, false> & { export type CatalogEntityStore = ItemListStore<CatalogEntity, false> & {
@ -26,15 +26,18 @@ export type CatalogEntityStore = ItemListStore<CatalogEntity, false> & {
onRun(entity: CatalogEntity): void; onRun(entity: CatalogEntity): void;
}; };
export function catalogEntityStore({ registry }: Dependencies): CatalogEntityStore { export function catalogEntityStore({
entityRegistry,
catalogRegistry,
}: Dependencies): CatalogEntityStore {
const activeCategory = observable.box<CatalogCategory | undefined>(undefined); const activeCategory = observable.box<CatalogCategory | undefined>(undefined);
const selectedItemId = observable.box<string | undefined>(undefined); const selectedItemId = observable.box<string | undefined>(undefined);
const entities = computed(() => { const entities = computed(() => {
const category = activeCategory.get(); const category = activeCategory.get();
return category return category
? registry.getItemsForCategory(category, { filtered: true }) ? entityRegistry.getItemsForCategory(category, { filtered: true })
: registry.filteredItems; : entityRegistry.filteredItems;
}); });
const selectedItem = computed(() => { const selectedItem = computed(() => {
const id = selectedItemId.get(); const id = selectedItemId.get();
@ -51,7 +54,7 @@ export function catalogEntityStore({ registry }: Dependencies): CatalogEntitySto
if (category) { if (category) {
category.emit("load"); category.emit("load");
} else { } else {
for (const category of catalogCategoryRegistry.items) { for (const category of catalogRegistry.items) {
category.emit("load"); category.emit("load");
} }
} }
@ -66,9 +69,9 @@ export function catalogEntityStore({ registry }: Dependencies): CatalogEntitySto
reaction(() => entities.get(), loadAll), reaction(() => entities.get(), loadAll),
reaction(() => activeCategory.get(), loadAll, { delay: 100 }), reaction(() => activeCategory.get(), loadAll, { delay: 100 }),
), ),
onRun: entity => registry.onRun(entity), onRun: entity => entityRegistry.onRun(entity),
failedLoading: false, failedLoading: false,
getTotalCount: () => registry.filteredItems.length, getTotalCount: () => entityRegistry.filteredItems.length,
isLoaded: true, isLoaded: true,
isSelected: (item) => item.getId() === selectedItemId.get(), isSelected: (item) => item.getId() === selectedItemId.get(),
isSelectedAll: () => false, isSelectedAll: () => false,

View File

@ -153,7 +153,7 @@ class NonInjectedCatalog extends React.Component<Dependencies> {
} }
onDetails = (entity: CatalogEntity) => { onDetails = (entity: CatalogEntity) => {
if (this.props.catalogEntityStore.selectedItemId) { if (this.props.catalogEntityStore.selectedItemId.get()) {
this.props.catalogEntityStore.selectedItemId.set(undefined); this.props.catalogEntityStore.selectedItemId.set(undefined);
} else { } else {
this.props.catalogEntityStore.onRun(entity); this.props.catalogEntityStore.onRun(entity);

View File

@ -10,10 +10,7 @@ import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as
import getValueFromRegisteredChannelInjectable from "./app-paths/get-value-from-registered-channel/get-value-from-registered-channel.injectable"; import getValueFromRegisteredChannelInjectable from "./app-paths/get-value-from-registered-channel/get-value-from-registered-channel.injectable";
import loggerInjectable from "../common/logger.injectable"; import loggerInjectable from "../common/logger.injectable";
import { overrideFsWithFakes } from "../test-utils/override-fs-with-fakes"; import { overrideFsWithFakes } from "../test-utils/override-fs-with-fakes";
import observableHistoryInjectable from "./navigation/observable-history.injectable";
import { searchParamsOptions } from "./navigation";
import { createMemoryHistory } from "history"; import { createMemoryHistory } from "history";
import { createObservableHistory } from "mobx-observable-history";
import registerIpcChannelListenerInjectable from "./app-paths/get-value-from-registered-channel/register-ipc-channel-listener.injectable"; import registerIpcChannelListenerInjectable from "./app-paths/get-value-from-registered-channel/register-ipc-channel-listener.injectable";
import focusWindowInjectable from "./ipc-channel-listeners/focus-window.injectable"; import focusWindowInjectable from "./ipc-channel-listeners/focus-window.injectable";
import extensionsStoreInjectable from "../extensions/extensions-store/extensions-store.injectable"; import extensionsStoreInjectable from "../extensions/extensions-store/extensions-store.injectable";
@ -40,6 +37,7 @@ import { observable, toJS } from "mobx";
import type { Draft } from "immer"; import type { Draft } from "immer";
import { produce, isDraft } from "immer"; import { produce, isDraft } from "immer";
import type { GetDiForUnitTestingOptions } from "../test-utils/get-dis-for-unit-testing"; import type { GetDiForUnitTestingOptions } from "../test-utils/get-dis-for-unit-testing";
import historyInjectable from "./navigation/history/history.injectable";
export interface GetRendererDiForUnitTestingOptions extends GetDiForUnitTestingOptions { export interface GetRendererDiForUnitTestingOptions extends GetDiForUnitTestingOptions {
overrideCreateStorage?: boolean; overrideCreateStorage?: boolean;
@ -78,6 +76,8 @@ export const getDiForUnitTesting = (opts: GetRendererDiForUnitTestingOptions = {
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake); di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
di.override(joinPathsInjectable, () => joinPathsFake); di.override(joinPathsInjectable, () => joinPathsFake);
di.override(historyInjectable, () => createMemoryHistory());
// eslint-disable-next-line unused-imports/no-unused-vars-ts // eslint-disable-next-line unused-imports/no-unused-vars-ts
di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore); di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore);
@ -94,14 +94,6 @@ export const getDiForUnitTesting = (opts: GetRendererDiForUnitTestingOptions = {
overrideFsWithFakes(di); overrideFsWithFakes(di);
di.override(observableHistoryInjectable, () => {
const historyFake = createMemoryHistory();
return createObservableHistory(historyFake, {
searchParams: searchParamsOptions,
});
});
di.override(focusWindowInjectable, () => () => {}); di.override(focusWindowInjectable, () => () => {});
di.override(loggerInjectable, () => ({ di.override(loggerInjectable, () => ({

View File

@ -3,33 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { ipcRenderer } from "electron"; import { asLegacyGlobalForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import { createBrowserHistory, createMemoryHistory } from "history"; import observableHistoryInjectable from "./history/observable.injectable";
import type { ObservableSearchParamsOptions } from "mobx-observable-history";
import { createObservableHistory } from "mobx-observable-history";
import logger from "../../main/logger";
export const searchParamsOptions: ObservableSearchParamsOptions = { export { searchParamsOptions } from "./history/search-params";
skipEmpty: true, // skip empty params, e.g. "?x=&y2=" will be "?y=2"
joinArrays: false, // join multiple params with same name, e.g. "?x=1&x=2" => "?x=1,2"
joinArraysWith: ",", // param values splitter, applicable only with {joinArrays:true}
};
/**
* @deprecated: Switch to using di.inject(historyInjectable)
*/
export const history = ipcRenderer ? createBrowserHistory() : createMemoryHistory();
/** /**
* @deprecated: Switch to using di.inject(observableHistoryInjectable) * @deprecated: Switch to using di.inject(observableHistoryInjectable)
*/ */
export const navigation = createObservableHistory(history, { export const navigation = asLegacyGlobalForExtensionApi(observableHistoryInjectable);
searchParams: searchParamsOptions,
});
navigation.listen((location, action) => {
const isClusterView = !process.isMainFrame;
const domain = global.location.href;
logger.debug(`[NAVIGATION]: ${action}-ing. Current is now:`, { isClusterView, domain, location });
});

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { history } from "./history"; import { createBrowserHistory } from "history";
const historyInjectable = getInjectable({ const historyInjectable = getInjectable({
id: "history", id: "history",
instantiate: () => history, instantiate: () => createBrowserHistory(),
}); });
export default historyInjectable; export default historyInjectable;

View File

@ -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 { createObservableHistory } from "mobx-observable-history";
import loggerInjectable from "../../../common/logger.injectable";
import { searchParamsOptions } from "./search-params";
import historyInjectable from "./history.injectable";
const observableHistoryInjectable = getInjectable({
id: "observable-history",
instantiate: (di) => {
const history = di.inject(historyInjectable);
const logger = di.inject(loggerInjectable);
const navigation = createObservableHistory(history, {
searchParams: searchParamsOptions,
});
navigation.listen((location, action) => {
const isClusterView = !process.isMainFrame;
const domain = global.location.href;
logger.debug(`[NAVIGATION]: ${action}-ing. Current is now:`, { isClusterView, domain, location });
});
return navigation;
},
});
export default observableHistoryInjectable;

View File

@ -0,0 +1,12 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ObservableSearchParamsOptions } from "mobx-observable-history";
export const searchParamsOptions: ObservableSearchParamsOptions = {
skipEmpty: true, // skip empty params, e.g. "?x=&y2=" will be "?y=2"
joinArrays: false, // join multiple params with same name, e.g. "?x=1&x=2" => "?x=1,2"
joinArraysWith: ",", // param values splitter, applicable only with {joinArrays:true}
};

View File

@ -1,15 +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 { navigation as observableHistory } from "./history";
const observableHistoryInjectable = getInjectable({
id: "observable-history",
causesSideEffects: true,
instantiate: () => observableHistory,
});
export default observableHistoryInjectable;

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type React from "react";
/**
* Returns `true` if `node` is a falsy value
*/
export function isNodeFalsy(node: React.ReactNode): boolean {
return !isNodeRenderable(node);
}
/**
* Return `true` if React would render this
*/
export function isNodeRenderable(node: React.ReactNode): boolean {
return Boolean(node);
}
/**
* Returns the first react node provided that is would be rendered by react
*/
export function foldNodes(...nodes: React.ReactNode[]): React.ReactNode {
return nodes.find(isNodeRenderable);
}