diff --git a/src/common/utils/hash-set.ts b/src/common/utils/hash-set.ts index c19bf14685..358fc9e578 100644 --- a/src/common/utils/hash-set.ts +++ b/src/common/utils/hash-set.ts @@ -21,8 +21,6 @@ import { action, IInterceptable, IInterceptor, IListenable, ISetWillChange, observable, ObservableMap, ObservableSet } from "mobx"; -export * from "./hashers"; - export function makeIterable(iterator: Iterator): IterableIterator { (iterator as IterableIterator)[Symbol.iterator] = () => iterator as IterableIterator; diff --git a/src/common/utils/hashers.ts b/src/common/utils/hashers.ts deleted file mode 100644 index b815a73a00..0000000000 --- a/src/common/utils/hashers.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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 { MD5 } from "crypto-js"; -import type { RoleBindingSubject } from "../../renderer/api/endpoints"; -import type { KubeObject } from "../../renderer/api/kube-object"; - -export function hashKubeObject(k: KubeObject): string { - return k.metadata.uid; -} - -export function hashRoleBindingSubject(subject: RoleBindingSubject): string { - return MD5(JSON.stringify([ - ["kind", subject.kind], - ["name", subject.name], - ["namespace", subject.namespace], - ["apiGroup", subject.apiGroup], - ])).toString(); -} diff --git a/src/extensions/renderer-api/k8s-api.ts b/src/extensions/renderer-api/k8s-api.ts index 5e939bc54d..c579aafbb6 100644 --- a/src/extensions/renderer-api/k8s-api.ts +++ b/src/extensions/renderer-api/k8s-api.ts @@ -88,6 +88,6 @@ export type { StorageClassStore } from "../../renderer/components/+storage-class export type { NamespaceStore } from "../../renderer/components/+namespaces/namespace.store"; export type { ServiceAccountsStore } from "../../renderer/components/+user-management/+service-accounts/store"; export type { RolesStore } from "../../renderer/components/+user-management/+roles/store"; -export type { RoleBindingsStore } from "../../renderer/components/+user-management/+roles-bindings/store"; +export type { RoleBindingsStore } from "../../renderer/components/+user-management/+role-bindings/store"; export type { CRDStore } from "../../renderer/components/+custom-resources/crd.store"; export type { CRDResourceStore } from "../../renderer/components/+custom-resources/crd-resource.store"; diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/details.scss b/src/renderer/components/+user-management/+cluster-role-bindings/details.scss similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/details.scss rename to src/renderer/components/+user-management/+cluster-role-bindings/details.scss diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/details.tsx b/src/renderer/components/+user-management/+cluster-role-bindings/details.tsx similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/details.tsx rename to src/renderer/components/+user-management/+cluster-role-bindings/details.tsx diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/dialog.scss b/src/renderer/components/+user-management/+cluster-role-bindings/dialog.scss similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/dialog.scss rename to src/renderer/components/+user-management/+cluster-role-bindings/dialog.scss diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/dialog.tsx b/src/renderer/components/+user-management/+cluster-role-bindings/dialog.tsx similarity index 98% rename from src/renderer/components/+user-management/+cluster-roles-bindings/dialog.tsx rename to src/renderer/components/+user-management/+cluster-role-bindings/dialog.tsx index 46320610ac..b39d891914 100644 --- a/src/renderer/components/+user-management/+cluster-roles-bindings/dialog.tsx +++ b/src/renderer/components/+user-management/+cluster-role-bindings/dialog.tsx @@ -38,7 +38,7 @@ import { Wizard, WizardStep } from "../../wizard"; import { clusterRoleBindingsStore } from "./store"; import { clusterRolesStore } from "../+cluster-roles/store"; import { getRoleRefSelectOption } from "../role-ref-select-option"; -import { ObservableHashSet, hashKubeObject, nFircate } from "../../../utils"; +import { ObservableHashSet, nFircate } from "../../../utils"; interface BindingSelectOption extends SelectOption { value: string; // binding name @@ -92,7 +92,7 @@ export class ClusterRoleBindingDialog extends React.Component { @observable selectedRoleRef: ClusterRole | undefined = undefined; @observable bindingName = ""; - selectedAccounts = new ObservableHashSet([], hashKubeObject); + selectedAccounts = new ObservableHashSet([], sa => sa.metadata.uid); selectedUsers = observable.set([]); selectedGroups = observable.set([]); diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/index.ts b/src/renderer/components/+user-management/+cluster-role-bindings/index.ts similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/index.ts rename to src/renderer/components/+user-management/+cluster-role-bindings/index.ts diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/store.ts b/src/renderer/components/+user-management/+cluster-role-bindings/store.ts similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/store.ts rename to src/renderer/components/+user-management/+cluster-role-bindings/store.ts diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/view.scss b/src/renderer/components/+user-management/+cluster-role-bindings/view.scss similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/view.scss rename to src/renderer/components/+user-management/+cluster-role-bindings/view.scss diff --git a/src/renderer/components/+user-management/+cluster-roles-bindings/view.tsx b/src/renderer/components/+user-management/+cluster-role-bindings/view.tsx similarity index 100% rename from src/renderer/components/+user-management/+cluster-roles-bindings/view.tsx rename to src/renderer/components/+user-management/+cluster-role-bindings/view.tsx diff --git a/src/renderer/components/+user-management/+roles-bindings/details.scss b/src/renderer/components/+user-management/+role-bindings/details.scss similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/details.scss rename to src/renderer/components/+user-management/+role-bindings/details.scss diff --git a/src/renderer/components/+user-management/+roles-bindings/details.tsx b/src/renderer/components/+user-management/+role-bindings/details.tsx similarity index 95% rename from src/renderer/components/+user-management/+roles-bindings/details.tsx rename to src/renderer/components/+user-management/+role-bindings/details.tsx index 7aa87c5a40..eda60be8d9 100644 --- a/src/renderer/components/+user-management/+roles-bindings/details.tsx +++ b/src/renderer/components/+user-management/+role-bindings/details.tsx @@ -37,11 +37,20 @@ import { Table, TableCell, TableHead, TableRow } from "../../table"; import { RoleBindingDialog } from "./dialog"; import { roleBindingsStore } from "./store"; import { ObservableHashSet } from "../../../../common/utils/hash-set"; -import { hashRoleBindingSubject } from "../../../../common/utils/hashers"; +import { MD5 } from "crypto-js"; interface Props extends KubeObjectDetailsProps { } +function hashRoleBindingSubject(subject: RoleBindingSubject): string { + return MD5(JSON.stringify([ + ["kind", subject.kind], + ["name", subject.name], + ["namespace", subject.namespace], + ["apiGroup", subject.apiGroup], + ])).toString(); +} + @observer export class RoleBindingDetails extends React.Component { selectedSubjects = new ObservableHashSet([], hashRoleBindingSubject); diff --git a/src/renderer/components/+user-management/+roles-bindings/dialog.scss b/src/renderer/components/+user-management/+role-bindings/dialog.scss similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/dialog.scss rename to src/renderer/components/+user-management/+role-bindings/dialog.scss diff --git a/src/renderer/components/+user-management/+roles-bindings/dialog.tsx b/src/renderer/components/+user-management/+role-bindings/dialog.tsx similarity index 98% rename from src/renderer/components/+user-management/+roles-bindings/dialog.tsx rename to src/renderer/components/+user-management/+role-bindings/dialog.tsx index e6122578b2..ba7113ed10 100644 --- a/src/renderer/components/+user-management/+roles-bindings/dialog.tsx +++ b/src/renderer/components/+user-management/+role-bindings/dialog.tsx @@ -41,7 +41,7 @@ import { roleBindingsStore } from "./store"; import { clusterRolesStore } from "../+cluster-roles/store"; import { Input } from "../../input"; import { getRoleRefSelectOption } from "../role-ref-select-option"; -import { ObservableHashSet, hashKubeObject, nFircate } from "../../../utils"; +import { ObservableHashSet, nFircate } from "../../../utils"; interface Props extends Partial { } @@ -83,7 +83,7 @@ export class RoleBindingDialog extends React.Component { @observable.ref selectedRoleRef: Role | ClusterRole | undefined = undefined; @observable bindingName = ""; @observable bindingNamespace = ""; - selectedAccounts = new ObservableHashSet([], hashKubeObject); + selectedAccounts = new ObservableHashSet([], sa => sa.metadata.uid); selectedUsers = observable.set([]); selectedGroups = observable.set([]); diff --git a/src/renderer/components/+user-management/+roles-bindings/index.ts b/src/renderer/components/+user-management/+role-bindings/index.ts similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/index.ts rename to src/renderer/components/+user-management/+role-bindings/index.ts diff --git a/src/renderer/components/+user-management/+roles-bindings/store.ts b/src/renderer/components/+user-management/+role-bindings/store.ts similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/store.ts rename to src/renderer/components/+user-management/+role-bindings/store.ts diff --git a/src/renderer/components/+user-management/+roles-bindings/view.scss b/src/renderer/components/+user-management/+role-bindings/view.scss similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/view.scss rename to src/renderer/components/+user-management/+role-bindings/view.scss diff --git a/src/renderer/components/+user-management/+roles-bindings/view.tsx b/src/renderer/components/+user-management/+role-bindings/view.tsx similarity index 100% rename from src/renderer/components/+user-management/+roles-bindings/view.tsx rename to src/renderer/components/+user-management/+role-bindings/view.tsx diff --git a/src/renderer/components/+user-management/+service-accounts/details.tsx b/src/renderer/components/+user-management/+service-accounts/details.tsx index 98af4d9c90..7b9a590138 100644 --- a/src/renderer/components/+user-management/+service-accounts/details.tsx +++ b/src/renderer/components/+user-management/+service-accounts/details.tsx @@ -22,7 +22,7 @@ import "./details.scss"; import { autorun, observable, makeObservable } from "mobx"; -import { disposeOnUnmount } from "mobx-react"; +import { disposeOnUnmount, observer } from "mobx-react"; import React from "react"; import { Link } from "react-router-dom"; @@ -40,6 +40,7 @@ import { ServiceAccountsSecret } from "./secret"; interface Props extends KubeObjectDetailsProps { } +@observer export class ServiceAccountsDetails extends React.Component { @observable secrets: Secret[]; @observable imagePullSecrets: Secret[]; diff --git a/src/renderer/components/+user-management/user-management.tsx b/src/renderer/components/+user-management/user-management.tsx index 6e4694b28d..c714f34525 100644 --- a/src/renderer/components/+user-management/user-management.tsx +++ b/src/renderer/components/+user-management/user-management.tsx @@ -28,9 +28,9 @@ import { PodSecurityPolicies } from "../+pod-security-policies"; import { isAllowedResource } from "../../../common/rbac"; import { TabLayout, TabLayoutRoute } from "../layout/tab-layout"; import { ClusterRoles } from "./+cluster-roles"; -import { ClusterRoleBindings } from "./+cluster-roles-bindings"; +import { ClusterRoleBindings } from "./+cluster-role-bindings"; import { Roles } from "./+roles"; -import { RoleBindings } from "./+roles-bindings"; +import { RoleBindings } from "./+role-bindings"; import { ServiceAccounts } from "./+service-accounts"; import { clusterRoleBindingsRoute, diff --git a/src/renderer/components/app.scss b/src/renderer/components/app.scss index 4097b1d99b..b4c15b89fd 100755 --- a/src/renderer/components/app.scss +++ b/src/renderer/components/app.scss @@ -29,7 +29,7 @@ --unit: 8px; --padding: var(--unit); --margin: var(--unit); - --border-radius: 5px; + --border-radius: 3px; --font-main: 'Roboto', 'Helvetica', 'Arial', sans-serif; --font-monospace: Lucida Console, Monaco, Consolas, monospace; --font-size-small: calc(1.5 * var(--unit)); diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 32c654c148..5b68b56e2e 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -20,57 +20,56 @@ */ import React from "react"; import { observable, makeObservable } from "mobx"; -import { webFrame } from "electron"; import { disposeOnUnmount, observer } from "mobx-react"; import { Redirect, Route, Router, Switch } from "react-router"; -import whatInput from "what-input"; - -import { clusterSetFrameIdHandler } from "../../common/cluster-ipc"; -import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store"; -import { appEventBus } from "../../common/event-bus"; -import { requestMain } from "../../common/ipc"; -import { isAllowedResource } from "../../common/rbac"; -import { ExtensionLoader } from "../../extensions/extension-loader"; -import { ClusterPageMenuRegistration, clusterPageMenuRegistry } from "../../extensions/registries"; -import { clusterPageRegistry, getExtensionPageUrl } from "../../extensions/registries/page-registry"; -import logger from "../../main/logger"; -import { kubeWatchApi } from "../api/kube-watch-api"; -import { KubeObjectStore } from "../kube-object.store"; import { history } from "../navigation"; +import { Notifications } from "./notifications"; import { NotFound } from "./+404"; -import { Apps, appsRoute } from "./+apps"; +import { UserManagement } from "./+user-management/user-management"; +import { ConfirmDialog } from "./confirm-dialog"; +import { usersManagementRoute } from "./+user-management/user-management.route"; import { clusterRoute, clusterURL } from "./+cluster"; +import { KubeConfigDialog } from "./kubeconfig-dialog/kubeconfig-dialog"; +import { Nodes, nodesRoute } from "./+nodes"; +import { Workloads, workloadsRoute, workloadsURL } from "./+workloads"; +import { Namespaces, namespacesRoute } from "./+namespaces"; +import { Network, networkRoute } from "./+network"; +import { Storage, storageRoute } from "./+storage"; import { ClusterOverview } from "./+cluster/cluster-overview"; import { Config, configRoute } from "./+config"; -import { crdRoute } from "./+custom-resources"; -import { CustomResources } from "./+custom-resources/custom-resources"; -import { eventRoute } from "./+events"; -import { eventStore } from "./+events/event.store"; import { Events } from "./+events/events"; -import { Namespaces, namespacesRoute } from "./+namespaces"; -import { namespaceStore } from "./+namespaces/namespace.store"; -import { Network, networkRoute } from "./+network"; -import { Nodes, nodesRoute } from "./+nodes"; -import { nodesStore } from "./+nodes/nodes.store"; -import { Storage, storageRoute } from "./+storage"; -import { UserManagement } from "./+user-management/user-management"; -import { usersManagementRoute } from "./+user-management/user-management.route"; -import { Workloads, workloadsRoute, workloadsURL } from "./+workloads"; -import { CronJobTriggerDialog } from "./+workloads-cronjobs/cronjob-trigger-dialog"; -import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale-dialog"; -import { podsStore } from "./+workloads-pods/pods.store"; -import { ReplicaSetScaleDialog } from "./+workloads-replicasets/replicaset-scale-dialog"; -import { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog"; -import { CommandContainer } from "./command-palette/command-container"; -import { ConfirmDialog } from "./confirm-dialog"; -import { clusterContext } from "./context"; -import { Terminal } from "./dock/terminal"; -import { ErrorBoundary } from "./error-boundary"; +import { eventRoute } from "./+events"; +import { Apps, appsRoute } from "./+apps"; import { KubeObjectDetails } from "./kube-object/kube-object-details"; -import { KubeConfigDialog } from "./kubeconfig-dialog/kubeconfig-dialog"; +import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale-dialog"; +import { CronJobTriggerDialog } from "./+workloads-cronjobs/cronjob-trigger-dialog"; +import { CustomResources } from "./+custom-resources/custom-resources"; +import { crdRoute } from "./+custom-resources"; +import { isAllowedResource } from "../../common/rbac"; import { MainLayout } from "./layout/main-layout"; +import { ErrorBoundary } from "./error-boundary"; +import { Terminal } from "./dock/terminal"; +import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store"; +import logger from "../../main/logger"; +import { webFrame } from "electron"; +import { clusterPageRegistry, getExtensionPageUrl } from "../../extensions/registries/page-registry"; +import { ExtensionLoader } from "../../extensions/extension-loader"; +import { appEventBus } from "../../common/event-bus"; +import { requestMain } from "../../common/ipc"; +import whatInput from "what-input"; +import { clusterSetFrameIdHandler } from "../../common/cluster-ipc"; +import { ClusterPageMenuRegistration, clusterPageMenuRegistry } from "../../extensions/registries"; import { TabLayout, TabLayoutRoute } from "./layout/tab-layout"; -import { Notifications } from "./notifications"; +import { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog"; +import { eventStore } from "./+events/event.store"; +import { nodesStore } from "./+nodes/nodes.store"; +import { podsStore } from "./+workloads-pods/pods.store"; +import { kubeWatchApi } from "../api/kube-watch-api"; +import { ReplicaSetScaleDialog } from "./+workloads-replicasets/replicaset-scale-dialog"; +import { CommandContainer } from "./command-palette/command-container"; +import { KubeObjectStore } from "../kube-object.store"; +import { clusterContext } from "./context"; +import { namespaceStore } from "./+namespaces/namespace.store"; @observer export class App extends React.Component { diff --git a/src/renderer/components/kube-object/kube-object-details.tsx b/src/renderer/components/kube-object/kube-object-details.tsx index 46e659b197..217c7c25c8 100644 --- a/src/renderer/components/kube-object/kube-object-details.tsx +++ b/src/renderer/components/kube-object/kube-object-details.tsx @@ -33,7 +33,6 @@ import { crdStore } from "../+custom-resources/crd.store"; import { CrdResourceDetails } from "../+custom-resources"; import { KubeObjectMenu } from "./kube-object-menu"; import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; -import type { CustomResourceDefinition } from "../../api/endpoints"; /** * Used to store `object.selfLink` to show more info about resource in the details panel. @@ -100,7 +99,11 @@ export class KubeObjectDetails extends React.Component { } @computed get object() { - return apiManager.getStore(this.path)?.getByPath(this.path); + const store = apiManager.getStore(this.path); + + if (store) { + return store.getByPath(this.path); + } } @computed get isCrdInstance() { @@ -148,7 +151,7 @@ export class KubeObjectDetails extends React.Component { }); if (isCrdInstance && details.length === 0) { - details.push(); + details.push(); } } diff --git a/src/renderer/components/select/select.scss b/src/renderer/components/select/select.scss index 286f70c140..55fddec850 100644 --- a/src/renderer/components/select/select.scss +++ b/src/renderer/components/select/select.scss @@ -46,15 +46,16 @@ html { } &__control { - border: solid 1px $halfGray; + border: none; border-radius: $radius; background: var(--select-menu-bgc); min-height: 0; + box-shadow: 0 0 0 1px $halfGray; cursor: pointer; line-height: 1; &--is-focused { - border-color: $primary; + box-shadow: 0 0 0 1px $primary; } } @@ -89,7 +90,7 @@ html { &__menu { background: var(--select-menu-bgc); - border-color: var(--select-menu-border-color); + box-shadow: inset 0 0 0 1px var(--select-menu-border-color); width: max-content; min-width: 100%; @@ -170,7 +171,7 @@ html { .Select { &__multi-value { background: none; - border-color: $textColorSecondary; + box-shadow: 0 0 0 1px $textColorSecondary; } &__option { @@ -195,7 +196,7 @@ html { &.theme-outlined { .Select__control { - border-color: $colorVague; + box-shadow: 0 0 0 1px $colorVague; color: $primary; .Select__value-container { @@ -211,23 +212,23 @@ html { &.theme-lens { :hover { &.Select__control { - border-color: var(--inputControlHoverBorder); + box-shadow: 0 0 0 1px var(--inputControlHoverBorder); } } :focus-within { &.Select__control { - border-color: $colorInfo; + box-shadow: 0 0 0 1px $colorInfo; } } &.Select__menu { - border-color: var(--inputControlBorder); + box-shadow: inset 0 0 0 1px var(--inputControlBorder); } .Select { &__control { - border-color: var(--inputControlBorder); + box-shadow: 0 0 0 1px var(--inputControlBorder); background: var(--inputControlBackground); border-radius: 5px; }