From 8d0abcc9d55cd951870e5b51b2e7f3ab3cee3014 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Thu, 4 Nov 2021 09:23:59 +0200 Subject: [PATCH] Demonstrate naive way to make component not responsible of it's dependencies and not use global shared state This is to make a step towards satisfaction of Dependency Inversion Principle. It's not fully satisfied because we still depend on concrete instances of classes instead of interfaces. This will start chain of thought to pursue warm and friendly unit testing and introduction of SOLID principles. Signed-off-by: Janne Savolainen Co-authored-by: Mikko Aspiala --- .../deployment-replicasets.tsx | 3 +- .../kube-object-details.tsx | 5 +- .../kube-object-list-layout.tsx | 3 +- .../inject-naive/inject-naive.tsx | 46 +++++++++++++++++ .../kube-object-menu/kube-object-menu.tsx | 51 ++++++++++++++----- 5 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 src/renderer/components/kube-object-menu/inject-naive/inject-naive.tsx diff --git a/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx b/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx index 03c8c47890..eae0e10332 100644 --- a/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx +++ b/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx @@ -32,6 +32,7 @@ import { Table, TableCell, TableHead, TableRow } from "../table"; import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { replicaSetStore } from "../+workloads-replicasets/replicasets.store"; import { showDetails } from "../kube-detail-params"; +import { InjectNaive } from "../kube-object-menu/inject-naive/inject-naive"; enum sortBy { @@ -115,6 +116,6 @@ export class DeploymentReplicaSets extends React.Component { export function ReplicaSetMenu(props: KubeObjectMenuProps) { return ( - + ); } diff --git a/src/renderer/components/kube-object-details/kube-object-details.tsx b/src/renderer/components/kube-object-details/kube-object-details.tsx index be888c6505..dacd0b61de 100644 --- a/src/renderer/components/kube-object-details/kube-object-details.tsx +++ b/src/renderer/components/kube-object-details/kube-object-details.tsx @@ -35,6 +35,7 @@ import logger from "../../../main/logger"; import { CrdResourceDetails } from "../+custom-resources"; import { KubeObjectMeta } from "../kube-object-meta"; import { hideDetails, kubeDetailsUrlParam } from "../kube-detail-params"; +import { InjectNaive } from "../kube-object-menu/inject-naive/inject-naive"; export interface KubeObjectDetailsProps { @@ -104,7 +105,7 @@ export class KubeObjectDetails extends React.Component { className="KubeObjectDetails flex column" open={isOpen} title="" - toolbar={} + toolbar={} onClose={hideDetails} > {isLoading && } @@ -144,7 +145,7 @@ export class KubeObjectDetails extends React.Component { className="KubeObjectDetails flex column" open={isOpen} title={title} - toolbar={} + toolbar={} onClose={hideDetails} > {isLoading && } diff --git a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx index f29a6da6e7..f0d9591e62 100644 --- a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx +++ b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx @@ -36,6 +36,7 @@ import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params"; import { Icon } from "../icon"; import { TooltipPosition } from "../tooltip"; import type { ClusterContext } from "../../../common/k8s-api/cluster-context"; +import { InjectNaive } from "../kube-object-menu/inject-naive/inject-naive"; export interface KubeObjectListLayoutProps extends ItemListLayoutProps { store: KubeObjectStore; @@ -140,7 +141,7 @@ export class KubeObjectListLayout extends React.Component< }), ...[customizeHeader].flat(), ]} - renderItemMenu={item => } + renderItemMenu={item => } /> ); } diff --git a/src/renderer/components/kube-object-menu/inject-naive/inject-naive.tsx b/src/renderer/components/kube-object-menu/inject-naive/inject-naive.tsx new file mode 100644 index 0000000000..91d97d25ea --- /dev/null +++ b/src/renderer/components/kube-object-menu/inject-naive/inject-naive.tsx @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import React from "react"; +import { editResourceTab } from "../../dock/edit-resource.store"; +import { hideDetails } from "../../kube-detail-params"; +import { apiManager } from "../../../../common/k8s-api/api-manager"; +import { KubeObjectMenuRegistry } from "../../../../extensions/registries"; +import { catalogEntityRegistry } from "../../../api/catalog-entity-registry"; + + +interface Props { + Component: React.ReactType + [key: string]: any, +} + +export const InjectNaive = ({ Component, ...props }: Props) => { + const kubeObjectMenuRegistry = KubeObjectMenuRegistry.getInstance(); + + return ( + ); +}; diff --git a/src/renderer/components/kube-object-menu/kube-object-menu.tsx b/src/renderer/components/kube-object-menu/kube-object-menu.tsx index adccdd3d57..2116221f03 100644 --- a/src/renderer/components/kube-object-menu/kube-object-menu.tsx +++ b/src/renderer/components/kube-object-menu/kube-object-menu.tsx @@ -22,13 +22,13 @@ import React from "react"; import { boundMethod, cssNames } from "../../utils"; import type { KubeObject } from "../../../common/k8s-api/kube-object"; -import { editResourceTab } from "../dock/edit-resource.store"; import { MenuActions, MenuActionsProps } from "../menu/menu-actions"; -import { hideDetails } from "../kube-detail-params"; -import { apiManager } from "../../../common/k8s-api/api-manager"; -import { KubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import identity from "lodash/identity"; -import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; + +import type { KubeObjectMenuRegistry } from "../../../extensions/registries"; +import type { ApiManager } from "../../../common/k8s-api/api-manager"; +import type { CatalogEntityRegistry } from "../../api/catalog-entity-registry"; + export interface KubeObjectMenuProps extends MenuActionsProps { object: T | null | undefined; @@ -36,13 +36,39 @@ export interface KubeObjectMenuProps extends MenuActionsProps { removable?: boolean; } -export class KubeObjectMenu extends React.Component> { +interface KubeObjectMenuDependencies extends KubeObjectMenuProps{ + apiManager: ApiManager, + hideDetails: Function, + editResourceTab: Function, + catalogEntityRegistry: CatalogEntityRegistry, + kubeObjectMenuRegistry: KubeObjectMenuRegistry +} + +export class KubeObjectMenu extends React.Component> { + get dependencies() { + const { + apiManager, + hideDetails, + editResourceTab, + catalogEntityRegistry, + kubeObjectMenuRegistry, + } = this.props; + + return { + apiManager, + editResourceTab, + hideDetails, + kubeObjectMenuRegistry, + catalogEntityRegistry, + }; + } + get store() { const { object } = this.props; if (!object) return null; - return apiManager.getStore(object.selfLink); + return this.dependencies.apiManager.getStore(object.selfLink); } get isEditable() { @@ -55,13 +81,13 @@ export class KubeObjectMenu extends React.Component extends React.Component extends React.Component (