diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index 53e7a52e4b..1af4302bb1 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -5,13 +5,14 @@ import type { CatalogEntityActionContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus, CatalogCategorySpec } from "../catalog"; import { CatalogEntity, CatalogCategory, categoryVersion } from "../catalog/catalog-entity"; -import { ClusterStore } from "../cluster-store/cluster-store"; import { broadcastMessage } from "../ipc"; import { app } from "electron"; import type { CatalogEntityConstructor, CatalogEntitySpec } from "../catalog/catalog-entity"; import { IpcRendererNavigationEvents } from "../../renderer/navigation/events"; import { requestClusterActivation, requestClusterDisconnection } from "../../renderer/ipc"; import KubeClusterCategoryIcon from "./icons/kubernetes.svg"; +import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api"; +import getClusterByIdInjectable from "../cluster-store/get-by-id.injectable"; export interface KubernetesClusterPrometheusMetrics { address?: { @@ -63,6 +64,8 @@ export function isKubernetesCluster(item: unknown): item is KubernetesCluster { return item instanceof KubernetesCluster; } +const getClusterById = asLegacyGlobalFunctionForExtensionApi(getClusterByIdInjectable); + export class KubernetesCluster< Metadata extends KubernetesClusterMetadata = KubernetesClusterMetadata, Status extends KubernetesClusterStatus = KubernetesClusterStatus, @@ -76,7 +79,7 @@ export class KubernetesCluster< async connect(): Promise { if (app) { - await ClusterStore.getInstance().getById(this.getId())?.activate(); + await getClusterById(this.getId())?.activate(); } else { await requestClusterActivation(this.getId(), false); } @@ -84,7 +87,7 @@ export class KubernetesCluster< async disconnect(): Promise { if (app) { - ClusterStore.getInstance().getById(this.getId())?.disconnect(); + getClusterById(this.getId())?.disconnect(); } else { await requestClusterDisconnection(this.getId(), false); } diff --git a/src/common/catalog-entities/web-link.ts b/src/common/catalog-entities/web-link.ts index b79f798566..5618120ec1 100644 --- a/src/common/catalog-entities/web-link.ts +++ b/src/common/catalog-entities/web-link.ts @@ -34,12 +34,13 @@ export class WebLink extends CatalogEntity di.inject(weblinkStoreInjectable).removeById(this.getId()), + onClick: async () => weblinkStore.removeById(this.getId()), confirm: { message: `Remove Web Link "${this.getName()}" from ${productName}?`, }, diff --git a/src/common/cluster-store/cluster-store.global-override-for-injectable.ts b/src/common/cluster-store/cluster-store.global-override-for-injectable.ts index 32a1ee62a1..f9f6bd8f69 100644 --- a/src/common/cluster-store/cluster-store.global-override-for-injectable.ts +++ b/src/common/cluster-store/cluster-store.global-override-for-injectable.ts @@ -7,11 +7,6 @@ import clusterStoreInjectable from "./cluster-store.injectable"; import type { Cluster } from "../cluster/cluster"; import type { ClusterStore } from "./cluster-store"; -export default getGlobalOverride( - clusterStoreInjectable, - () => - ({ - provideInitialFromMain: () => {}, - getById: (id) => (void id, {}) as Cluster, - } as ClusterStore), -); +export default getGlobalOverride(clusterStoreInjectable, () => ({ + getById: () => ({}) as Cluster, +} as Partial as ClusterStore)); diff --git a/src/common/cluster-store/cluster-store.ts b/src/common/cluster-store/cluster-store.ts index 7b46460013..462c1c6dc3 100644 --- a/src/common/cluster-store/cluster-store.ts +++ b/src/common/cluster-store/cluster-store.ts @@ -10,11 +10,9 @@ import { BaseStore } from "../base-store"; import { Cluster } from "../cluster/cluster"; import migrations from "../../migrations/cluster-store"; import logger from "../../main/logger"; -import { ipcMainHandle } from "../ipc"; import { disposer, toJS } from "../utils"; import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types"; import { requestInitialClusterStates } from "../../renderer/ipc"; -import { clusterStates } from "../ipc/cluster"; import type { CreateCluster } from "../cluster/create-cluster-injection-token"; import type { ReadClusterConfigSync } from "./read-cluster-config.injectable"; import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable"; @@ -58,15 +56,6 @@ export class ClusterStore extends BaseStore { } } - provideInitialFromMain() { - ipcMainHandle(clusterStates, () => ( - this.clustersList.map(cluster => ({ - id: cluster.id, - state: cluster.getState(), - })) - )); - } - protected pushStateToViewsAutomatically() { if (ipcMain) { this.disposer.push( diff --git a/src/extensions/common-api/user-preferences.ts b/src/extensions/common-api/user-preferences.ts index 3a0a93793b..ed925bd05d 100644 --- a/src/extensions/common-api/user-preferences.ts +++ b/src/extensions/common-api/user-preferences.ts @@ -3,7 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { UserStore } from "../../common/user-store"; +import userStoreInjectable from "../../common/user-store/user-store.injectable"; +import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api"; export interface UserPreferenceExtensionItems { /** * Get the configured kubectl binaries path. @@ -11,6 +12,8 @@ export interface UserPreferenceExtensionItems { getKubectlPath: () => string | undefined; } +const userStore = asLegacyGlobalForExtensionApi(userStoreInjectable); + export const Preferences: UserPreferenceExtensionItems = { - getKubectlPath: () => UserStore.getInstance().kubectlBinariesPath, + getKubectlPath: () => userStore.kubectlBinariesPath, }; diff --git a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts index 7bb4a8e540..5c701374ce 100644 --- a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts +++ b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts @@ -12,6 +12,7 @@ import catalogEntityRegistryInjectable from "../../../catalog/entity-registry.in import askUserForFilePathsInjectable from "../../../ipc/ask-user-for-file-paths.injectable"; import applicationMenuItemCompositeInjectable from "../../../../features/application-menu/main/application-menu-item-composite.injectable"; import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; const setupIpcMainHandlersInjectable = getInjectable({ id: "setup-ipc-main-handlers", @@ -24,6 +25,7 @@ const setupIpcMainHandlersInjectable = getInjectable({ const operatingSystemTheme = di.inject(operatingSystemThemeInjectable); const askUserForFilePaths = di.inject(askUserForFilePathsInjectable); const emitAppEvent = di.inject(emitAppEventInjectable); + const getClusterById = di.inject(getClusterByIdInjectable); return { id: "setup-ipc-main-handlers", @@ -37,6 +39,7 @@ const setupIpcMainHandlersInjectable = getInjectable({ operatingSystemTheme, askUserForFilePaths, emitAppEvent, + getClusterById, }); }, }; diff --git a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts index cb6a642a6a..5088fe7804 100644 --- a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts +++ b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts @@ -5,9 +5,9 @@ import type { IpcMainInvokeEvent } from "electron"; import { BrowserWindow, Menu } from "electron"; import { clusterFrameMap } from "../../../../common/cluster-frames"; -import { clusterActivateHandler, clusterSetFrameIdHandler, clusterDisconnectHandler } from "../../../../common/ipc/cluster"; +import { clusterActivateHandler, clusterSetFrameIdHandler, clusterDisconnectHandler, clusterStates } from "../../../../common/ipc/cluster"; import type { ClusterId } from "../../../../common/cluster-types"; -import { ClusterStore } from "../../../../common/cluster-store/cluster-store"; +import type { ClusterStore } from "../../../../common/cluster-store/cluster-store"; import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc"; import type { CatalogEntityRegistry } from "../../../catalog"; import { pushCatalogToRenderer } from "../../../catalog-pusher"; @@ -23,7 +23,7 @@ import type { Composite } from "../../../../common/utils/composite/get-composite import { getApplicationMenuTemplate } from "../../../../features/application-menu/main/populate-application-menu.injectable"; import type { MenuItemRoot } from "../../../../features/application-menu/main/application-menu-item-composite.injectable"; import type { EmitAppEvent } from "../../../../common/app-event-bus/emit-event.injectable"; - +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; interface Dependencies { applicationMenuItemComposite: IComputedValue>; catalogEntityRegistry: CatalogEntityRegistry; @@ -31,6 +31,7 @@ interface Dependencies { operatingSystemTheme: IComputedValue; askUserForFilePaths: AskUserForFilePaths; emitAppEvent: EmitAppEvent; + getClusterById: GetClusterById; } export const setupIpcMainHandlers = ({ @@ -40,15 +41,15 @@ export const setupIpcMainHandlers = ({ operatingSystemTheme, askUserForFilePaths, emitAppEvent, + getClusterById, }: Dependencies) => { ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => { - return ClusterStore.getInstance() - .getById(clusterId) + return getClusterById(clusterId) ?.activate(force); }); ipcMainHandle(clusterSetFrameIdHandler, (event: IpcMainInvokeEvent, clusterId: ClusterId) => { - const cluster = ClusterStore.getInstance().getById(clusterId); + const cluster = getClusterById(clusterId); if (cluster) { clusterFrameMap.set(cluster.id, { frameId: event.frameId, processId: event.processId }); @@ -60,7 +61,7 @@ export const setupIpcMainHandlers = ({ ipcMainHandle(clusterDisconnectHandler, (event, clusterId: ClusterId) => { emitAppEvent({ name: "cluster", action: "stop" }); - const cluster = ClusterStore.getInstance().getById(clusterId); + const cluster = getClusterById(clusterId); if (cluster) { cluster.disconnect(); @@ -92,5 +93,10 @@ export const setupIpcMainHandlers = ({ return operatingSystemTheme.get(); }); - clusterStore.provideInitialFromMain(); + ipcMainHandle(clusterStates, () => ( + clusterStore.clustersList.map(cluster => ({ + id: cluster.id, + state: cluster.getState(), + })) + )); }; diff --git a/src/main/helm/exec.ts b/src/main/helm/exec.ts index 6dbaa3f000..fa96846089 100644 --- a/src/main/helm/exec.ts +++ b/src/main/helm/exec.ts @@ -6,10 +6,10 @@ import { promiseExecFile } from "../../common/utils/promise-exec"; import type { ObjectEncodingOptions } from "fs"; import type { ExecFileOptions, ExecFileOptionsWithStringEncoding } from "child_process"; -import { UserStore } from "../../common/user-store"; import { isChildProcessError } from "../../common/utils"; import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import helmBinaryPathInjectable from "./helm-binary-path.injectable"; +import userStoreInjectable from "../../common/user-store/user-store.injectable"; /** * ExecFile the bundled helm CLI @@ -22,14 +22,15 @@ export async function execHelm(args: string[], { encoding, ...rest }: ObjectEnco }; const di = getLegacyGlobalDiForExtensionApi(); const helmBinaryPath = di.inject(helmBinaryPathInjectable); + const userStore = di.inject(userStoreInjectable); try { const opts = { ...options }; opts.env ??= { ...process.env }; - if (!opts.env.HTTPS_PROXY && UserStore.getInstance().httpsProxy) { - opts.env.HTTPS_PROXY = UserStore.getInstance().httpsProxy; + if (!opts.env.HTTPS_PROXY && userStore.httpsProxy) { + opts.env.HTTPS_PROXY = userStore.httpsProxy; } const { stdout } = await promiseExecFile(helmBinaryPath, args, opts); diff --git a/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.ts b/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.ts deleted file mode 100644 index abfb13e071..0000000000 --- a/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.ts +++ /dev/null @@ -1,21 +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 { UserStore } from "../../../../common/user-store"; -import { getBaseRegistryUrl } from "./get-base-registry-url"; - -const getBaseRegistryUrlInjectable = getInjectable({ - id: "get-base-registry-url", - - instantiate: () => getBaseRegistryUrl({ - // TODO: use injection - getRegistryUrlPreference: () => UserStore.getInstance().extensionRegistryUrl, - }), -}); - -export default getBaseRegistryUrlInjectable; diff --git a/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.tsx b/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.tsx new file mode 100644 index 0000000000..6a03466abd --- /dev/null +++ b/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.injectable.tsx @@ -0,0 +1,58 @@ +/** + * 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 React from "react"; +import execFileInjectable from "../../../../common/fs/exec-file.injectable"; +import loggerInjectable from "../../../../common/logger.injectable"; +import { defaultExtensionRegistryUrl } from "../../../../common/user-store/preferences-helpers"; +import userStoreInjectable from "../../../../common/user-store/user-store.injectable"; +import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable"; + +const getBaseRegistryUrlInjectable = getInjectable({ + id: "get-base-registry-url", + + instantiate: (di) => { + const { extensionRegistryUrl } = di.inject(userStoreInjectable); + const showErrorNotification = di.inject(showErrorNotificationInjectable); + const logger = di.inject(loggerInjectable); + const execFile = di.inject(execFileInjectable); + + return async () => { + switch (extensionRegistryUrl.location) { + case "custom": + return extensionRegistryUrl.customUrl; + + case "npmrc": { + const filteredEnv = Object.fromEntries( + Object.entries(process.env) + .filter(([key]) => !key.startsWith("npm")), + ); + const result = await execFile("npm", ["config", "get", "registry"], { env: filteredEnv }); + + if (result.callWasSuccessful) { + return result.response.trim(); + } + + showErrorNotification(( +

+ Failed to get configured registry from + .npmrc + . Falling back to default registry. +

+ )); + logger.warn("[EXTENSIONS]: failed to get configured registry from .npmrc", result.error); + } + + // fallthrough + default: + case "default": + return defaultExtensionRegistryUrl; + } + }; + }, +}); + +export default getBaseRegistryUrlInjectable; diff --git a/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.tsx b/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.tsx deleted file mode 100644 index c3a4ff8381..0000000000 --- a/src/renderer/components/+extensions/get-base-registry-url/get-base-registry-url.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import React from "react"; -import type { ExtensionRegistry } from "../../../../common/user-store/preferences-helpers"; -import { defaultExtensionRegistryUrl } from "../../../../common/user-store/preferences-helpers"; -import { promiseExecFile } from "../../../utils"; -import { Notifications } from "../../notifications"; - -interface Dependencies { - getRegistryUrlPreference: () => ExtensionRegistry; -} - -export const getBaseRegistryUrl = ({ getRegistryUrlPreference }: Dependencies) => async () => { - const extensionRegistryUrl = getRegistryUrlPreference(); - - switch (extensionRegistryUrl.location) { - case "custom": - return extensionRegistryUrl.customUrl; - - case "npmrc": { - try { - const filteredEnv = Object.fromEntries( - Object.entries(process.env) - .filter(([key]) => !key.startsWith("npm")), - ); - const { stdout } = await promiseExecFile("npm", ["config", "get", "registry"], { env: filteredEnv }); - - return stdout.trim(); - } catch (error) { - Notifications.error(( -

- Failed to get configured registry from - .npmrc - . Falling back to default registry. -

- )); - console.warn("[EXTENSIONS]: failed to get configured registry from .npmrc", error); - } - } - - // fallthrough - default: - case "default": - return defaultExtensionRegistryUrl; - } -}; diff --git a/src/renderer/components/catalog-entities/weblink-add-command.tsx b/src/renderer/components/catalog-entities/weblink-add-command.tsx index 91778f8514..b6daee6e5b 100644 --- a/src/renderer/components/catalog-entities/weblink-add-command.tsx +++ b/src/renderer/components/catalog-entities/weblink-add-command.tsx @@ -7,13 +7,15 @@ import React from "react"; import { observer } from "mobx-react"; import { Input } from "../input"; import { isUrl } from "../input/input_validators"; -import { WeblinkStore } from "../../../common/weblink-store"; +import type { WeblinkStore } from "../../../common/weblink-store"; import { computed, makeObservable, observable } from "mobx"; import { withInjectables } from "@ogre-tools/injectable-react"; import commandOverlayInjectable from "../command-palette/command-overlay.injectable"; +import weblinkStoreInjectable from "../../../common/weblink-store.injectable"; interface Dependencies { closeCommandOverlay: () => void; + weblinkStore: WeblinkStore; } @@ -40,7 +42,7 @@ class NonInjectedWeblinkAddCommand extends React.Component { } onSubmit(name: string) { - WeblinkStore.getInstance().add({ + this.props.weblinkStore.add({ name: name || this.url, url: this.url, }); @@ -64,7 +66,7 @@ class NonInjectedWeblinkAddCommand extends React.Component { value={this.url} onChange={(v) => this.onChangeUrl(v)} onSubmit={(v) => this.onSubmitUrl(v)} - showValidationLine={true} + showValidationLine={true} /> { this.nameHidden && ( @@ -93,7 +95,8 @@ class NonInjectedWeblinkAddCommand extends React.Component { export const WeblinkAddCommand = withInjectables(NonInjectedWeblinkAddCommand, { getProps: (di, props) => ({ - closeCommandOverlay: di.inject(commandOverlayInjectable).close, ...props, + closeCommandOverlay: di.inject(commandOverlayInjectable).close, + weblinkStore: di.inject(weblinkStoreInjectable), }), }); diff --git a/src/renderer/components/dock/logs/list.tsx b/src/renderer/components/dock/logs/list.tsx index 2976a258fa..0290049ccc 100644 --- a/src/renderer/components/dock/logs/list.tsx +++ b/src/renderer/components/dock/logs/list.tsx @@ -15,13 +15,15 @@ import { disposeOnUnmount, observer } from "mobx-react"; import moment from "moment-timezone"; import type { Align, ListOnScrollProps } from "react-window"; import { SearchStore } from "../../../search-store/search-store"; -import { UserStore } from "../../../../common/user-store"; +import type { UserStore } from "../../../../common/user-store"; import { array, autoBind, cssNames } from "../../../utils"; import type { VirtualListRef } from "../../virtual-list"; import { VirtualList } from "../../virtual-list"; import { ToBottom } from "./to-bottom"; import type { LogTabViewModel } from "../logs/logs-view-model"; import { Spinner } from "../../spinner"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import userStoreInjectable from "../../../../common/user-store/user-store.injectable"; export interface LogListProps { model: LogTabViewModel; @@ -33,8 +35,12 @@ export interface LogListRef { scrollToItem: (index: number, align: Align) => void; } +interface Dependencies { + userStore: UserStore; +} + @observer -class NonForwardedLogList extends React.Component }> { +class NonForwardedLogList extends React.Component }> { @observable isJumpButtonVisible = false; @observable isLastLineVisible = true; @@ -122,7 +128,7 @@ class NonForwardedLogList extends React.Component (`${logTimestamp && moment.tz(logTimestamp, UserStore.getInstance().localeTimezone).format()}${log}`)); + .map(([logTimestamp, log]) => (`${logTimestamp && moment.tz(logTimestamp, this.props.userStore.localeTimezone).format()}${log}`)); } /** @@ -273,6 +279,13 @@ class NonForwardedLogList extends React.Component }>(NonForwardedLogList, { + getProps: (di, props) => ({ + ...props, + userStore: di.inject(userStoreInjectable), + }), +}); + export const LogList = React.forwardRef((props, ref) => ( - + )); diff --git a/src/renderer/components/locale-date/locale-date.tsx b/src/renderer/components/locale-date/locale-date.tsx index 3dc95e678b..28b5f6b05a 100644 --- a/src/renderer/components/locale-date/locale-date.tsx +++ b/src/renderer/components/locale-date/locale-date.tsx @@ -6,17 +6,27 @@ import React from "react"; import { observer } from "mobx-react"; import moment from "moment-timezone"; -import { UserStore } from "../../../common/user-store"; +import type { UserStore } from "../../../common/user-store"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import userStoreInjectable from "../../../common/user-store/user-store.injectable"; export interface LocaleDateProps { date: string; } -@observer -export class LocaleDate extends React.Component { - render() { - const { date } = this.props; - - return moment.tz(date, UserStore.getInstance().localeTimezone).format(); - } +interface Dependencies { + userStore: UserStore; } + +const NonInjectedLocaleDate = observer(({ date, userStore }: LocaleDateProps & Dependencies) => ( + <> + {`${moment.tz(date, userStore.localeTimezone).format()}`} + +)); + +export const LocaleDate = withInjectables(NonInjectedLocaleDate, { + getProps: (di, props) => ({ + ...props, + userStore: di.inject(userStoreInjectable), + }), +}); diff --git a/src/renderer/initializers/catalog.tsx b/src/renderer/initializers/catalog.tsx index 2597eb0f3e..908c65a976 100644 --- a/src/renderer/initializers/catalog.tsx +++ b/src/renderer/initializers/catalog.tsx @@ -6,14 +6,17 @@ import React from "react"; import fs from "fs"; import "../../common/catalog-entities/kubernetes-cluster"; -import { ClusterStore } from "../../common/cluster-store/cluster-store"; import { catalogCategoryRegistry } from "../api/catalog-category-registry"; import { WeblinkAddCommand } from "../components/catalog-entities/weblink-add-command"; import { loadConfigFromString } from "../../common/kube-helpers"; import type { OpenDeleteClusterDialog } from "../components/delete-cluster-dialog/open.injectable"; +import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api"; +import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable"; + +const getClusterById = asLegacyGlobalFunctionForExtensionApi(getClusterByIdInjectable); async function onClusterDelete(clusterId: string, openDeleteClusterDialog: OpenDeleteClusterDialog) { - const cluster = ClusterStore.getInstance().getById(clusterId); + const cluster = getClusterById(clusterId); if (!cluster) { return console.warn("[KUBERNETES-CLUSTER]: cannot delete cluster, does not exist in store", { clusterId }); diff --git a/src/renderer/ipc/list-namespaces-forbidden-handler.injectable.tsx b/src/renderer/ipc/list-namespaces-forbidden-handler.injectable.tsx index 6ee14d7857..dda488df06 100644 --- a/src/renderer/ipc/list-namespaces-forbidden-handler.injectable.tsx +++ b/src/renderer/ipc/list-namespaces-forbidden-handler.injectable.tsx @@ -6,12 +6,12 @@ import { getInjectable } from "@ogre-tools/injectable"; import navigateToEntitySettingsInjectable from "../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable"; import type { ListNamespaceForbiddenArgs } from "../../common/ipc/cluster"; import { Notifications } from "../components/notifications"; -import { ClusterStore } from "../../common/cluster-store/cluster-store"; import { Button } from "../components/button"; import type { IpcRendererEvent } from "electron"; import React from "react"; import notificationsStoreInjectable from "../components/notifications/notifications-store.injectable"; import { getMillisecondsFromUnixEpoch } from "../../common/utils/date/get-current-date-time"; +import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable"; const listNamespacesForbiddenHandlerInjectable = getInjectable({ id: "list-namespaces-forbidden-handler", @@ -19,6 +19,7 @@ const listNamespacesForbiddenHandlerInjectable = getInjectable({ instantiate: (di) => { const navigateToEntitySettings = di.inject(navigateToEntitySettingsInjectable); const notificationsStore = di.inject(notificationsStoreInjectable); + const getClusterById = di.inject(getClusterByIdInjectable); const notificationLastDisplayedAt = new Map(); const intervalBetweenNotifications = 1000 * 60; // 60s @@ -52,7 +53,7 @@ const listNamespacesForbiddenHandlerInjectable = getInjectable({ Add Accessible Namespaces

{"Cluster "} - {ClusterStore.getInstance().getById(clusterId)?.name ?? ""} + {getClusterById(clusterId)?.name ?? ""} {" does not have permissions to list namespaces. Please add the namespaces you have access to."}

diff --git a/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable.ts b/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable.ts index cb6f4652ce..aaffe8dc32 100644 --- a/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable.ts +++ b/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.injectable.ts @@ -15,6 +15,7 @@ import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.i // TODO: Importing from features is not OK. Make protocol-router to comply with Open Closed Principle to allow moving implementation under a feature import navigateToPreferencesInjectable from "../../../features/preferences/common/navigate-to-preferences.injectable"; +import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable"; const bindProtocolAddRouteHandlersInjectable = getInjectable({ id: "bind-protocol-add-route-handlers", @@ -29,6 +30,7 @@ const bindProtocolAddRouteHandlersInjectable = getInjectable({ navigateToClusterView: di.inject(navigateToClusterViewInjectable), navigateToPreferences: di.inject(navigateToPreferencesInjectable), entityRegistry: di.inject(catalogEntityRegistryInjectable), + getClusterById: di.inject(getClusterByIdInjectable), }), }); diff --git a/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.tsx b/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.tsx index ad8b0e007f..12a95a101d 100644 --- a/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.tsx +++ b/src/renderer/protocol-handler/bind-protocol-add-route-handlers/bind-protocol-add-route-handlers.tsx @@ -6,7 +6,6 @@ import React from "react"; import type { LensProtocolRouterRenderer } from "../lens-protocol-router-renderer/lens-protocol-router-renderer"; import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry"; -import { ClusterStore } from "../../../common/cluster-store/cluster-store"; import { EXTENSION_NAME_MATCH, EXTENSION_PUBLISHER_MATCH, @@ -18,6 +17,7 @@ import type { NavigateToEntitySettings } from "../../../common/front-end-routing import type { NavigateToClusterView } from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable"; import assert from "assert"; import type { AttemptInstallByInfo } from "../../components/+extensions/attempt-install-by-info.injectable"; +import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable"; // TODO: make it so that the handlers are type safe and we don't need to do the asserts interface Dependencies { @@ -30,6 +30,7 @@ interface Dependencies { navigateToClusterView: NavigateToClusterView; navigateToPreferences: (tabId: string) => void; entityRegistry: CatalogEntityRegistry; + getClusterById: GetClusterById; } export const bindProtocolAddRouteHandlers = ({ @@ -42,6 +43,7 @@ export const bindProtocolAddRouteHandlers = ({ navigateToClusterView, navigateToPreferences, entityRegistry, + getClusterById, }: Dependencies) => () => { lensProtocolRouterRenderer .addInternalHandler("/preferences", ({ search: { highlight: tabId }}) => { @@ -93,7 +95,7 @@ export const bindProtocolAddRouteHandlers = ({ // Handlers below are deprecated and only kept for backward compact purposes .addInternalHandler("/cluster/:clusterId", ({ pathname: { clusterId }}) => { assert(clusterId); - const cluster = ClusterStore.getInstance().getById(clusterId); + const cluster = getClusterById(clusterId); if (cluster) { navigateToClusterView(clusterId); @@ -109,7 +111,7 @@ export const bindProtocolAddRouteHandlers = ({ }) .addInternalHandler("/cluster/:clusterId/settings", ({ pathname: { clusterId }}) => { assert(clusterId); - const cluster = ClusterStore.getInstance().getById(clusterId); + const cluster = getClusterById(clusterId); if (cluster) { navigateToEntitySettings(clusterId);