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

Remove all uses of legacy global Notification functions

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-01-03 12:11:26 -05:00
parent 2aa9fc972e
commit b86eb3d8db
40 changed files with 418 additions and 369 deletions

View File

@ -22,6 +22,11 @@ import notificationsStoreInjectable from "../../renderer/components/notification
import podStoreInjectable from "../../renderer/components/+workloads-pods/store.injectable";
import getDetailsUrlInjectable from "../../renderer/components/kube-detail-params/get-details-url.injectable";
import showDetailsInjectable from "../../renderer/components/kube-detail-params/show-details.injectable";
import showCheckedErrorNotificationInjectable from "../../renderer/components/notifications/show-checked-error.injectable";
import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable";
import showInfoNotificationInjectable from "../../renderer/components/notifications/show-info-notification.injectable";
import showShortInfoNotificationInjectable from "../../renderer/components/notifications/show-short-info.injectable";
import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable";
// layouts
export * from "../../renderer/components/layout/main-layout";
@ -67,7 +72,25 @@ export * from "../../renderer/components/drawer";
export * from "../../renderer/components/dialog";
export * from "../../renderer/components/line-progress";
export * from "../../renderer/components/menu";
export * from "../../renderer/components/notifications";
export type {
CreateNotificationOptions,
Notification,
NotificationId,
NotificationMessage,
NotificationStatus,
ShowNotification,
NotificationsStore,
} from "../../renderer/components/notifications";
export const Notifications = {
ok: asLegacyGlobalFunctionForExtensionApi(showSuccessNotificationInjectable),
error: asLegacyGlobalFunctionForExtensionApi(showErrorNotificationInjectable),
checkedError: asLegacyGlobalFunctionForExtensionApi(showCheckedErrorNotificationInjectable),
info: asLegacyGlobalFunctionForExtensionApi(showInfoNotificationInjectable),
shortInfo: asLegacyGlobalFunctionForExtensionApi(showShortInfoNotificationInjectable),
};
export * from "../../renderer/components/spinner";
export * from "../../renderer/components/stepper";
export * from "../../renderer/components/wizard";

View File

@ -16,7 +16,7 @@ import { loadConfigFromString, splitConfig } from "../../../common/kube-helpers"
import { docsUrl } from "../../../common/vars";
import { isDefined, iter } from "../../utils";
import { Button } from "../button";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { SettingLayout } from "../layout/setting-layout";
import { MonacoEditor } from "../monaco-editor";
import { withInjectables } from "@ogre-tools/injectable-react";
@ -27,6 +27,8 @@ import type { EmitAppEvent } from "../../../common/app-event-bus/emit-event.inje
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
import type { GetDirnameOfPath } from "../../../common/path/get-dirname.injectable";
import getDirnameOfPathInjectable from "../../../common/path/get-dirname.injectable";
import showSuccessNotificationInjectable from "../notifications/show-success-notification.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
interface Option {
config: KubeConfig;
@ -38,6 +40,8 @@ interface Dependencies {
navigateToCatalog: NavigateToCatalog;
getDirnameOfPath: GetDirnameOfPath;
emitAppEvent: EmitAppEvent;
showSuccessNotification: ShowNotification;
showErrorNotification: ShowNotification;
}
function getContexts(config: KubeConfig): Map<string, Option> {
@ -97,11 +101,11 @@ class NonInjectedAddCluster extends React.Component<Dependencies> {
await fse.ensureDir(this.props.getDirnameOfPath(absPath));
await fse.writeFile(absPath, this.customConfig.trim(), { encoding: "utf-8", mode: 0o600 });
Notifications.ok(`Successfully added ${this.kubeContexts.size} new cluster(s)`);
this.props.showSuccessNotification(`Successfully added ${this.kubeContexts.size} new cluster(s)`);
return this.props.navigateToCatalog();
} catch (error) {
Notifications.error(`Failed to add clusters: ${error}`);
this.props.showErrorNotification(`Failed to add clusters: ${error}`);
}
});
@ -163,5 +167,7 @@ export const AddCluster = withInjectables<Dependencies>(NonInjectedAddCluster, {
navigateToCatalog: di.inject(navigateToCatalogInjectable),
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
emitAppEvent: di.inject(emitAppEventInjectable),
showSuccessNotification: di.inject(showSuccessNotificationInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -18,13 +18,14 @@ import type { IResourceQuotaValues, ResourceQuotaApi } from "../../../../common/
import { Select } from "../../select";
import { Icon } from "../../icon";
import { Button } from "../../button";
import { Notifications } from "../../notifications";
import { NamespaceSelect } from "../../+namespaces/namespace-select";
import { SubTitle } from "../../layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import closeAddQuotaDialogInjectable from "./close.injectable";
import isAddQuotaDialogOpenInjectable from "./is-open.injectable";
import resourceQuotaApiInjectable from "../../../../common/k8s-api/endpoints/resource-quota.api.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface AddQuotaDialogProps extends DialogProps {
}
@ -33,6 +34,7 @@ interface Dependencies {
resourceQuotaApi: ResourceQuotaApi;
isAddQuotaDialogOpen: IComputedValue<boolean>;
closeAddQuotaDialog: () => void;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
const defaultQuotas = JSON.stringify({
@ -128,7 +130,7 @@ class NonInjectedAddQuotaDialog extends React.Component<AddQuotaDialogProps & De
});
this.close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while creating ResourceQuota");
this.props.showCheckedErrorNotification(err, "Unknown error occured while creating ResourceQuota");
}
};
@ -250,5 +252,6 @@ export const AddQuotaDialog = withInjectables<Dependencies, AddQuotaDialogProps>
closeAddQuotaDialog: di.inject(closeAddQuotaDialogInjectable),
isAddQuotaDialogOpen: di.inject(isAddQuotaDialogOpenInjectable),
resourceQuotaApi: di.inject(resourceQuotaApiInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -21,7 +21,6 @@ import { NamespaceSelect } from "../../+namespaces/namespace-select";
import { Select } from "../../select";
import { Icon } from "../../icon";
import { base64, iter } from "../../../utils";
import { Notifications } from "../../notifications";
import upperFirst from "lodash/upperFirst";
import { fromEntries } from "../../../../common/utils/objects";
import type { ShowDetails } from "../../kube-detail-params/show-details.injectable";
@ -30,6 +29,8 @@ import closeAddSecretDialogInjectable from "./close.injectable";
import secretApiInjectable from "../../../../common/k8s-api/endpoints/secret.api.injectable";
import showDetailsInjectable from "../../kube-detail-params/show-details.injectable";
import isAddSecretDialogOpenInjectable from "./is-open.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface AddSecretDialogProps extends Partial<DialogProps> {
}
@ -54,6 +55,7 @@ interface Dependencies {
isAddSecretDialogOpen: IComputedValue<boolean>;
closeAddSecretDialog: () => void;
showDetails: ShowDetails;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -116,7 +118,7 @@ class NonInjectedAddSecretDialog extends React.Component<AddSecretDialogProps &
this.props.showDetails(newSecret?.selfLink);
this.close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while creating a Secret");
this.props.showCheckedErrorNotification(err, "Unknown error occured while creating a Secret");
}
};
@ -254,5 +256,6 @@ export const AddSecretDialog = withInjectables<Dependencies, AddSecretDialogProp
secretApi: di.inject(secretApiInjectable),
showDetails: di.inject(showDetailsInjectable),
isAddSecretDialogOpen: di.inject(isAddSecretDialogOpenInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -14,7 +14,7 @@ import createTempFilesAndValidateInjectable from "./create-temp-files-and-valida
import extensionInstallationStateStoreInjectable from "../../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import type { Disposer } from "../../../../common/utils";
import { disposer } from "../../../../common/utils";
import { Notifications } from "../../notifications";
import type { ShowNotification } from "../../notifications";
import { Button } from "../../button";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
import type { LensExtensionId } from "../../../../extensions/lens-extension";
@ -23,6 +23,8 @@ import { remove as removeDir } from "fs-extra";
import { shell } from "electron";
import type { ExtensionInstallationStateStore } from "../../../../extensions/extension-installation-state-store/extension-installation-state-store";
import { ExtensionInstallationState } from "../../../../extensions/extension-installation-state-store/extension-installation-state-store";
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
import showInfoNotificationInjectable from "../../notifications/show-info-notification.injectable";
export interface InstallRequest {
fileName: string;
@ -36,6 +38,8 @@ interface Dependencies {
createTempFilesAndValidate: CreateTempFilesAndValidate;
getExtensionDestFolder: GetExtensionDestFolder;
installStateStore: ExtensionInstallationStateStore;
showErrorNotification: ShowNotification;
showInfoNotification: ShowNotification;
}
export type AttemptInstall = (request: InstallRequest, cleanup?: Disposer) => Promise<void>;
@ -47,6 +51,8 @@ const attemptInstall = ({
createTempFilesAndValidate,
getExtensionDestFolder,
installStateStore,
showErrorNotification,
showInfoNotification,
}: Dependencies): AttemptInstall =>
async (request, cleanup) => {
const dispose = disposer(
@ -66,7 +72,7 @@ const attemptInstall = ({
if (curState !== ExtensionInstallationState.IDLE) {
dispose();
return void Notifications.error(
return void showErrorNotification(
<div className="flex column gaps">
<b>Extension Install Collision:</b>
<p>
@ -86,7 +92,7 @@ const attemptInstall = ({
const { version: oldVersion } = installedExtension.manifest;
// confirm to uninstall old version before installing new version
const removeNotification = Notifications.info(
const removeNotification = showInfoNotification(
<div className="InstallingExtensionNotification flex gaps align-center">
<div className="flex column gaps">
<p>
@ -142,6 +148,8 @@ const attemptInstallInjectable = getInjectable({
createTempFilesAndValidate: di.inject(createTempFilesAndValidateInjectable),
getExtensionDestFolder: di.inject(getExtensionDestFolderInjectable),
installStateStore: di.inject(extensionInstallationStateStoreInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
showInfoNotification: di.inject(showInfoNotificationInjectable),
}),
});

View File

@ -9,10 +9,11 @@ import extensionDiscoveryInjectable from "../../../extensions/extension-discover
import loggerInjectable from "../../../common/logger.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import { extensionDisplayName } from "../../../extensions/lens-extension";
import { Notifications } from "../notifications";
import React from "react";
import { when } from "mobx";
import { getMessageFromError } from "./get-message-from-error/get-message-from-error";
import showSuccessNotificationInjectable from "../notifications/show-success-notification.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
const uninstallExtensionInjectable = getInjectable({
id: "uninstall-extension",
@ -22,6 +23,8 @@ const uninstallExtensionInjectable = getInjectable({
const extensionDiscovery = di.inject(extensionDiscoveryInjectable);
const extensionInstallationStateStore = di.inject(extensionInstallationStateStoreInjectable);
const logger = di.inject(loggerInjectable);
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
const showErrorNotification = di.inject(showErrorNotificationInjectable);
return async (extensionId: LensExtensionId): Promise<boolean> => {
const ext = extensionLoader.getExtension(extensionId);
@ -44,7 +47,7 @@ const uninstallExtensionInjectable = getInjectable({
// wait for the ExtensionLoader to actually uninstall the extension
await when(() => !extensionLoader.userExtensions.has(extensionId));
Notifications.ok(
showSuccessNotification(
<p>
{"Extension "}
<b>{displayName}</b>
@ -60,7 +63,7 @@ const uninstallExtensionInjectable = getInjectable({
`[EXTENSION-UNINSTALL]: uninstalling ${displayName} has failed: ${error}`,
{ error },
);
Notifications.error(
showErrorNotification(
<p>
{"Uninstalling extension "}
<b>{displayName}</b>

View File

@ -14,7 +14,6 @@ import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../../wizard";
import type { HelmRelease } from "../../../../common/k8s-api/endpoints/helm-releases.api";
import { Select } from "../../select";
import { Notifications } from "../../notifications";
import orderBy from "lodash/orderBy";
import { withInjectables } from "@ogre-tools/injectable-react";
import releaseRollbackDialogStateInjectable from "./state.injectable";
@ -22,6 +21,8 @@ import type { RollbackRelease } from "../rollback-release/rollback-release.injec
import rollbackReleaseInjectable from "../rollback-release/rollback-release.injectable";
import type { HelmReleaseRevision, RequestHelmReleaseHistory } from "../../../../common/k8s-api/endpoints/helm-releases.api/request-history.injectable";
import requestHelmReleaseHistoryInjectable from "../../../../common/k8s-api/endpoints/helm-releases.api/request-history.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface ReleaseRollbackDialogProps extends DialogProps {
}
@ -30,6 +31,7 @@ interface Dependencies {
rollbackRelease: RollbackRelease;
state: IObservableValue<HelmRelease | undefined>;
requestHelmReleaseHistory: RequestHelmReleaseHistory;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -71,7 +73,7 @@ class NonInjectedReleaseRollbackDialog extends React.Component<ReleaseRollbackDi
await this.props.rollbackRelease(release.getName(), release.getNs(), revision.revision);
this.close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while rolling back release");
this.props.showCheckedErrorNotification(err, "Unknown error occured while rolling back release");
}
};
@ -143,5 +145,6 @@ export const ReleaseRollbackDialog = withInjectables<Dependencies, ReleaseRollba
rollbackRelease: di.inject(rollbackReleaseInjectable),
state: di.inject(releaseRollbackDialogStateInjectable),
requestHelmReleaseHistory: di.inject(requestHelmReleaseHistoryInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -15,13 +15,14 @@ import { Wizard, WizardStep } from "../../wizard";
import type { Namespace } from "../../../../common/k8s-api/endpoints";
import { Input } from "../../input";
import { systemName } from "../../input/input_validators";
import { Notifications } from "../../notifications";
import { withInjectables } from "@ogre-tools/injectable-react";
import namespaceStoreInjectable from "../store.injectable";
import addNamespaceDialogStateInjectable
from "./state.injectable";
import type { NamespaceStore } from "../store";
import { autoBind } from "../../../utils";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface AddNamespaceDialogProps extends DialogProps {
onSuccess?(ns: Namespace): void;
@ -31,6 +32,7 @@ export interface AddNamespaceDialogProps extends DialogProps {
interface Dependencies {
namespaceStore: NamespaceStore;
state: IObservableValue<boolean>;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -63,7 +65,7 @@ class NonInjectedAddNamespaceDialog extends React.Component<AddNamespaceDialogPr
onSuccess?.(created);
this.close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while creating the namespace");
this.props.showCheckedErrorNotification(err, "Unknown error occured while creating the namespace");
onError?.(err);
}
}
@ -112,5 +114,6 @@ export const AddNamespaceDialog = withInjectables<Dependencies, AddNamespaceDial
...props,
namespaceStore: di.inject(namespaceStoreInjectable),
state: di.inject(addNamespaceDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -10,12 +10,13 @@ import type { MenuActionsProps } from "../menu/menu-actions";
import { MenuActions } from "../menu/menu-actions";
import { MenuItem } from "../menu";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { withInjectables } from "@ogre-tools/injectable-react";
import portForwardDialogModelInjectable from "../../port-forward/port-forward-dialog-model/port-forward-dialog-model.injectable";
import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable";
import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable";
import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
export interface PortForwardMenuProps extends MenuActionsProps {
portForward: PortForwardItem;
@ -26,6 +27,7 @@ interface Dependencies {
portForwardStore: PortForwardStore;
openPortForwardDialog: (item: PortForwardItem) => void;
openPortForward: OpenPortForward;
showErrorNotification: ShowNotification;
}
class NonInjectedPortForwardMenu<Props extends PortForwardMenuProps & Dependencies> extends React.Component<Props> {
@ -35,12 +37,12 @@ class NonInjectedPortForwardMenu<Props extends PortForwardMenuProps & Dependenci
}
remove() {
const { portForward } = this.props;
const { portForward, showErrorNotification } = this.props;
try {
this.portForwardStore.remove(portForward);
} catch (error) {
Notifications.error(`Error occurred stopping the port-forward from port ${portForward.forwardPort}. The port-forward may still be active.`);
showErrorNotification(`Error occurred stopping the port-forward from port ${portForward.forwardPort}. The port-forward may still be active.`);
}
}
@ -49,14 +51,14 @@ class NonInjectedPortForwardMenu<Props extends PortForwardMenuProps & Dependenci
}
private startPortForwarding = async () => {
const { portForward } = this.props;
const { portForward, showErrorNotification } = this.props;
const pf = await this.portForwardStore.start(portForward);
if (pf.status === "Disabled") {
const { name, kind, forwardPort } = portForward;
Notifications.error(`Error occurred starting port-forward, the local port ${forwardPort} may not be available or the ${kind} ${name} may not be reachable`);
showErrorNotification(`Error occurred starting port-forward, the local port ${forwardPort} may not be available or the ${kind} ${name} may not be reachable`);
}
};
@ -134,15 +136,12 @@ class NonInjectedPortForwardMenu<Props extends PortForwardMenuProps & Dependenci
}
}
export const PortForwardMenu = withInjectables<Dependencies, PortForwardMenuProps>(
NonInjectedPortForwardMenu,
{
getProps: (di, props) => ({
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
openPortForward: di.inject(openPortForwardInjectable),
...props,
}),
},
);
export const PortForwardMenu = withInjectables<Dependencies, PortForwardMenuProps>(NonInjectedPortForwardMenu, {
getProps: (di, props) => ({
...props,
portForwardStore: di.inject(portForwardStoreInjectable),
openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open,
openPortForward: di.inject(openPortForwardInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -10,7 +10,7 @@ import { disposeOnUnmount, observer } from "mobx-react";
import type { Service, ServicePort } from "../../../common/k8s-api/endpoints";
import { action, makeObservable, observable, reaction } from "mobx";
import { cssNames } from "../../utils";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { Button } from "../button";
import type { ForwardedPort, PortForwardStore } from "../../port-forward";
import { predictProtocol } from "../../port-forward";
@ -24,6 +24,7 @@ import notifyErrorPortForwardingInjectable from "../../port-forward/notify-error
import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable";
import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
export interface ServicePortComponentProps {
service: Service;
@ -37,6 +38,7 @@ interface Dependencies {
aboutPortForwarding: () => void;
notifyErrorPortForwarding: (message: string) => void;
openPortForward: OpenPortForward;
showErrorNotification: ShowNotification;
}
@observer
@ -138,7 +140,7 @@ class NonInjectedServicePortComponent extends React.Component<ServicePortCompone
@action
async stopPortForward() {
const { service, port } = this.props;
const { service, port, showErrorNotification } = this.props;
const portForward: ForwardedPort = {
kind: "service",
name: service.getName(),
@ -152,7 +154,7 @@ class NonInjectedServicePortComponent extends React.Component<ServicePortCompone
try {
await this.portForwardStore.remove(portForward);
} catch (error) {
Notifications.error(`Error occurred stopping the port-forward from port ${portForward.forwardPort}.`);
showErrorNotification(`Error occurred stopping the port-forward from port ${portForward.forwardPort}.`);
} finally {
this.checkExistingPortForwarding();
this.forwardPort = 0;
@ -207,6 +209,7 @@ export const ServicePortComponent = withInjectables<Dependencies, ServicePortCom
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
logger: di.inject(loggerInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -16,7 +16,6 @@ import { Dialog } from "../../../dialog";
import { EditableList } from "../../../editable-list";
import { Icon } from "../../../icon";
import { SubTitle } from "../../../layout/sub-title";
import { Notifications } from "../../../notifications";
import { onMultiSelectFor, Select } from "../../../select";
import { Wizard, WizardStep } from "../../../wizard";
import { ObservableHashSet, nFircate } from "../../../../utils";
@ -39,6 +38,8 @@ import type { ShowDetails } from "../../../kube-detail-params/show-details.injec
import type { ClusterRoleBindingStore } from "../store";
import clusterRoleBindingStoreInjectable from "../store.injectable";
import showDetailsInjectable from "../../../kube-detail-params/show-details.injectable";
import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable";
export interface ClusterRoleBindingDialogProps extends Partial<DialogProps> {
}
@ -52,6 +53,7 @@ interface Dependencies {
closeClusterRoleBindingDialog: CloseClusterRoleBindingDialog;
openClusterRoleBindingDialog: OpenClusterRoleBindingDialog;
showDetails: ShowDetails;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -167,7 +169,7 @@ class NonInjectedClusterRoleBindingDialog extends React.Component<ClusterRoleBin
showDetails(selfLink);
closeClusterRoleBindingDialog();
} catch (err) {
Notifications.checkedError(err, `Unknown error occured while ${this.isEditing ? "editing the" : "creating a"} ClusterRoleBinding`);
this.props.showCheckedErrorNotification(err, `Unknown error occured while ${this.isEditing ? "editing the" : "creating a"} ClusterRoleBinding`);
}
};
@ -307,5 +309,6 @@ export const ClusterRoleBindingDialog = withInjectables<Dependencies, ClusterRol
openClusterRoleBindingDialog: di.inject(openClusterRoleBindingDialogInjectable),
closeClusterRoleBindingDialog: di.inject(closeClusterRoleBindingDialogInjectable),
showDetails: di.inject(showDetailsInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -11,7 +11,6 @@ import type { DialogProps } from "../../../dialog";
import { Dialog } from "../../../dialog";
import { Input } from "../../../input";
import { SubTitle } from "../../../layout/sub-title";
import { Notifications } from "../../../notifications";
import { Wizard, WizardStep } from "../../../wizard";
import type { AddClusterRoleDialogState } from "./state.injectable";
import type { ClusterRoleStore } from "../store";
@ -21,6 +20,8 @@ import closeAddClusterRoleDialogInjectable from "./close.injectable";
import clusterRoleStoreInjectable from "../store.injectable";
import showDetailsInjectable from "../../../kube-detail-params/show-details.injectable";
import addClusterRoleDialogStateInjectable from "./state.injectable";
import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable";
export interface AddClusterRoleDialogProps extends Partial<DialogProps> {
}
@ -30,6 +31,7 @@ interface Dependencies {
clusterRoleStore: ClusterRoleStore;
showDetails: ShowDetails;
closeAddClusterRoleDialog: () => void;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -40,6 +42,7 @@ class NonInjectedAddClusterRoleDialog extends React.Component<AddClusterRoleDial
clusterRoleStore,
showDetails,
state,
showCheckedErrorNotification,
} = this.props;
try {
@ -48,7 +51,7 @@ class NonInjectedAddClusterRoleDialog extends React.Component<AddClusterRoleDial
showDetails(role.selfLink);
closeAddClusterRoleDialog();
} catch (error) {
Notifications.checkedError(error, "Unknown error occured while creating the role");
showCheckedErrorNotification(error, "Unknown error occured while creating the role");
}
};
@ -94,5 +97,6 @@ export const AddClusterRoleDialog = withInjectables<Dependencies, AddClusterRole
clusterRoleStore: di.inject(clusterRoleStoreInjectable),
showDetails: di.inject(showDetailsInjectable),
state: di.inject(addClusterRoleDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -16,7 +16,6 @@ import { Dialog } from "../../../dialog";
import { EditableList } from "../../../editable-list";
import { Icon } from "../../../icon";
import { SubTitle } from "../../../layout/sub-title";
import { Notifications } from "../../../notifications";
import type { SelectOption } from "../../../select";
import { onMultiSelectFor, Select } from "../../../select";
import { Wizard, WizardStep } from "../../../wizard";
@ -38,6 +37,8 @@ import clusterRoleStoreInjectable from "../../+cluster-roles/store.injectable";
import roleStoreInjectable from "../../+roles/store.injectable";
import serviceAccountStoreInjectable from "../../+service-accounts/store.injectable";
import roleApiInjectable from "../../../../../common/k8s-api/endpoints/role.api.injectable";
import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable";
export interface RoleBindingDialogProps extends Partial<DialogProps> {
}
@ -51,6 +52,7 @@ interface Dependencies {
clusterRoleStore: ClusterRoleStore;
serviceAccountStore: ServiceAccountStore;
roleApi: RoleApi;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -169,6 +171,7 @@ class NonInjectedRoleBindingDialog extends React.Component<RoleBindingDialogProp
const {
roleBindingStore,
showDetails,
showCheckedErrorNotification,
} = this.props;
const { selectedRoleRef, bindingNamespace, selectedBindings, roleBinding, bindingName } = this;
@ -193,7 +196,7 @@ class NonInjectedRoleBindingDialog extends React.Component<RoleBindingDialogProp
showDetails(newRoleBinding.selfLink);
this.props.closeRoleBindingDialog();
} catch (err) {
Notifications.checkedError(err, `Unknown error occured while ${this.isEditing ? "editing" : "creating"} role bindings.`);
showCheckedErrorNotification(err, `Unknown error occured while ${this.isEditing ? "editing" : "creating"} role bindings.`);
}
};
@ -318,5 +321,6 @@ export const RoleBindingDialog = withInjectables<Dependencies, RoleBindingDialog
roleStore: di.inject(roleStoreInjectable),
serviceAccountStore: di.inject(serviceAccountStoreInjectable),
roleApi: di.inject(roleApiInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -13,7 +13,6 @@ import type { DialogProps } from "../../../dialog";
import { Dialog } from "../../../dialog";
import { Input } from "../../../input";
import { SubTitle } from "../../../layout/sub-title";
import { Notifications } from "../../../notifications";
import { Wizard, WizardStep } from "../../../wizard";
import type { AddRoleDialogState } from "./state.injectable";
import type { RoleStore } from "../store";
@ -23,6 +22,8 @@ import closeAddRoleDialogInjectable from "./close.injectable";
import roleStoreInjectable from "../store.injectable";
import showDetailsInjectable from "../../../kube-detail-params/show-details.injectable";
import addRoleDialogStateInjectable from "./state.injectable";
import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable";
export interface AddRoleDialogProps extends Partial<DialogProps> {
}
@ -32,6 +33,7 @@ interface Dependencies {
showDetails: ShowDetails;
state: AddRoleDialogState;
roleStore: RoleStore;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -42,6 +44,7 @@ class NonInjectedAddRoleDialog extends React.Component<AddRoleDialogProps & Depe
roleStore,
state,
showDetails,
showCheckedErrorNotification,
} = this.props;
try {
@ -53,7 +56,7 @@ class NonInjectedAddRoleDialog extends React.Component<AddRoleDialogProps & Depe
showDetails(role.selfLink);
closeAddRoleDialog();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while creating role");
showCheckedErrorNotification(err, "Unknown error occured while creating role");
}
};
@ -104,5 +107,6 @@ export const AddRoleDialog = withInjectables<Dependencies, AddRoleDialogProps>(N
roleStore: di.inject(roleStoreInjectable),
showDetails: di.inject(showDetailsInjectable),
state: di.inject(addRoleDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -14,7 +14,6 @@ import { Dialog } from "../../../dialog";
import { Input } from "../../../input";
import { systemName } from "../../../input/input_validators";
import { SubTitle } from "../../../layout/sub-title";
import { Notifications } from "../../../notifications";
import { Wizard, WizardStep } from "../../../wizard";
import type { CreateServiceAccountDialogState } from "./state.injectable";
import type { ServiceAccountStore } from "../store";
@ -24,6 +23,8 @@ import closeCreateServiceAccountDialogInjectable from "./close.injectable";
import serviceAccountStoreInjectable from "../store.injectable";
import showDetailsInjectable from "../../../kube-detail-params/show-details.injectable";
import createServiceAccountDialogStateInjectable from "./state.injectable";
import type { ShowCheckedErrorNotification } from "../../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../../notifications/show-checked-error.injectable";
export interface CreateServiceAccountDialogProps extends Partial<DialogProps> {
}
@ -33,12 +34,19 @@ interface Dependencies {
serviceAccountStore: ServiceAccountStore;
closeCreateServiceAccountDialog: () => void;
showDetails: ShowDetails;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
class NonInjectedCreateServiceAccountDialog extends React.Component<CreateServiceAccountDialogProps & Dependencies> {
createAccount = async () => {
const { closeCreateServiceAccountDialog, serviceAccountStore, state, showDetails } = this.props;
const {
closeCreateServiceAccountDialog,
serviceAccountStore,
state,
showDetails,
showCheckedErrorNotification,
} = this.props;
try {
const serviceAccount = await serviceAccountStore.create({
@ -49,7 +57,7 @@ class NonInjectedCreateServiceAccountDialog extends React.Component<CreateServic
showDetails(serviceAccount.selfLink);
closeCreateServiceAccountDialog();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while creating service account");
showCheckedErrorNotification(err, "Unknown error occured while creating service account");
}
};
@ -99,5 +107,6 @@ export const CreateServiceAccountDialog = withInjectables<Dependencies, CreateSe
serviceAccountStore: di.inject(serviceAccountStoreInjectable),
showDetails: di.inject(showDetailsInjectable),
state: di.inject(createServiceAccountDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -7,13 +7,14 @@ import type { KubeObjectMenuProps } from "../kube-object-menu";
import type { CronJob, CronJobApi } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
import type { OpenCronJobTriggerDialog } from "./trigger-dialog/open.injectable";
import openCronJobTriggerDialogInjectable from "./trigger-dialog/open.injectable";
import cronJobApiInjectable from "../../../common/k8s-api/endpoints/cron-job.api.injectable";
import type { ShowCheckedErrorNotification } from "../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../notifications/show-checked-error.injectable";
export interface CronJobMenuProps extends KubeObjectMenuProps<CronJob> {}
@ -21,6 +22,7 @@ interface Dependencies {
openConfirmDialog: OpenConfirmDialog;
openCronJobTriggerDialog: OpenCronJobTriggerDialog;
cronJobApi: CronJobApi;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
const NonInjectedCronJobMenu = ({
@ -29,6 +31,7 @@ const NonInjectedCronJobMenu = ({
openConfirmDialog,
openCronJobTriggerDialog,
cronJobApi,
showCheckedErrorNotification,
}: Dependencies & CronJobMenuProps) => (
<>
<MenuItem onClick={() => openCronJobTriggerDialog(object)}>
@ -48,7 +51,7 @@ const NonInjectedCronJobMenu = ({
try {
await cronJobApi.resume({ namespace: object.getNs(), name: object.getName() });
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while resuming CronJob");
showCheckedErrorNotification(err, "Unknown error occured while resuming CronJob");
}
},
labelOk: `Resume`,
@ -76,7 +79,7 @@ const NonInjectedCronJobMenu = ({
try {
await cronJobApi.suspend({ namespace: object.getNs(), name: object.getName() });
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while suspending CronJob");
showCheckedErrorNotification(err, "Unknown error occured while suspending CronJob");
}
},
labelOk: `Suspend`,
@ -106,5 +109,6 @@ export const CronJobMenu = withInjectables<Dependencies, CronJobMenuProps>(NonIn
openConfirmDialog: di.inject(openConfirmDialogInjectable),
openCronJobTriggerDialog: di.inject(openCronJobTriggerDialogInjectable),
cronJobApi: di.inject(cronJobApiInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -13,7 +13,7 @@ import type { DialogProps } from "../../dialog";
import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../../wizard";
import type { CronJob, JobApi } from "../../../../common/k8s-api/endpoints";
import { Notifications } from "../../notifications";
import type { ShowNotification } from "../../notifications";
import { cssNames } from "../../../utils";
import { Input } from "../../input";
import { systemName, maxLength } from "../../input/input_validators";
@ -21,6 +21,9 @@ import { withInjectables } from "@ogre-tools/injectable-react";
import closeCronJobTriggerDialogInjectable from "./close.injectable";
import jobApiInjectable from "../../../../common/k8s-api/endpoints/job.api.injectable";
import cronJobTriggerDialogStateInjectable from "./state.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
export interface CronJobTriggerDialogProps extends Partial<DialogProps> {
}
@ -29,6 +32,8 @@ interface Dependencies {
state: IObservableValue<CronJob | undefined>;
jobApi: JobApi;
closeCronJobTriggerDialog: () => void;
showCheckedErrorNotification: ShowCheckedErrorNotification;
showErrorNotification: ShowNotification;
}
@observer
@ -49,7 +54,9 @@ class NonInjectedCronJobTriggerDialog extends Component<CronJobTriggerDialogProp
async trigger(cronJob: CronJob): Promise<void> {
if (!cronJob.spec.jobTemplate) {
return void Notifications.error(`CronJob ${cronJob.getName()} has no jobTemplate`);
this.props.showErrorNotification(`CronJob ${cronJob.getName()} has no jobTemplate`);
return;
}
try {
@ -73,7 +80,7 @@ class NonInjectedCronJobTriggerDialog extends Component<CronJobTriggerDialogProp
this.props.closeCronJobTriggerDialog();
} catch (err) {
Notifications.checkedError(err, "Unknown error occurred while creating job");
this.props.showCheckedErrorNotification(err, "Unknown error occurred while creating job");
}
}
@ -138,5 +145,7 @@ export const CronJobTriggerDialog = withInjectables<Dependencies, CronJobTrigger
closeCronJobTriggerDialog: di.inject(closeCronJobTriggerDialogInjectable),
jobApi: di.inject(jobApiInjectable),
state: di.inject(cronJobTriggerDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -7,17 +7,19 @@ import type { KubeObjectMenuProps } from "../kube-object-menu";
import type { DaemonSet, DaemonSetApi } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import { withInjectables } from "@ogre-tools/injectable-react";
import daemonSetApiInjectable from "../../../common/k8s-api/endpoints/daemon-set.api.injectable";
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
import type { ShowCheckedErrorNotification } from "../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../notifications/show-checked-error.injectable";
export interface DaemonSetMenuProps extends KubeObjectMenuProps<DaemonSet> {}
interface Dependencies {
daemonsetApi: DaemonSetApi;
openConfirmDialog: OpenConfirmDialog;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
const NonInjectedDaemonSetMenu = ({
@ -25,6 +27,7 @@ const NonInjectedDaemonSetMenu = ({
object,
toolbar,
openConfirmDialog,
showCheckedErrorNotification,
}: Dependencies & DaemonSetMenuProps) => (
<>
<MenuItem
@ -37,7 +40,7 @@ const NonInjectedDaemonSetMenu = ({
name: object.getName(),
});
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while restarting daemonset");
showCheckedErrorNotification(err, "Unknown error occured while restarting daemonset");
}
},
labelOk: "Restart",
@ -65,5 +68,6 @@ export const DaemonSetMenu = withInjectables<Dependencies, DaemonSetMenuProps>(N
...props,
daemonsetApi: di.inject(daemonSetApiInjectable),
openConfirmDialog: di.inject(openConfirmDialogInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -7,13 +7,14 @@ import type { KubeObjectMenuProps } from "../kube-object-menu";
import type { Deployment, DeploymentApi } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import type { OpenDeploymentScaleDialog } from "./scale/open.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import deploymentApiInjectable from "../../../common/k8s-api/endpoints/deployment.api.injectable";
import openDeploymentScaleDialogInjectable from "./scale/open.injectable";
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
import type { ShowCheckedErrorNotification } from "../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../notifications/show-checked-error.injectable";
export interface DeploymentMenuProps extends KubeObjectMenuProps<Deployment> {}
@ -21,6 +22,7 @@ interface Dependencies {
openDeploymentScaleDialog: OpenDeploymentScaleDialog;
deploymentApi: DeploymentApi;
openConfirmDialog: OpenConfirmDialog;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
const NonInjectedDeploymentMenu = ({
@ -29,6 +31,7 @@ const NonInjectedDeploymentMenu = ({
openDeploymentScaleDialog,
toolbar,
openConfirmDialog,
showCheckedErrorNotification,
}: Dependencies & DeploymentMenuProps) => (
<>
<MenuItem onClick={() => openDeploymentScaleDialog(object)}>
@ -49,7 +52,7 @@ const NonInjectedDeploymentMenu = ({
name: object.getName(),
});
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while restarting deployment");
showCheckedErrorNotification(err, "Unknown error occured while restarting deployment");
}
},
labelOk: "Restart",
@ -78,5 +81,6 @@ export const DeploymentMenu = withInjectables<Dependencies, DeploymentMenuProps>
deploymentApi: di.inject(deploymentApiInjectable),
openDeploymentScaleDialog: di.inject(openDeploymentScaleDialogInjectable),
openConfirmDialog: di.inject(openConfirmDialogInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -15,11 +15,12 @@ import { Wizard, WizardStep } from "../../wizard";
import type { Deployment, DeploymentApi } from "../../../../common/k8s-api/endpoints";
import { Icon } from "../../icon";
import { Slider } from "../../slider";
import { Notifications } from "../../notifications";
import { cssNames } from "../../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import deploymentApiInjectable from "../../../../common/k8s-api/endpoints/deployment.api.injectable";
import deploymentScaleDialogStateInjectable from "./dialog-state.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface DeploymentScaleDialogProps extends Partial<DialogProps> {
}
@ -27,6 +28,7 @@ export interface DeploymentScaleDialogProps extends Partial<DialogProps> {
interface Dependencies {
deploymentApi: DeploymentApi;
state: IObservableValue<Deployment | undefined>;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -82,7 +84,7 @@ class NonInjectedDeploymentScaleDialog extends Component<DeploymentScaleDialogPr
}
close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while scaling Deployment");
this.props.showCheckedErrorNotification(err, "Unknown error occured while scaling Deployment");
}
};
@ -182,5 +184,6 @@ export const DeploymentScaleDialog = withInjectables<Dependencies, DeploymentSca
...props,
deploymentApi: di.inject(deploymentApiInjectable),
state: di.inject(deploymentScaleDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -10,7 +10,7 @@ import { disposeOnUnmount, observer } from "mobx-react";
import type { ContainerPort, Pod } from "../../../common/k8s-api/endpoints";
import { action, makeObservable, observable, reaction } from "mobx";
import { cssNames } from "../../utils";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { Button } from "../button";
import type { ForwardedPort, PortForwardStore } from "../../port-forward";
import { predictProtocol } from "../../port-forward";
@ -24,6 +24,7 @@ import notifyErrorPortForwardingInjectable from "../../port-forward/notify-error
import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable";
import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
export interface PodContainerPortProps {
pod: Pod;
@ -37,6 +38,7 @@ interface Dependencies {
aboutPortForwarding: () => void;
notifyErrorPortForwarding: (message: string) => void;
openPortForward: OpenPortForward;
showErrorNotification: ShowNotification;
}
@observer
@ -134,7 +136,7 @@ class NonInjectedPodContainerPort extends React.Component<PodContainerPortProps
@action
async stopPortForward() {
const { pod, port } = this.props;
const { pod, port, showErrorNotification } = this.props;
const portForward: ForwardedPort = {
kind: "pod",
name: pod.getName(),
@ -148,7 +150,7 @@ class NonInjectedPodContainerPort extends React.Component<PodContainerPortProps
try {
await this.portForwardStore.remove(portForward);
} catch (error) {
Notifications.error(`Error occurred stopping the port-forward from port ${portForward.forwardPort}.`);
showErrorNotification(`Error occurred stopping the port-forward from port ${portForward.forwardPort}.`);
} finally {
this.checkExistingPortForwarding();
this.forwardPort = 0;
@ -205,5 +207,6 @@ export const PodContainerPort = withInjectables<Dependencies, PodContainerPortPr
notifyErrorPortForwarding: di.inject(notifyErrorPortForwardingInjectable),
openPortForward: di.inject(openPortForwardInjectable),
logger: di.inject(loggerInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -14,12 +14,13 @@ import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../../wizard";
import { Icon } from "../../icon";
import { Slider } from "../../slider";
import { Notifications } from "../../notifications";
import { cssNames } from "../../../utils";
import type { ReplicaSet, ReplicaSetApi } from "../../../../common/k8s-api/endpoints";
import { withInjectables } from "@ogre-tools/injectable-react";
import replicaSetApiInjectable from "../../../../common/k8s-api/endpoints/replica-set.api.injectable";
import replicaSetScaleDialogStateInjectable from "./state.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface ReplicaSetScaleDialogProps extends Partial<DialogProps> {
}
@ -27,6 +28,7 @@ export interface ReplicaSetScaleDialogProps extends Partial<DialogProps> {
interface Dependencies {
replicaSetApi: ReplicaSetApi;
state: IObservableValue<ReplicaSet | undefined>;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -82,7 +84,7 @@ class NonInjectedReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogPr
}
close();
} catch (err) {
Notifications.checkedError(err, "Unknown error occured while scaling ReplicaSet");
this.props.showCheckedErrorNotification(err, "Unknown error occured while scaling ReplicaSet");
}
};
@ -178,5 +180,6 @@ export const ReplicaSetScaleDialog = withInjectables<Dependencies, ReplicaSetSca
...props,
replicaSetApi: di.inject(replicaSetApiInjectable),
state: di.inject(replicaSetScaleDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -15,11 +15,12 @@ import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../../wizard";
import { Icon } from "../../icon";
import { Slider } from "../../slider";
import { Notifications } from "../../notifications";
import { cssNames } from "../../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import statefulSetApiInjectable from "../../../../common/k8s-api/endpoints/stateful-set.api.injectable";
import statefulSetDialogStateInjectable from "./dialog-state.injectable";
import type { ShowCheckedErrorNotification } from "../../notifications/show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "../../notifications/show-checked-error.injectable";
export interface StatefulSetScaleDialogProps extends Partial<DialogProps> {
}
@ -27,6 +28,7 @@ export interface StatefulSetScaleDialogProps extends Partial<DialogProps> {
interface Dependencies {
statefulSetApi: StatefulSetApi;
state: IObservableValue<StatefulSet | undefined>;
showCheckedErrorNotification: ShowCheckedErrorNotification;
}
@observer
@ -82,7 +84,7 @@ class NonInjectedStatefulSetScaleDialog extends Component<StatefulSetScaleDialog
}
close();
} catch (error) {
Notifications.checkedError(error, "Unknown error occured while scaling StatefulSet");
this.props.showCheckedErrorNotification(error, "Unknown error occured while scaling StatefulSet");
}
};
@ -178,5 +180,6 @@ export const StatefulSetScaleDialog = withInjectables<Dependencies, StatefulSetS
...props,
statefulSetApi: di.inject(statefulSetApiInjectable),
state: di.inject(statefulSetDialogStateInjectable),
showCheckedErrorNotification: di.inject(showCheckedErrorNotificationInjectable),
}),
});

View File

@ -16,9 +16,10 @@ import { Button } from "../button";
import type { DialogProps } from "../dialog";
import { Dialog } from "../dialog";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { withInjectables } from "@ogre-tools/injectable-react";
import confirmDialogStateInjectable from "./state.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
export interface ConfirmDialogProps extends Partial<DialogProps> {
}
@ -39,6 +40,7 @@ export interface ConfirmDialogBooleanParams {
interface Dependencies {
state: IObservableValue<ConfirmDialogParams | undefined>;
showErrorNotification: ShowNotification;
}
const defaultParams = {
@ -68,7 +70,7 @@ class NonInjectedConfirmDialog extends React.Component<ConfirmDialogProps & Depe
this.isSaving = true;
await (async () => this.params.ok())();
} catch (error) {
Notifications.error(
this.props.showErrorNotification(
<>
<p>Confirmation action failed:</p>
<p>
@ -96,7 +98,7 @@ class NonInjectedConfirmDialog extends React.Component<ConfirmDialogProps & Depe
try {
await Promise.resolve(this.params.cancel());
} catch (error) {
Notifications.error(
this.props.showErrorNotification(
<>
<p>Cancelling action failed:</p>
<p>
@ -167,5 +169,6 @@ export const ConfirmDialog = withInjectables<Dependencies, ConfirmDialogProps>(N
getProps: (di, props) => ({
...props,
state: di.inject(confirmDialogStateInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
}),
});

View File

@ -9,18 +9,31 @@ import React from "react";
import type { DialogProps } from "../dialog";
import { Dialog } from "../dialog";
import { Wizard, WizardStep } from "../wizard";
import { Notifications } from "../notifications";
import type { ShowNotification } from "../notifications";
import { Button } from "../button";
import { Icon } from "../icon";
import { clipboard } from "electron";
import { kebabCase } from "lodash/fp";
import { withInjectables } from "@ogre-tools/injectable-react";
import showSuccessNotificationInjectable from "../notifications/show-success-notification.injectable";
export interface LogsDialogProps extends DialogProps {
title: string;
logs: string;
}
export function LogsDialog({ title, logs, ...dialogProps }: LogsDialogProps) {
interface Dependencies {
showSuccessNotification: ShowNotification;
}
const NonInjectedLogsDialog = (props: LogsDialogProps & Dependencies) => {
const {
title,
logs,
showSuccessNotification,
...dialogProps
} = props;
return (
<Dialog
{...dialogProps}
@ -39,7 +52,7 @@ export function LogsDialog({ title, logs, ...dialogProps }: LogsDialogProps) {
plain
onClick={() => {
clipboard.writeText(logs);
Notifications.ok(`Logs copied to clipboard.`);
showSuccessNotification(`Logs copied to clipboard.`);
}}
>
<Icon material="assignment"/>
@ -58,4 +71,11 @@ export function LogsDialog({ title, logs, ...dialogProps }: LogsDialogProps) {
</Wizard>
</Dialog>
);
}
};
export const LogsDialog = withInjectables<Dependencies, LogsDialogProps>(NonInjectedLogsDialog, {
getProps: (di, props) => ({
...props,
showSuccessNotification: di.inject(showSuccessNotificationInjectable),
}),
});

View File

@ -4,22 +4,16 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { when } from "mobx";
import loggerInjectable from "../../../../common/logger.injectable";
import { TerminalChannels } from "../../../../common/terminal/channels";
import { waitUntilDefined } from "../../../../common/utils/wait";
import type { TerminalApi } from "../../../api/terminal-api";
import { noop } from "../../../utils";
import { Notifications } from "../../notifications";
import showSuccessNotificationInjectable from "../../notifications/show-success-notification.injectable";
import selectDockTabInjectable from "../dock/select-dock-tab.injectable";
import type { DockTab, TabId } from "../dock/store";
import type { TabId } from "../dock/store";
import createTerminalTabInjectable from "./create-terminal-tab.injectable";
import getTerminalApiInjectable from "./get-terminal-api.injectable";
interface Dependencies {
selectTab: (tabId: TabId) => void;
createTerminalTab: () => DockTab;
getTerminalApi: (tabId: TabId) => TerminalApi | undefined;
}
export interface SendCommandOptions {
/**
* Emit an enter after the command
@ -37,59 +31,63 @@ export interface SendCommandOptions {
tabId?: TabId;
}
const sendCommand = ({ selectTab, createTerminalTab, getTerminalApi }: Dependencies) => async (command: string, options: SendCommandOptions = {}): Promise<void> => {
let tabId: string | undefined = options.tabId;
if (tabId) {
selectTab(tabId);
} else {
tabId = createTerminalTab().id;
}
const terminalApi = await waitUntilDefined(() => (
tabId
? getTerminalApi(tabId)
: undefined
));
const shellIsReady = when(() => terminalApi.isReady);
const notifyVeryLong = setTimeout(() => {
shellIsReady.cancel();
Notifications.info(
"If terminal shell is not ready please check your shell init files, if applicable.",
{
timeout: 4_000,
},
);
}, 10_000);
await shellIsReady.catch(noop);
clearTimeout(notifyVeryLong);
if (terminalApi) {
if (options.enter) {
command += "\r";
}
terminalApi.sendMessage({
type: TerminalChannels.STDIN,
data: command,
});
} else {
console.warn(
"The selected tab is does not have a connection. Cannot send command.",
{ tabId, command },
);
}
};
export type SendCommand = (command: string, options?: SendCommandOptions) => Promise<void>;
const sendCommandInjectable = getInjectable({
id: "send-command",
instantiate: (di) => sendCommand({
createTerminalTab: di.inject(createTerminalTabInjectable),
selectTab: di.inject(selectDockTabInjectable),
getTerminalApi: di.inject(getTerminalApiInjectable),
}),
instantiate: (di): SendCommand => {
const createTerminalTab = di.inject(createTerminalTabInjectable);
const selectTab = di.inject(selectDockTabInjectable);
const getTerminalApi = di.inject(getTerminalApiInjectable);
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
const logger = di.inject(loggerInjectable);
return async (command: string, options: SendCommandOptions = {}): Promise<void> => {
let tabId: string | undefined = options.tabId;
if (tabId) {
selectTab(tabId);
} else {
tabId = createTerminalTab().id;
}
const terminalApi = await waitUntilDefined(() => (
tabId
? getTerminalApi(tabId)
: undefined
));
const shellIsReady = when(() => terminalApi.isReady);
const notifyVeryLong = setTimeout(() => {
shellIsReady.cancel();
showSuccessNotification(
"If terminal shell is not ready please check your shell init files, if applicable.",
{
timeout: 4_000,
},
);
}, 10_000);
await shellIsReady.catch(noop);
clearTimeout(notifyVeryLong);
if (terminalApi) {
if (options.enter) {
command += "\r";
}
terminalApi.sendMessage({
type: TerminalChannels.STDIN,
data: command,
});
} else {
logger.warn(
"The selected tab is does not have a connection. Cannot send command.",
{ tabId, command },
);
}
};
},
});
export default sendCommandInjectable;

View File

@ -16,13 +16,6 @@ import { Animate } from "../animate";
import { Icon } from "../icon";
import { withInjectables } from "@ogre-tools/injectable-react";
import notificationsStoreInjectable from "./notifications-store.injectable";
import { asLegacyGlobalFunctionForExtensionApi } from "../../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
import showSuccessNotificationInjectable from "./show-success-notification.injectable";
import type { ShowCheckedErrorNotification } from "./show-checked-error.injectable";
import showCheckedErrorNotificationInjectable from "./show-checked-error.injectable";
import showErrorNotificationInjectable from "./show-error-notification.injectable";
import showInfoNotificationInjectable from "./show-info-notification.injectable";
import showShortInfoNotificationInjectable from "./show-short-info.injectable";
export type ShowNotification = (message: NotificationMessage, opts?: CreateNotificationOptions) => Disposer;
@ -102,25 +95,8 @@ class NonInjectedNotifications extends React.Component<Dependencies> {
}
}
export const Notifications = withInjectables<Dependencies>(
NonInjectedNotifications,
{
getProps: (di) => ({
store: di.inject(notificationsStoreInjectable),
}),
},
) as React.FC & {
ok: ShowNotification;
checkedError: ShowCheckedErrorNotification;
error: ShowNotification;
shortInfo: ShowNotification;
info: ShowNotification;
};
Notifications.ok = asLegacyGlobalFunctionForExtensionApi(showSuccessNotificationInjectable);
Notifications.error = asLegacyGlobalFunctionForExtensionApi(showErrorNotificationInjectable);
Notifications.checkedError = asLegacyGlobalFunctionForExtensionApi(showCheckedErrorNotificationInjectable);
Notifications.info = asLegacyGlobalFunctionForExtensionApi(showInfoNotificationInjectable);
Notifications.shortInfo = asLegacyGlobalFunctionForExtensionApi(showShortInfoNotificationInjectable);
export const Notifications = withInjectables<Dependencies>(NonInjectedNotifications, {
getProps: (di) => ({
store: di.inject(notificationsStoreInjectable),
}),
});

View File

@ -2,13 +2,13 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { Notifications } from "../components/notifications";
import { getInjectable } from "@ogre-tools/injectable";
import userStoreInjectable from "../../common/user-store/user-store.injectable";
import React from "react";
import navigateToKubernetesPreferencesInjectable from "../../features/preferences/common/navigate-to-kubernetes-preferences.injectable";
import discoverAllKubeconfigSyncKindsInjectable from "../../features/preferences/renderer/preference-items/kubernetes/kubeconfig-sync/discover-all-sync-kinds.injectable";
import { action } from "mobx";
import showSuccessNotificationInjectable from "../components/notifications/show-success-notification.injectable";
const addSyncEntriesInjectable = getInjectable({
id: "add-sync-entries",
@ -17,6 +17,7 @@ const addSyncEntriesInjectable = getInjectable({
const userStore = di.inject(userStoreInjectable);
const navigateToKubernetesPreferences = di.inject(navigateToKubernetesPreferencesInjectable);
const discoverAllKubeconfigSyncKinds = di.inject(discoverAllKubeconfigSyncKindsInjectable);
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
return async (filePaths: string[]) => {
const kinds = await discoverAllKubeconfigSyncKinds(filePaths);
@ -27,7 +28,7 @@ const addSyncEntriesInjectable = getInjectable({
}
});
Notifications.ok((
showSuccessNotification((
<div>
<p>Selected items has been added to Kubeconfig Sync.</p>
<br/>

View File

@ -5,13 +5,15 @@
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 { 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";
import showSuccessNotificationInjectable from "../components/notifications/show-success-notification.injectable";
const intervalBetweenNotifications = 1000 * 60; // 60s
const listNamespacesForbiddenHandlerInjectable = getInjectable({
id: "list-namespaces-forbidden-handler",
@ -21,7 +23,7 @@ const listNamespacesForbiddenHandlerInjectable = getInjectable({
const notificationsStore = di.inject(notificationsStoreInjectable);
const getClusterById = di.inject(getClusterByIdInjectable);
const notificationLastDisplayedAt = new Map<string, number>();
const intervalBetweenNotifications = 1000 * 60; // 60s
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
return (
event: IpcRendererEvent,
@ -47,7 +49,7 @@ const listNamespacesForbiddenHandlerInjectable = getInjectable({
return;
}
Notifications.info(
showSuccessNotification(
(
<div className="flex column gaps">
<b>Add Accessible Namespaces</b>

View File

@ -3,15 +3,28 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { registerIpcListeners } from "./register-listeners";
import { defaultHotbarCells } from "../../common/hotbars/types";
import { clusterListNamespaceForbiddenChannel } from "../../common/ipc/cluster";
import { hotbarTooManyItemsChannel } from "../../common/ipc/hotbar";
import showErrorNotificationInjectable from "../components/notifications/show-error-notification.injectable";
import ipcRendererInjectable from "../utils/channel/ipc-renderer.injectable";
import listNamespacesForbiddenHandlerInjectable from "./list-namespaces-forbidden-handler.injectable";
const registerIpcListenersInjectable = getInjectable({
id: "register-ipc-listeners",
instantiate: (di) => registerIpcListeners({
listNamespacesForbiddenHandler: di.inject(listNamespacesForbiddenHandlerInjectable),
}),
instantiate: (di) => {
const listNamespacesForbiddenHandler = di.inject(listNamespacesForbiddenHandlerInjectable);
const ipcRenderer = di.inject(ipcRendererInjectable);
const showErrorNotification = di.inject(showErrorNotificationInjectable);
return () => {
ipcRenderer.on(clusterListNamespaceForbiddenChannel, listNamespacesForbiddenHandler);
ipcRenderer.on(hotbarTooManyItemsChannel, () => {
showErrorNotification(`Cannot have more than ${defaultHotbarCells} items pinned to a hotbar`);
});
};
},
});
export default registerIpcListenersInjectable;

View File

@ -1,27 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { IpcRendererEvent } from "electron";
import { ipcRenderer } from "electron";
import { Notifications } from "../components/notifications";
import { defaultHotbarCells } from "../../common/hotbars/types";
import { type ListNamespaceForbiddenArgs, clusterListNamespaceForbiddenChannel } from "../../common/ipc/cluster";
import { hotbarTooManyItemsChannel } from "../../common/ipc/hotbar";
function HotbarTooManyItemsHandler(): void {
Notifications.error(`Cannot have more than ${defaultHotbarCells} items pinned to a hotbar`);
}
interface Dependencies {
listNamespacesForbiddenHandler: (
event: IpcRendererEvent,
...[clusterId]: ListNamespaceForbiddenArgs
) => void;
}
export const registerIpcListeners = ({ listNamespacesForbiddenHandler }: Dependencies) => () => {
ipcRenderer.on(clusterListNamespaceForbiddenChannel, listNamespacesForbiddenHandler);
ipcRenderer.on(hotbarTooManyItemsChannel, HotbarTooManyItemsHandler);
};

View File

@ -1,30 +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 { aboutPortForwarding } from "./port-forward-notify";
import navigateToPortForwardsInjectable from "../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
import hostedClusterIdInjectable from "../cluster-frame-context/hosted-cluster-id.injectable";
import assert from "assert";
import notificationsStoreInjectable from "../components/notifications/notifications-store.injectable";
const aboutPortForwardingInjectable = getInjectable({
id: "about-port-forwarding",
instantiate: (di) => {
const hostedClusterId = di.inject(hostedClusterIdInjectable);
const notificationsStore = di.inject(notificationsStoreInjectable);
const navigateToPortForwards = di.inject(navigateToPortForwardsInjectable);
assert(hostedClusterId, "Only allowed to notify about port forward errors within a cluster frame");
return aboutPortForwarding({
navigateToPortForwards,
hostedClusterId,
notificationsStore,
});
},
});
export default aboutPortForwardingInjectable;

View File

@ -0,0 +1,48 @@
/**
* 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 navigateToPortForwardsInjectable from "../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
import { Button } from "../components/button";
import showSuccessNotificationInjectable from "../components/notifications/show-success-notification.injectable";
const aboutPortForwardingInjectable = getInjectable({
id: "about-port-forwarding",
instantiate: (di) => {
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
const navigateToPortForwards = di.inject(navigateToPortForwardsInjectable);
return () => {
const removeNotification = showSuccessNotification(
(
<div className="flex column gaps">
<b>Port Forwarding</b>
<p>
You can manage your port forwards on the Port Forwarding Page.
</p>
<div className="flex gaps row align-left box grow">
<Button
active
outlined
label="Go to Port Forwarding"
onClick={() => {
navigateToPortForwards();
removeNotification();
}}
/>
</div>
</div>
),
{
id: "port-forward-notification",
timeout: 10_000,
},
);
};
},
});
export default aboutPortForwardingInjectable;

View File

@ -1,30 +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 { notifyErrorPortForwarding } from "./port-forward-notify";
import navigateToPortForwardsInjectable from "../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
import hostedClusterIdInjectable from "../cluster-frame-context/hosted-cluster-id.injectable";
import assert from "assert";
import notificationsStoreInjectable from "../components/notifications/notifications-store.injectable";
const notifyErrorPortForwardingInjectable = getInjectable({
id: "notify-error-port-forwarding",
instantiate: (di) => {
const hostedClusterId = di.inject(hostedClusterIdInjectable);
const notificationsStore = di.inject(notificationsStoreInjectable);
const navigateToPortForwards = di.inject(navigateToPortForwardsInjectable);
assert(hostedClusterId, "Only allowed to notify about port forward errors within a cluster frame");
return notifyErrorPortForwarding({
navigateToPortForwards,
hostedClusterId,
notificationsStore,
});
},
});
export default notifyErrorPortForwardingInjectable;

View File

@ -0,0 +1,47 @@
/**
* 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 navigateToPortForwardsInjectable from "../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
import showErrorNotificationInjectable from "../components/notifications/show-error-notification.injectable";
import React from "react";
import { Button } from "../components/button";
const notifyErrorPortForwardingInjectable = getInjectable({
id: "notify-error-port-forwarding",
instantiate: (di) => {
const showErrorNotification = di.inject(showErrorNotificationInjectable);
const navigateToPortForwards = di.inject(navigateToPortForwardsInjectable);
return (msg: string) => {
const removeNotification = showErrorNotification(
(
<div className="flex column gaps">
<b>Port Forwarding</b>
<p>
{msg}
</p>
<div className="flex gaps row align-left box grow">
<Button
active
outlined
label="Check Port Forwarding"
onClick={() => {
navigateToPortForwards();
removeNotification();
}}
/>
</div>
</div>
),
{
timeout: 10_000,
},
);
};
},
});
export default notifyErrorPortForwardingInjectable;

View File

@ -1,92 +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 { Button } from "../components/button";
import { Notifications } from "../components/notifications";
import type { NavigateToPortForwards } from "../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
import type { NotificationsStore } from "../components/notifications/notifications.store";
interface AboutPortForwardingDependencies {
navigateToPortForwards: NavigateToPortForwards;
hostedClusterId: string;
notificationsStore: NotificationsStore;
}
export const aboutPortForwarding = ({
navigateToPortForwards,
hostedClusterId,
notificationsStore,
}: AboutPortForwardingDependencies) => () => {
const notificationId = `port-forward-notification-${hostedClusterId}`;
Notifications.info(
(
<div className="flex column gaps">
<b>Port Forwarding</b>
<p>
You can manage your port forwards on the Port Forwarding Page.
</p>
<div className="flex gaps row align-left box grow">
<Button
active
outlined
label="Go to Port Forwarding"
onClick={() => {
navigateToPortForwards();
notificationsStore.remove(notificationId);
}}
/>
</div>
</div>
),
{
id: notificationId,
timeout: 10_000,
},
);
};
interface NotifyErrorPortForwardingDependencies {
navigateToPortForwards: NavigateToPortForwards;
hostedClusterId: string;
notificationsStore: NotificationsStore;
}
export const notifyErrorPortForwarding = ({
navigateToPortForwards,
hostedClusterId,
notificationsStore,
}: NotifyErrorPortForwardingDependencies) => (msg: string) => {
const notificationId = `port-forward-error-notification-${hostedClusterId}`;
Notifications.error(
(
<div className="flex column gaps">
<b>Port Forwarding</b>
<p>
{msg}
</p>
<div className="flex gaps row align-left box grow">
<Button
active
outlined
label="Check Port Forwarding"
onClick={() => {
navigateToPortForwards();
notificationsStore.remove(notificationId);
}}
/>
</div>
</div>
),
{
id: notificationId,
timeout: 10_000,
},
);
};

View File

@ -16,6 +16,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";
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
const bindProtocolAddRouteHandlersInjectable = getInjectable({
id: "bind-protocol-add-route-handlers",
@ -31,6 +32,7 @@ const bindProtocolAddRouteHandlersInjectable = getInjectable({
navigateToPreferences: di.inject(navigateToPreferencesInjectable),
entityRegistry: di.inject(catalogEntityRegistryInjectable),
getClusterById: di.inject(getClusterByIdInjectable),
showShortInfoNotification: di.inject(showShortInfoNotificationInjectable),
}),
});

View File

@ -11,7 +11,7 @@ import {
EXTENSION_PUBLISHER_MATCH,
LensProtocolRouter,
} from "../../../common/protocol-handler";
import { Notifications } from "../../components/notifications";
import type { ShowNotification } from "../../components/notifications";
import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
import type { NavigateToEntitySettings } from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
import type { NavigateToClusterView } from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
@ -19,7 +19,6 @@ 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 {
attemptInstallByInfo: AttemptInstallByInfo;
lensProtocolRouterRenderer: LensProtocolRouterRenderer;
@ -31,6 +30,7 @@ interface Dependencies {
navigateToPreferences: (tabId: string) => void;
entityRegistry: CatalogEntityRegistry;
getClusterById: GetClusterById;
showShortInfoNotification: ShowNotification;
}
export const bindProtocolAddRouteHandlers = ({
@ -44,6 +44,7 @@ export const bindProtocolAddRouteHandlers = ({
navigateToPreferences,
entityRegistry,
getClusterById,
showShortInfoNotification,
}: Dependencies) => () => {
lensProtocolRouterRenderer
.addInternalHandler("/preferences", ({ search: { highlight: tabId }}) => {
@ -53,7 +54,7 @@ export const bindProtocolAddRouteHandlers = ({
})
.addInternalHandler("/", ({ tail }) => {
if (tail) {
Notifications.shortInfo(
showShortInfoNotification(
<p>
{"Unknown Action for "}
<code>
@ -83,7 +84,7 @@ export const bindProtocolAddRouteHandlers = ({
if (entity) {
navigateToEntitySettings(entityId);
} else {
Notifications.shortInfo(
showShortInfoNotification(
<p>
{"Unknown catalog entity "}
<code>{entityId}</code>
@ -100,7 +101,7 @@ export const bindProtocolAddRouteHandlers = ({
if (cluster) {
navigateToClusterView(clusterId);
} else {
Notifications.shortInfo(
showShortInfoNotification(
<p>
{"Unknown catalog entity "}
<code>{clusterId}</code>
@ -116,7 +117,7 @@ export const bindProtocolAddRouteHandlers = ({
if (cluster) {
navigateToEntitySettings(clusterId);
} else {
Notifications.shortInfo(
showShortInfoNotification(
<p>
{"Unknown catalog entity "}
<code>{clusterId}</code>

View File

@ -7,16 +7,19 @@ import extensionLoaderInjectable from "../../../extensions/extension-loader/exte
import { LensProtocolRouterRenderer } from "./lens-protocol-router-renderer";
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import showErrorNotificationInjectable from "../../components/notifications/show-error-notification.injectable";
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
const lensProtocolRouterRendererInjectable = getInjectable({
id: "lens-protocol-router-renderer",
instantiate: (di) =>
new LensProtocolRouterRenderer({
extensionLoader: di.inject(extensionLoaderInjectable),
extensionsStore: di.inject(extensionsStoreInjectable),
logger: di.inject(loggerInjectable),
}),
instantiate: (di) => new LensProtocolRouterRenderer({
extensionLoader: di.inject(extensionLoaderInjectable),
extensionsStore: di.inject(extensionsStoreInjectable),
logger: di.inject(loggerInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
showShortInfoNotification: di.inject(showShortInfoNotificationInjectable),
}),
});
export default lensProtocolRouterRendererInjectable;

View File

@ -9,12 +9,15 @@ import * as proto from "../../../common/protocol-handler";
import Url from "url-parse";
import type { LensProtocolRouterDependencies } from "../../../common/protocol-handler";
import { foldAttemptResults, ProtocolHandlerInvalid, RouteAttempt } from "../../../common/protocol-handler";
import { Notifications } from "../../components/notifications";
import type { ShowNotification } from "../../components/notifications";
interface Dependencies extends LensProtocolRouterDependencies {}
interface Dependencies extends LensProtocolRouterDependencies {
showShortInfoNotification: ShowNotification;
showErrorNotification: ShowNotification;
}
export class LensProtocolRouterRenderer extends proto.LensProtocolRouter {
constructor(protected dependencies: Dependencies) {
constructor(protected readonly dependencies: Dependencies) {
super(dependencies);
}
@ -26,7 +29,7 @@ export class LensProtocolRouterRenderer extends proto.LensProtocolRouter {
const rendererAttempt = this._routeToInternal(new Url(rawUrl, true));
if (foldAttemptResults(mainAttemptResult, rendererAttempt) === RouteAttempt.MISSING) {
Notifications.shortInfo((
this.dependencies.showShortInfoNotification((
<p>
{"Unknown action "}
<code>{rawUrl}</code>
@ -40,7 +43,7 @@ export class LensProtocolRouterRenderer extends proto.LensProtocolRouter {
switch (foldAttemptResults(mainAttemptResult, rendererAttempt)) {
case RouteAttempt.MISSING:
Notifications.shortInfo((
this.dependencies.showShortInfoNotification((
<p>
{"Unknown action "}
<code>{rawUrl}</code>
@ -49,7 +52,7 @@ export class LensProtocolRouterRenderer extends proto.LensProtocolRouter {
));
break;
case RouteAttempt.MISSING_EXTENSION:
Notifications.shortInfo((
this.dependencies.showShortInfoNotification((
<p>
{"Missing extension for action "}
<code>{rawUrl}</code>
@ -60,7 +63,7 @@ export class LensProtocolRouterRenderer extends proto.LensProtocolRouter {
}
});
ipcRenderer.on(ProtocolHandlerInvalid, (event, error: string, rawUrl: string) => {
Notifications.error((
this.dependencies.showErrorNotification((
<>
<p>
{"Failed to route "}