diff --git a/src/common/k8s-api/endpoints/index.ts b/src/common/k8s-api/endpoints/index.ts
index 33ec108a31..9d3fa94815 100644
--- a/src/common/k8s-api/endpoints/index.ts
+++ b/src/common/k8s-api/endpoints/index.ts
@@ -43,5 +43,4 @@ export * from "./service.api";
export * from "./service-account.api";
export * from "./stateful-set.api";
export * from "./storage-class.api";
-export * from "./legacy-globals";
export * from "./types";
diff --git a/src/common/k8s-api/endpoints/legacy-globals.ts b/src/common/k8s-api/endpoints/legacy-globals.ts
deleted file mode 100644
index a0e905315b..0000000000
--- a/src/common/k8s-api/endpoints/legacy-globals.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Copyright (c) OpenLens Authors. All rights reserved.
- * Licensed under MIT License. See LICENSE in root directory for more information.
- */
-
-import { asLegacyGlobalForExtensionApi } from "../../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
-import roleApiInjectable from "./role.api.injectable";
-
-/**
- * @deprecated use `di.inject(roleApiInjectable)` instead
- */
-export const roleApi = asLegacyGlobalForExtensionApi(roleApiInjectable);
diff --git a/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx b/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx
index 08067ed817..67d3b38fe1 100644
--- a/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx
+++ b/src/renderer/components/+user-management/+role-bindings/__tests__/dialog.test.tsx
@@ -6,7 +6,7 @@
import userEvent from "@testing-library/user-event";
import React from "react";
import { ClusterRole } from "../../../../../common/k8s-api/endpoints";
-import { RoleBindingDialog } from "../dialog";
+import { RoleBindingDialog } from "../dialog/view";
import { getDiForUnitTesting } from "../../../../getDiForUnitTesting";
import type { DiRender } from "../../../test-utils/renderFor";
import { renderFor } from "../../../test-utils/renderFor";
@@ -16,9 +16,12 @@ import storesAndApisCanBeCreatedInjectable from "../../../../stores-apis-can-be-
import directoryForKubeConfigsInjectable from "../../../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import hostedClusterInjectable from "../../../../cluster-frame-context/hosted-cluster.injectable";
import createClusterInjectable from "../../../../cluster/create-cluster.injectable";
+import type { OpenRoleBindingDialog } from "../dialog/open.injectable";
+import openRoleBindingDialogInjectable from "../dialog/open.injectable";
describe("RoleBindingDialog tests", () => {
let render: DiRender;
+ let openRoleBindingDialog: OpenRoleBindingDialog;
beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });
@@ -27,6 +30,8 @@ describe("RoleBindingDialog tests", () => {
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
+ openRoleBindingDialog = di.inject(openRoleBindingDialogInjectable);
+
const createCluster = di.inject(createClusterInjectable);
di.override(hostedClusterInjectable, () => createCluster({
@@ -55,11 +60,6 @@ describe("RoleBindingDialog tests", () => {
]);
});
- afterEach(() => {
- RoleBindingDialog.close();
- jest.resetAllMocks();
- });
-
it("should render without any errors", () => {
const { container } = render();
@@ -67,7 +67,7 @@ describe("RoleBindingDialog tests", () => {
});
it("role select should be searchable", async () => {
- RoleBindingDialog.open();
+ openRoleBindingDialog();
const res = render();
userEvent.click(await res.findByText("Select role", { exact: false }));
diff --git a/src/renderer/components/+user-management/+role-bindings/details.tsx b/src/renderer/components/+user-management/+role-bindings/details.tsx
index eeadae080c..43d3a44f0c 100644
--- a/src/renderer/components/+user-management/+role-bindings/details.tsx
+++ b/src/renderer/components/+user-management/+role-bindings/details.tsx
@@ -14,19 +14,21 @@ import { AddRemoveButtons } from "../../add-remove-buttons";
import { DrawerTitle } from "../../drawer";
import type { KubeObjectDetailsProps } from "../../kube-object-details";
import { Table, TableCell, TableHead, TableRow } from "../../table";
-import { RoleBindingDialog } from "./dialog";
import { roleBindingStore } from "./legacy-store";
import { ObservableHashSet } from "../../../../common/utils/hash-set";
import { hashSubject } from "../hashers";
import type { OpenConfirmDialog } from "../../confirm-dialog/open.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import openConfirmDialogInjectable from "../../confirm-dialog/open.injectable";
+import type { OpenRoleBindingDialog } from "./dialog/open.injectable";
+import openRoleBindingDialogInjectable from "./dialog/open.injectable";
export interface RoleBindingDetailsProps extends KubeObjectDetailsProps {
}
interface Dependencies {
openConfirmDialog: OpenConfirmDialog;
+ openRoleBindingDialog: OpenRoleBindingDialog;
}
@observer
@@ -60,7 +62,7 @@ class NonInjectedRoleBindingDetails extends React.Component RoleBindingDialog.open(roleBinding)}
+ onAdd={() => openRoleBindingDialog(roleBinding)}
onRemove={selectedSubjects.size ? this.removeSelectedSubjects : undefined}
addTooltip={`Edit bindings of ${roleRef.name}`}
removeTooltip={`Remove selected bindings from ${roleRef.name}`}
@@ -130,5 +132,6 @@ export const RoleBindingDetails = withInjectables ({
...props,
openConfirmDialog: di.inject(openConfirmDialogInjectable),
+ openRoleBindingDialog: di.inject(openRoleBindingDialogInjectable),
}),
});
diff --git a/src/renderer/components/+user-management/+role-bindings/dialog/close.injectable.ts b/src/renderer/components/+user-management/+role-bindings/dialog/close.injectable.ts
new file mode 100644
index 0000000000..1f42df1818
--- /dev/null
+++ b/src/renderer/components/+user-management/+role-bindings/dialog/close.injectable.ts
@@ -0,0 +1,18 @@
+/**
+ * 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 { action } from "mobx";
+import roleBindingDialogStateInjectable from "./state.injectable";
+
+const closeRoleBindingDialogInjectable = getInjectable({
+ id: "close-role-binding-dialog",
+ instantiate: (di) => {
+ const state = di.inject(roleBindingDialogStateInjectable);
+
+ return action(() => state.set({ isOpen: false }));
+ },
+});
+
+export default closeRoleBindingDialogInjectable;
diff --git a/src/renderer/components/+user-management/+role-bindings/dialog/open.injectable.ts b/src/renderer/components/+user-management/+role-bindings/dialog/open.injectable.ts
new file mode 100644
index 0000000000..bda4f5363b
--- /dev/null
+++ b/src/renderer/components/+user-management/+role-bindings/dialog/open.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * 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 { action } from "mobx";
+import type { RoleBinding } from "../../../../../common/k8s-api/endpoints";
+import roleBindingDialogStateInjectable from "./state.injectable";
+
+export type OpenRoleBindingDialog = (roleBinding?: RoleBinding | undefined) => void;
+
+const openRoleBindingDialogInjectable = getInjectable({
+ id: "open-role-binding-dialog",
+ instantiate: (di): OpenRoleBindingDialog => {
+ const state = di.inject(roleBindingDialogStateInjectable);
+
+ return action((roleBinding) => state.set({
+ isOpen: true,
+ roleBinding,
+ }));
+ },
+});
+
+export default openRoleBindingDialogInjectable;
diff --git a/src/renderer/components/+user-management/+role-bindings/dialog/state.injectable.ts b/src/renderer/components/+user-management/+role-bindings/dialog/state.injectable.ts
new file mode 100644
index 0000000000..03b1093a3b
--- /dev/null
+++ b/src/renderer/components/+user-management/+role-bindings/dialog/state.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * 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 { observable } from "mobx";
+import type { RoleBinding } from "../../../../../common/k8s-api/endpoints";
+
+export type RoleBindingDialogState = {
+ isOpen: false;
+ roleBinding?: undefined;
+} | {
+ isOpen: true;
+ roleBinding: RoleBinding | undefined;
+};
+
+const roleBindingDialogStateInjectable = getInjectable({
+ id: "role-binding-dialog-state",
+ instantiate: () => observable.box({ isOpen: false }),
+});
+
+export default roleBindingDialogStateInjectable;
diff --git a/src/renderer/components/+user-management/+role-bindings/dialog.scss b/src/renderer/components/+user-management/+role-bindings/dialog/view.scss
similarity index 100%
rename from src/renderer/components/+user-management/+role-bindings/dialog.scss
rename to src/renderer/components/+user-management/+role-bindings/dialog/view.scss
diff --git a/src/renderer/components/+user-management/+role-bindings/dialog.tsx b/src/renderer/components/+user-management/+role-bindings/dialog/view.tsx
similarity index 63%
rename from src/renderer/components/+user-management/+role-bindings/dialog.tsx
rename to src/renderer/components/+user-management/+role-bindings/dialog/view.tsx
index 49ac40d7d1..ae2518eb8d 100644
--- a/src/renderer/components/+user-management/+role-bindings/dialog.tsx
+++ b/src/renderer/components/+user-management/+role-bindings/dialog/view.tsx
@@ -3,64 +3,65 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
-import "./dialog.scss";
+import "./view.scss";
+import type { IObservableValue } from "mobx";
import { computed, observable, makeObservable, action } from "mobx";
import { observer } from "mobx-react";
import React from "react";
-
-import { roleStore } from "../+roles/legacy-store";
-import { serviceAccountStore } from "../+service-accounts/legacy-store";
-import { NamespaceSelect } from "../../+namespaces/namespace-select";
-import type { ClusterRole, Role, RoleBinding, ServiceAccount } from "../../../../common/k8s-api/endpoints";
-import { roleApi } from "../../../../common/k8s-api/endpoints";
-import type { DialogProps } from "../../dialog";
-import { Dialog } from "../../dialog";
-import { EditableList } from "../../editable-list";
-import { Icon } from "../../icon";
-import { showDetails } from "../../kube-detail-params";
-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";
-import { roleBindingStore } from "./legacy-store";
-import { clusterRoleStore } from "../+cluster-roles/legacy-store";
-import { Input } from "../../input";
-import { ObservableHashSet, nFircate } from "../../../utils";
-import type { Subject } from "../../../../common/k8s-api/endpoints/types/subject";
+import { NamespaceSelect } from "../../../+namespaces/namespace-select";
+import type { ClusterRole, Role, RoleApi, ServiceAccount } from "../../../../../common/k8s-api/endpoints";
+import type { DialogProps } from "../../../dialog";
+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";
+import { Input } from "../../../input";
+import { ObservableHashSet, nFircate } from "../../../../utils";
+import type { Subject } from "../../../../../common/k8s-api/endpoints/types/subject";
+import type { RoleBindingDialogState } from "./state.injectable";
+import type { RoleBindingStore } from "../store";
+import { withInjectables } from "@ogre-tools/injectable-react";
+import roleBindingStoreInjectable from "../store.injectable";
+import roleBindingDialogStateInjectable from "./state.injectable";
+import closeRoleBindingDialogInjectable from "./close.injectable";
+import type { ShowDetails } from "../../../kube-detail-params/show-details.injectable";
+import type { RoleStore } from "../../+roles/store";
+import type { ClusterRoleStore } from "../../+cluster-roles/store";
+import type { ServiceAccountStore } from "../../+service-accounts/store";
+import showDetailsInjectable from "../../../kube-detail-params/show-details.injectable";
+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";
export interface RoleBindingDialogProps extends Partial {
}
-interface DialogState {
- isOpen: boolean;
- data?: RoleBinding;
+interface Dependencies {
+ state: IObservableValue;
+ roleBindingStore: RoleBindingStore;
+ closeRoleBindingDialog: () => void;
+ showDetails: ShowDetails;
+ roleStore: RoleStore;
+ clusterRoleStore: ClusterRoleStore;
+ serviceAccountStore: ServiceAccountStore;
+ roleApi: RoleApi;
}
@observer
-export class RoleBindingDialog extends React.Component {
- static state = observable.object({
- isOpen: false,
- });
-
- constructor(props: RoleBindingDialogProps) {
+class NonInjectedRoleBindingDialog extends React.Component {
+ constructor(props: RoleBindingDialogProps & Dependencies) {
super(props);
makeObservable(this);
}
- static open(roleBinding?: RoleBinding) {
- RoleBindingDialog.state.isOpen = true;
- RoleBindingDialog.state.data = roleBinding;
- }
-
- static close() {
- RoleBindingDialog.state.isOpen = false;
- RoleBindingDialog.state.data = undefined;
- }
-
- get roleBinding() {
- return RoleBindingDialog.state.data;
+ @computed get roleBinding() {
+ return this.props.state.get().roleBinding;
}
@computed get isEditing() {
@@ -97,6 +98,10 @@ export class RoleBindingDialog extends React.Component {
}
@computed get roleRefOptions(): SelectOption[] {
+ const {
+ roleStore,
+ clusterRoleStore,
+ } = this.props;
const roles = roleStore.items
.filter(role => role.getNs() === this.bindingNamespace);
const clusterRoles = clusterRoleStore.items;
@@ -111,7 +116,7 @@ export class RoleBindingDialog extends React.Component {
}
@computed get serviceAccountOptions(): SelectOption[] {
- return serviceAccountStore.items.map(serviceAccount => ({
+ return this.props.serviceAccountStore.items.map(serviceAccount => ({
value: serviceAccount,
label: `${serviceAccount.getName()} (${serviceAccount.getNs()})`,
isSelected: this.selectedAccounts.has(serviceAccount),
@@ -119,18 +124,22 @@ export class RoleBindingDialog extends React.Component {
}
onOpen = action(() => {
+ const {
+ roleStore,
+ clusterRoleStore,
+ serviceAccountStore,
+ roleApi,
+ } = this.props;
const binding = this.roleBinding;
if (!binding) {
return this.reset();
}
- const findByRoleRefName = (item: Role | ClusterRole) => item.getName() === binding.roleRef.name;
-
this.selectedRoleRef = (
binding.roleRef.kind === roleApi.kind
- ? roleStore.items.find(findByRoleRefName)
- : clusterRoleStore.items.find(findByRoleRefName)
+ ? roleStore.items.find(item => item.getName() === binding.roleRef.name)
+ : clusterRoleStore.items.find(item => item.getName() === binding.roleRef.name)
);
this.bindingName = binding.getName();
@@ -157,6 +166,10 @@ export class RoleBindingDialog extends React.Component {
});
createBindings = async () => {
+ const {
+ roleBindingStore,
+ showDetails,
+ } = this.props;
const { selectedRoleRef, bindingNamespace, selectedBindings, roleBinding, bindingName } = this;
if (!selectedRoleRef || !roleBinding || !bindingNamespace || !bindingName) {
@@ -178,7 +191,7 @@ export class RoleBindingDialog extends React.Component {
});
showDetails(newRoleBinding.selfLink);
- RoleBindingDialog.close();
+ this.props.closeRoleBindingDialog();
} catch (err) {
Notifications.checkedError(err, `Unknown error occured while ${this.isEditing ? "editing" : "creating"} role bindings.`);
}
@@ -260,7 +273,7 @@ export class RoleBindingDialog extends React.Component {
}
render() {
- const { ...dialogProps } = this.props;
+ const { closeRoleBindingDialog, roleBindingStore, state, ...dialogProps } = this.props;
const [action, nextLabel] = this.isEditing ? ["Edit", "Update"] : ["Add", "Create"];
const disableNext = !this.selectedRoleRef || !this.selectedBindings.length || !this.bindingNamespace || !this.bindingName;
@@ -268,8 +281,8 @@ export class RoleBindingDialog extends React.Component {