1
0
mirror of https://github.com/lensapp/lens.git synced 2024-09-11 09:25:26 +03:00

chore: Extract sidebar item injection token into separate package

- Add unit tests to cover custom resources sidebar items

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-05-12 09:46:48 -04:00
parent d28da8e7ac
commit 500ac15703
113 changed files with 5645 additions and 1681 deletions

View File

@ -184,6 +184,7 @@
"@k8slens/application-for-electron-main": "^6.5.0", "@k8slens/application-for-electron-main": "^6.5.0",
"@k8slens/button": "^1.0.0", "@k8slens/button": "^1.0.0",
"@k8slens/cluster-settings": "^6.5.0", "@k8slens/cluster-settings": "^6.5.0",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/core": "^6.5.0", "@k8slens/core": "^6.5.0",
"@k8slens/ensure-binaries": "^6.5.0", "@k8slens/ensure-binaries": "^6.5.0",
"@k8slens/error-boundary": "^1.0.0", "@k8slens/error-boundary": "^1.0.0",

View File

@ -25,13 +25,14 @@ runInAction(() => {
registerLensCore(di, environment); registerLensCore(di, environment);
registerFeature(di, registerFeature(di,
loggerFeature, loggerFeature,
); );
registerFeature(di, registerFeature(
applicationFeature, di,
applicationFeatureForElectronMain, applicationFeature,
messagingFeatureForMain, applicationFeatureForElectronMain,
messagingFeatureForMain,
); );
try { try {

View File

@ -28,6 +28,7 @@ import { reactApplicationFeature } from "@k8slens/react-application";
import { routingFeature } from "@k8slens/routing"; import { routingFeature } from "@k8slens/routing";
import { loggerFeature } from "@k8slens/logger"; import { loggerFeature } from "@k8slens/logger";
import { animateFeature } from "@k8slens/animate"; import { animateFeature } from "@k8slens/animate";
import { clusterSidebarFeature } from "@k8slens/cluster-sidebar";
const environment = "renderer"; const environment = "renderer";
@ -54,6 +55,7 @@ runInAction(() => {
routingFeature, routingFeature,
metricsFeature, metricsFeature,
animateFeature, animateFeature,
clusterSidebarFeature,
); );
autoRegister({ autoRegister({

26
package-lock.json generated
View File

@ -3702,6 +3702,10 @@
"resolved": "packages/cluster-settings", "resolved": "packages/cluster-settings",
"link": true "link": true
}, },
"node_modules/@k8slens/cluster-sidebar": {
"resolved": "packages/cluster-sidebar",
"link": true
},
"node_modules/@k8slens/computed-channel": { "node_modules/@k8slens/computed-channel": {
"resolved": "packages/technical-features/messaging/computed-channel", "resolved": "packages/technical-features/messaging/computed-channel",
"link": true "link": true
@ -33993,6 +33997,7 @@
"@k8slens/application-for-electron-main": "^6.5.0", "@k8slens/application-for-electron-main": "^6.5.0",
"@k8slens/button": "^1.0.0", "@k8slens/button": "^1.0.0",
"@k8slens/cluster-settings": "^6.5.0", "@k8slens/cluster-settings": "^6.5.0",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/core": "^6.5.0", "@k8slens/core": "^6.5.0",
"@k8slens/ensure-binaries": "^6.5.0", "@k8slens/ensure-binaries": "^6.5.0",
"@k8slens/error-boundary": "^1.0.0", "@k8slens/error-boundary": "^1.0.0",
@ -34200,6 +34205,26 @@
"@ogre-tools/injectable": "^17.1.0" "@ogre-tools/injectable": "^17.1.0"
} }
}, },
"packages/cluster-sidebar": {
"name": "@k8slens/cluster-sidebar",
"version": "1.0.0-alpha.0",
"license": "MIT",
"devDependencies": {
"@k8slens/eslint-config": "^6.5.0-alpha.3",
"@k8slens/jest": "^6.5.0-alpha.5",
"@k8slens/typescript": "^6.5.0-alpha.2",
"@k8slens/webpack": "^6.5.0-alpha.5"
},
"peerDependencies": {
"@k8slens/feature-core": "^6.5.0-alpha.4",
"@k8slens/utilities": "^1.0.0-alpha.3",
"@ogre-tools/injectable": "^15.8.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.8.1",
"@ogre-tools/injectable-extension-for-mobx": "^15.8.1",
"mobx": "^6.9.0",
"react": "^17.0.2"
}
},
"packages/core": { "packages/core": {
"name": "@k8slens/core", "name": "@k8slens/core",
"version": "6.5.0", "version": "6.5.0",
@ -34318,6 +34343,7 @@
"@k8slens/application-for-electron-main": "^6.5.0-alpha.0", "@k8slens/application-for-electron-main": "^6.5.0-alpha.0",
"@k8slens/button": "^1.0.0-alpha.5", "@k8slens/button": "^1.0.0-alpha.5",
"@k8slens/cluster-settings": "^6.5.0-alpha.1", "@k8slens/cluster-settings": "^6.5.0-alpha.1",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/error-boundary": "^1.0.0-alpha.5", "@k8slens/error-boundary": "^1.0.0-alpha.5",
"@k8slens/event-emitter": "^1.0.0-alpha.1", "@k8slens/event-emitter": "^1.0.0-alpha.1",
"@k8slens/icon": "^1.0.0-alpha.7", "@k8slens/icon": "^1.0.0-alpha.7",

View File

@ -0,0 +1,6 @@
module.exports = {
extends: "@k8slens/eslint-config/eslint",
parserOptions: {
project: "./tsconfig.json",
},
};

View File

@ -0,0 +1 @@
"@k8slens/eslint-config/prettier"

View File

@ -0,0 +1,8 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export * from "./src/tokens";
export * from "./src/feature";
export { default as sidebarItemsInjectable } from "./src/sidebar-items.injectable";

View File

@ -0,0 +1 @@
module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;

View File

@ -0,0 +1,48 @@
{
"name": "@k8slens/cluster-sidebar",
"private": false,
"version": "1.0.0-alpha.0",
"description": "Injection tokens for adding new sidebar items within the Cluster View",
"type": "commonjs",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": {
"name": "OpenLens Authors",
"email": "info@k8slens.dev"
},
"license": "MIT",
"homepage": "https://github.com/lensapp/lens",
"scripts": {
"build": "lens-webpack-build",
"clean": "rimraf dist/",
"test": "jest --coverage --runInBand",
"lint": "lens-lint",
"lint:fix": "lens-lint --fix"
},
"peerDependencies": {
"@k8slens/feature-core": "^6.5.0-alpha.4",
"@k8slens/utilities": "^1.0.0-alpha.3",
"@ogre-tools/injectable": "^15.8.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.8.1",
"@ogre-tools/injectable-extension-for-mobx": "^15.8.1",
"mobx": "^6.9.0",
"react": "^17.0.2"
},
"devDependencies": {
"@k8slens/eslint-config": "^6.5.0-alpha.3",
"@k8slens/jest": "^6.5.0-alpha.5",
"@k8slens/typescript": "^6.5.0-alpha.2",
"@k8slens/webpack": "^6.5.0-alpha.5"
}
}

View File

@ -0,0 +1,14 @@
import { getFeature } from "@k8slens/feature-core";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
export const clusterSidebarFeature = getFeature({
id: "cluster-side-feature",
register: (di) => {
autoRegister({
di,
targetModule: module,
getRequireContexts: () => [require.context("./", true, /\.injectable\.(ts|tsx)$/)],
});
},
});

View File

@ -0,0 +1,62 @@
/* eslint-disable prettier/prettier */
import { getInjectable } from "@ogre-tools/injectable";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
import { HierarchicalSidebarItem, sidebarItemInjectionToken, SidebarItemRegistration } from "./tokens";
import { computed } from "mobx";
import { byOrderNumber } from "@k8slens/utilities";
const getSidebarItemsHierarchy = (
registrations: SidebarItemRegistration[],
parentId: string | null,
): HierarchicalSidebarItem[] => (
registrations
.filter((item) => item.parentId === parentId)
.map(({
isActive,
isVisible,
...registration
}) => {
const children = getSidebarItemsHierarchy(registrations, registration.id);
return {
...registration,
children,
isVisible: computed(() => {
if (children.length === 0) {
if (isVisible) {
return isVisible.get();
}
return true;
}
return children.some((child) => child.isVisible.get());
}),
isActive: computed(() => {
if (children.length === 0) {
if (isActive) {
return isActive.get();
}
return false;
}
return children.some((child) => child.isActive.get());
}),
};
})
.sort(byOrderNumber)
);
const sidebarItemsInjectable = getInjectable({
id: "sidebar-items",
instantiate: (di) => {
const computedInjectMany = di.inject(computedInjectManyInjectable);
const sidebarItemRegistrations = computedInjectMany(sidebarItemInjectionToken);
return computed(() => getSidebarItemsHierarchy(sidebarItemRegistrations.get(), null));
},
});
export default sidebarItemsInjectable;

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import type { StrictReactNode } from "@k8slens/utilities";
export interface SidebarItemRegistration {
id: string;
parentId: string | null;
title: StrictReactNode;
onClick: () => void;
getIcon?: () => StrictReactNode;
isActive?: IComputedValue<boolean>;
isVisible?: IComputedValue<boolean>;
orderNumber: number;
}
export interface SidebarItem {
id: string;
parentId: string | null;
title: StrictReactNode;
onClick: () => void;
getIcon?: () => StrictReactNode;
isActive: IComputedValue<boolean>;
isVisible: IComputedValue<boolean>;
}
export interface HierarchicalSidebarItem extends SidebarItem {
children: HierarchicalSidebarItem[];
}
export const sidebarItemInjectionToken = getInjectionToken<SidebarItemRegistration>({
id: "sidebar-item-injection-token",
});

View File

@ -0,0 +1,4 @@
{
"extends": "@k8slens/typescript/config/base.json",
"include": ["**/*.ts"]
}

View File

@ -0,0 +1 @@
module.exports = require("@k8slens/webpack").configForReact;

View File

@ -211,6 +211,7 @@
"@k8slens/application-for-electron-main": "^6.5.0-alpha.0", "@k8slens/application-for-electron-main": "^6.5.0-alpha.0",
"@k8slens/button": "^1.0.0-alpha.5", "@k8slens/button": "^1.0.0-alpha.5",
"@k8slens/cluster-settings": "^6.5.0-alpha.1", "@k8slens/cluster-settings": "^6.5.0-alpha.1",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/error-boundary": "^1.0.0-alpha.5", "@k8slens/error-boundary": "^1.0.0-alpha.5",
"@k8slens/event-emitter": "^1.0.0-alpha.1", "@k8slens/event-emitter": "^1.0.0-alpha.1",
"@k8slens/kube-api": "^1.0.0-alpha.1", "@k8slens/kube-api": "^1.0.0-alpha.1",

View File

@ -1,21 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
const crdListRouteInjectable = getInjectable({
id: "crd-list-route",
instantiate: () => ({
path: "/crd/definitions",
clusterFrame: true,
isEnabled: computed(() => true),
}),
injectionToken: frontEndRouteInjectionToken,
});
export default crdListRouteInjectable;

View File

@ -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 { shouldShowResourceInjectionToken } from "../../../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
const customResourceDefinitionsRouteInjectable = getInjectable({
id: "custom-resource-definitions-route",
instantiate: (di) => ({
path: "/crd/definitions",
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
group: "apiextensions.k8s.io",
apiName: "customresourcedefinitions",
}),
}),
injectionToken: frontEndRouteInjectionToken,
});
export default customResourceDefinitionsRouteInjectable;

View File

@ -4,8 +4,8 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { computed } from "mobx";
import type { Route } from "../../../../front-end-route-injection-token"; import type { Route } from "../../../front-end-route-injection-token";
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token"; import { frontEndRouteInjectionToken } from "../../../front-end-route-injection-token";
export interface CustomResourcesPathParameters { export interface CustomResourcesPathParameters {
group?: string; group?: string;

View File

@ -3,8 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import crdListRouteInjectable from "./crd-list-route.injectable"; import { navigateToRouteInjectionToken } from "../../../navigate-to-route-injection-token";
import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token"; import crdListRouteInjectable from "./custom-resource-definitions.injectable";
const navigateToCrdListInjectable = getInjectable({ const navigateToCrdListInjectable = getInjectable({
id: "navigate-to-crd-list", id: "navigate-to-crd-list",

View File

@ -3,9 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { navigateToRouteInjectionToken } from "../../../navigate-to-route-injection-token";
import type { CustomResourcesPathParameters } from "./custom-resources-route.injectable"; import type { CustomResourcesPathParameters } from "./custom-resources-route.injectable";
import customResourcesRouteInjectable from "./custom-resources-route.injectable"; import customResourcesRouteInjectable from "./custom-resources-route.injectable";
import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token";
const navigateToCustomResourcesInjectable = getInjectable({ const navigateToCustomResourcesInjectable = getInjectable({
id: "navigate-to-custom-resources", id: "navigate-to-custom-resources",
@ -14,8 +14,7 @@ const navigateToCustomResourcesInjectable = getInjectable({
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
const route = di.inject(customResourcesRouteInjectable); const route = di.inject(customResourcesRouteInjectable);
return (parameters?: CustomResourcesPathParameters) => return (parameters?: CustomResourcesPathParameters) => navigateToRoute(route, { parameters });
navigateToRoute(route, { parameters });
}, },
}); });

View File

@ -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 { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
import { shouldShowResourceInjectionToken } from "../../../../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
const ingressClassesRouteInjectable = getInjectable({
id: "ingress-classes-route",
instantiate: (di) => ({
path: "/ingress-classes",
clusterFrame: true,
isEnabled: di.inject(shouldShowResourceInjectionToken, {
apiName: "ingressclasses",
group: "networking.k8s.io",
}),
}),
injectionToken: frontEndRouteInjectionToken,
});
export default ingressClassesRouteInjectable;

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 { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
import {
shouldShowResourceInjectionToken,
} from "../../../../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
const ingressClassesesRouteInjectable = getInjectable({
id: "ingress-classes-route",
instantiate: (di) => {
const isEnabled = di.inject(shouldShowResourceInjectionToken, {
apiName: "ingressclasses",
group: "networking.k8s.io",
});
return {
path: "/ingress-classes",
clusterFrame: true,
isEnabled,
};
},
injectionToken: frontEndRouteInjectionToken,
});
export default ingressClassesesRouteInjectable;

View File

@ -4,14 +4,14 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token"; import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token";
import ingressClassesesRouteInjectable from "./ingress-classeses-route.injectable"; import ingressClassesRouteInjectable from "./ingress-classes-route.injectable";
const navigateToIngressesInjectable = getInjectable({ const navigateToIngressesInjectable = getInjectable({
id: "navigate-to-ingress-classes", id: "navigate-to-ingress-classes",
instantiate: (di) => { instantiate: (di) => {
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
const route = di.inject(ingressClassesesRouteInjectable); const route = di.inject(ingressClassesRouteInjectable);
return () => navigateToRoute(route); return () => navigateToRoute(route);
}, },

View File

@ -1,25 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { sortBy } from "lodash/fp";
export interface Orderable {
readonly orderNumber: number;
}
export type MaybeOrderable = Orderable | object;
export const orderByOrderNumber = <T extends MaybeOrderable>(maybeOrderables: T[]) =>
sortBy(
(orderable) =>
"orderNumber" in orderable
? orderable.orderNumber
: Number.MAX_SAFE_INTEGER,
maybeOrderables,
);
export const byOrderNumber = <T extends Orderable>(left: T, right: T) => (
left.orderNumber - right.orderNumber
);

View File

@ -4,18 +4,17 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import applicationMenuItemsInjectable from "./application-menu-items.injectable"; import applicationMenuItemsInjectable from "./application-menu-items.injectable";
import type { Composite } from "../../../common/utils/composite/get-composite/get-composite";
import { getCompositeFor } from "../../../common/utils/composite/get-composite/get-composite"; import { getCompositeFor } from "../../../common/utils/composite/get-composite/get-composite";
import { computed } from "mobx"; import { computed } from "mobx";
import { pipeline } from "@ogre-tools/fp";
import type { ApplicationMenuItemTypes } from "./menu-items/application-menu-item-injection-token"; import type { ApplicationMenuItemTypes } from "./menu-items/application-menu-item-injection-token";
import type { RootComposite } from "../../../common/utils/composite/interfaces"; import type { RootComposite } from "../../../common/utils/composite/interfaces";
import type { Discriminable } from "../../../common/utils/composable-responsibilities/discriminable/discriminable"; import type { Discriminable } from "../../../common/utils/composable-responsibilities/discriminable/discriminable";
import { orderByOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable";
import logErrorInjectable from "../../../common/log-error.injectable"; import logErrorInjectable from "../../../common/log-error.injectable";
import { isShown } from "../../../common/utils/composable-responsibilities/showable/showable"; import { isShown } from "../../../common/utils/composable-responsibilities/showable/showable";
import type { Orderable } from "@k8slens/utilities";
import { byOrderNumber } from "@k8slens/utilities";
export type MenuItemRoot = Discriminable<"root"> & RootComposite<"root">; export type MenuItemRoot = Discriminable<"root"> & RootComposite<"root"> & Orderable;
const applicationMenuItemCompositeInjectable = getInjectable({ const applicationMenuItemCompositeInjectable = getInjectable({
id: "application-menu-item-composite", id: "application-menu-item-composite",
@ -24,40 +23,30 @@ const applicationMenuItemCompositeInjectable = getInjectable({
const menuItems = di.inject(applicationMenuItemsInjectable); const menuItems = di.inject(applicationMenuItemsInjectable);
const logError = di.inject(logErrorInjectable); const logError = di.inject(logErrorInjectable);
return computed((): Composite<ApplicationMenuItemTypes | MenuItemRoot> => { const getComposite = getCompositeFor<ApplicationMenuItemTypes | MenuItemRoot>({
const items = menuItems.get(); getId: (x) => x.id,
getParentId: (x) => x.parentId,
transformChildren: (children) => (
[...children]
.sort(byOrderNumber)
.filter(isShown)
),
handleMissingParentIds: ({ missingParentIds }) => {
const ids = missingParentIds.join('", "');
return pipeline( logError(`[MENU]: cannot render menu item for missing parentIds: "${ids}"`);
[ },
{
parentId: undefined,
id: "root",
kind: "root",
} as const,
...items,
],
getCompositeFor({
getId: (x) => x.id,
getParentId: (x) => x.parentId,
transformChildren: (children) =>
pipeline(
children,
orderByOrderNumber,
(children) => children.filter(isShown),
),
handleMissingParentIds: ({ missingParentIds }) => {
logError(
`[MENU]: cannot render menu item for missing parentIds: "${missingParentIds.join(
'", "',
)}"`,
);
},
}),
);
}); });
return computed(() => getComposite([
{
parentId: undefined,
id: "root",
kind: "root",
orderNumber: -Infinity,
} as const,
...menuItems.get(),
]));
}, },
}); });

View File

@ -8,7 +8,7 @@ import type { SetOptional } from "type-fest";
import type { ChildOfParentComposite, ParentOfChildComposite } from "../../../../common/utils/composite/interfaces"; import type { ChildOfParentComposite, ParentOfChildComposite } from "../../../../common/utils/composite/interfaces";
import type { MaybeShowable } from "../../../../common/utils/composable-responsibilities/showable/showable"; import type { MaybeShowable } from "../../../../common/utils/composable-responsibilities/showable/showable";
import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable"; import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable";
import type { Orderable } from "../../../../common/utils/composable-responsibilities/orderable/orderable"; import type { Orderable } from "@k8slens/utilities";
export interface MayHaveKeyboardShortcut { export interface MayHaveKeyboardShortcut {
keyboardShortcut?: string; keyboardShortcut?: string;

View File

@ -0,0 +1,244 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import { CustomResourceDefinition } from "../../extensions/common-api/k8s-api";
import type { CustomResourceDefinitionStore } from "../../renderer/components/custom-resources/definition.store";
import customResourceDefinitionStoreInjectable from "../../renderer/components/custom-resources/definition.store.injectable";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
describe("cluster - custom resources in sidebar", () => {
let builder: ApplicationBuilder;
let result: RenderResult;
let customResourceDefinitionStore: CustomResourceDefinitionStore;
let customResourceDefinition: CustomResourceDefinition;
beforeEach(async () => {
builder = getApplicationBuilder();
builder.setEnvironmentToClusterFrame();
builder.afterWindowStart(({ windowDi }) => {
customResourceDefinitionStore = windowDi.inject(customResourceDefinitionStoreInjectable);
customResourceDefinition = new CustomResourceDefinition({
apiVersion: "apiextensions.k8s.io/v1",
kind: "CustomResourceDefinition",
metadata: {
name: "some-crd",
selfLink: "/apis/apiextensions.k8s.io/v1/customresourcedefinitions/some-crd",
uid: "some-uid",
resourceVersion: "1",
},
spec: {
group: "some-group",
scope: "Cluster",
names: {
kind: "SomeResource",
plural: "some-resources",
singular: "some-resource",
},
versions: [
{
storage: true,
name: "v1",
served: true,
additionalPrinterColumns: [
{
name: "Some Column",
type: "string",
description: "Some description",
jsonPath: ".spec.someColumn",
},
],
},
],
},
});
});
result = await builder.render();
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows the sidebar", () => {
expect(result.getByTestId("cluster-sidebar")).toBeInTheDocument();
});
it("does not show Custom Resources section", () => {
expect(result.queryByTestId("sidebar-item-custom-resources")).not.toBeInTheDocument();
});
describe("when custom resource exists", () => {
beforeEach(() => {
customResourceDefinitionStore.items.replace([
customResourceDefinition,
]);
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("still does not show Custom Resources sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resources")).not.toBeInTheDocument();
});
describe("when specific custom resource is an allowed resource", () => {
beforeEach(() => {
builder.allowKubeResource({
apiName: "some-resources",
group: "some-group",
});
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows Custom Resources sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resources")).toBeInTheDocument();
});
it("shows Custom Resources sidebar as expandable", () => {
expect(result.getByTestId("sidebar-item-expand-icon-for-custom-resources")).toBeInTheDocument();
});
it("does not show SomeResources sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-group-some-group")).not.toBeInTheDocument();
});
it("does not show Custom Resources Definitions sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-definitions")).not.toBeInTheDocument();
});
describe("when custom resources sidebar item is expanded", () => {
beforeEach(() => {
result.getByTestId("sidebar-item-expand-icon-for-custom-resources").click();
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows Custom Resources sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resources")).toBeInTheDocument();
});
it("shows Custom Resources sidebar as expandable", () => {
expect(result.getByTestId("sidebar-item-expand-icon-for-custom-resources")).toBeInTheDocument();
});
it("shows some-group group sidebar item", () => {
expect(result.getByTestId("sidebar-item-custom-resource-group-some-group")).toBeInTheDocument();
});
it("does not show Custom Resources Definitions sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-definitions")).not.toBeInTheDocument();
});
describe("when custom resources group sidebar item is expanded", () => {
beforeEach(() => {
result.getByTestId("sidebar-item-expand-icon-for-custom-resource-group-some-group").click();
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows some-group group sidebar item", () => {
expect(result.getByTestId("sidebar-item-custom-resource-group-some-group")).toBeInTheDocument();
});
it("shows some-resources group sidebar item", () => {
expect(result.getByTestId("sidebar-item-custom-resource-group-some-group/some-resources")).toBeInTheDocument();
});
});
});
});
describe("when custom resource definitions are an allowed resource", () => {
beforeEach(() => {
builder.allowKubeResource({
apiName: "customresourcedefinitions",
group: "apiextensions.k8s.io",
});
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows Custom Resources sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resources")).toBeInTheDocument();
});
it("shows Custom Resources sidebar as expandable", () => {
expect(result.getByTestId("sidebar-item-expand-icon-for-custom-resources")).toBeInTheDocument();
});
it("does not show SomeResources sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-group-some-group")).not.toBeInTheDocument();
});
it("does not show Custom Resources Definitions sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-definitions")).not.toBeInTheDocument();
});
describe("when custom resources sidebar item is expanded", () => {
beforeEach(() => {
result.getByTestId("sidebar-item-expand-icon-for-custom-resources").click();
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows Custom Resources sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resources")).toBeInTheDocument();
});
it("shows Custom Resources sidebar as expandable", () => {
expect(result.getByTestId("sidebar-item-expand-icon-for-custom-resources")).toBeInTheDocument();
});
it("does not show SomeResources sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-group-some-group")).not.toBeInTheDocument();
});
it("shows Custom Resources Definitions sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resource-definitions")).toBeInTheDocument();
});
});
});
});
describe("when custom resource definitions are an allowed resource", () => {
beforeEach(() => {
builder.allowKubeResource({
apiName: "customresourcedefinitions",
group: "apiextensions.k8s.io",
});
});
it("renders", () => {
expect(result.container).toMatchSnapshot();
});
it("shows Custom Resources sidebar", () => {
expect(result.getByTestId("sidebar-item-custom-resources")).toBeInTheDocument();
});
it("shows Custom Resources sidebar as expandable", () => {
expect(result.getByTestId("sidebar-item-expand-icon-for-custom-resources")).toBeInTheDocument();
});
it("does not show Custom Resources Definitions sidebar", () => {
expect(result.queryByTestId("sidebar-item-custom-resource-definitions")).not.toBeInTheDocument();
});
});
});

View File

@ -5,9 +5,8 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { RenderResult } from "@testing-library/react"; import type { RenderResult } from "@testing-library/react";
import { fireEvent } from "@testing-library/react"; import { fireEvent } from "@testing-library/react";
import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sidebar-items.injectable"; import { runInAction } from "mobx";
import { computed, runInAction } from "mobx";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
@ -23,7 +22,14 @@ describe("cluster - order of sidebar items", () => {
builder.beforeWindowStart(({ windowDi }) => { builder.beforeWindowStart(({ windowDi }) => {
runInAction(() => { runInAction(() => {
windowDi.register(testSidebarItemsInjectable); windowDi.register(
someParentSidebarItemInjectable,
someOtherParentSidebarItemInjectable,
someAnotherParentSidebarItemInjectable,
someChildSidebarItemInjectable,
someOtherChildSidebarItemInjectable,
someAnotherChildSidebarItemInjectable,
);
}); });
}); });
}); });
@ -78,54 +84,74 @@ describe("cluster - order of sidebar items", () => {
}); });
}); });
const testSidebarItemsInjectable = getInjectable({ const someParentSidebarItemInjectable = getInjectable({
id: "some-sidebar-item-injectable", id: "some-parent-sidebar-item",
instantiate: () => ({
instantiate: () => id: "some-parent-id",
computed((): SidebarItemRegistration[] => [ parentId: null,
{ title: "Some parent",
id: "some-parent-id", onClick: noop,
parentId: null, orderNumber: 42,
title: "Some parent", }),
onClick: noop, injectionToken: sidebarItemInjectionToken,
orderNumber: 42, });
},
{ const someOtherParentSidebarItemInjectable = getInjectable({
id: "some-other-parent-id", id: "some-other-parent-sidebar-item",
parentId: null, instantiate: () => ({
title: "Some other parent", id: "some-other-parent-id",
onClick: noop, parentId: null,
orderNumber: 126, title: "Some other parent",
}, onClick: noop,
{ orderNumber: 126,
id: "some-another-parent-id", }),
parentId: null, injectionToken: sidebarItemInjectionToken,
title: "Some another parent", });
onClick: noop,
orderNumber: 84, const someAnotherParentSidebarItemInjectable = getInjectable({
}, id: "some-another-parent-sidebar-item",
{ instantiate: () => ({
id: "some-child-id", id: "some-another-parent-id",
parentId: "some-parent-id", parentId: null,
title: "Some child", title: "Some another parent",
onClick: noop, onClick: noop,
orderNumber: 168, orderNumber: 84,
}, }),
{ injectionToken: sidebarItemInjectionToken,
id: "some-other-child-id", });
parentId: "some-parent-id",
title: "Some other child", const someChildSidebarItemInjectable = getInjectable({
onClick: noop, id: "some-child-sidebar-item",
orderNumber: 252, instantiate: (di) => ({
}, id: "some-child-id",
{ parentId: di.inject(someParentSidebarItemInjectable).id,
id: "some-another-child-id", title: "Some child",
parentId: "some-parent-id", onClick: noop,
title: "Some another child", orderNumber: 168,
onClick: noop, }),
orderNumber: 210, injectionToken: sidebarItemInjectionToken,
}, });
]),
const someOtherChildSidebarItemInjectable = getInjectable({
injectionToken: sidebarItemsInjectionToken, id: "some-other-child-sidebar-item",
instantiate: (di) => ({
id: "some-other-child-id",
parentId: di.inject(someParentSidebarItemInjectable).id,
title: "Some other child",
onClick: noop,
orderNumber: 252,
}),
injectionToken: sidebarItemInjectionToken,
});
const someAnotherChildSidebarItemInjectable = getInjectable({
id: "some-another-child-sidebar-item",
instantiate: (di) => ({
id: "some-another-child-id",
parentId: di.inject(someParentSidebarItemInjectable).id,
title: "Some another child",
onClick: noop,
orderNumber: 210,
}),
injectionToken: sidebarItemInjectionToken,
}); });

View File

@ -8,8 +8,7 @@ import React from "react";
import type { RenderResult } from "@testing-library/react"; import type { RenderResult } from "@testing-library/react";
import { fireEvent } from "@testing-library/react"; import { fireEvent } from "@testing-library/react";
import { routeSpecificComponentInjectionToken } from "../../renderer/routes/route-specific-component-injection-token"; import { routeSpecificComponentInjectionToken } from "../../renderer/routes/route-specific-component-injection-token";
import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sidebar-items.injectable";
import { computed, runInAction } from "mobx"; import { computed, runInAction } from "mobx";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
import routeIsActiveInjectable from "../../renderer/routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../renderer/routes/route-is-active.injectable";
@ -44,9 +43,12 @@ describe("cluster - sidebar and tab navigation for core", () => {
beforeEach(() => { beforeEach(() => {
builder.beforeWindowStart(({ windowDi }) => { builder.beforeWindowStart(({ windowDi }) => {
runInAction(() => { runInAction(() => {
windowDi.register(testRouteInjectable); windowDi.register(
windowDi.register(testRouteComponentInjectable); testRouteInjectable,
windowDi.register(testSidebarItemsInjectable); testRouteComponentInjectable,
someParentSidebarItemInjectable,
someChildSidebarItemInjectable,
);
}); });
}); });
}); });
@ -292,36 +294,36 @@ describe("cluster - sidebar and tab navigation for core", () => {
}); });
}); });
const testSidebarItemsInjectable = getInjectable({ const someParentSidebarItemInjectable = getInjectable({
id: "some-sidebar-items-injectable", id: "some-parent-sidebar-item",
instantiate: () => ({
id: "some-parent-id",
parentId: null,
title: "Some parent",
onClick: noop,
getIcon: () => <div data-testid="some-icon-for-parent" />,
orderNumber: 42,
}),
injectionToken: sidebarItemInjectionToken,
});
const someChildSidebarItemInjectable = getInjectable({
id: "some-child-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(testRouteInjectable); const route = di.inject(testRouteInjectable);
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
const routeIsActive = di.inject(routeIsActiveInjectable, route); const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "some-child-id",
id: "some-parent-id", parentId: di.inject(someParentSidebarItemInjectable).id,
parentId: null, title: "Some child",
title: "Some parent", onClick: () => navigateToRoute(route),
onClick: noop, isActive: routeIsActive,
getIcon: () => <div data-testid="some-icon-for-parent" />, orderNumber: 168,
orderNumber: 42, };
},
{
id: "some-child-id",
parentId: "some-parent-id",
title: "Some child",
onClick: () => navigateToRoute(route),
isActive: routeIsActive,
orderNumber: 42,
},
]);
}, },
injectionToken: sidebarItemInjectionToken,
injectionToken: sidebarItemsInjectionToken,
}); });
const testRouteInjectable = getInjectable({ const testRouteInjectable = getInjectable({

View File

@ -4,9 +4,8 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { RenderResult } from "@testing-library/react"; import type { RenderResult } from "@testing-library/react";
import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sidebar-items.injectable"; import { runInAction } from "mobx";
import { computed, runInAction } from "mobx";
import { routeSpecificComponentInjectionToken } from "../../renderer/routes/route-specific-component-injection-token"; import { routeSpecificComponentInjectionToken } from "../../renderer/routes/route-specific-component-injection-token";
import React from "react"; import React from "react";
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token"; import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
@ -102,18 +101,16 @@ const testSidebarItemsInjectable = getInjectable({
const testRoute = di.inject(testRouteInjectable); const testRoute = di.inject(testRouteInjectable);
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "some-item-id",
id: "some-item-id", parentId: null,
parentId: null, title: "Some item",
title: "Some item", onClick: () => navigateToRoute(testRoute),
onClick: () => navigateToRoute(testRoute), isVisible: testRoute.isEnabled,
isVisible: testRoute.isEnabled, orderNumber: 42,
orderNumber: 42, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });

View File

@ -8,7 +8,7 @@ import type { ChildOfParentComposite, ParentOfChildComposite } from "../../../..
import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable"; import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable";
import type { Labelable } from "../../../../common/utils/composable-responsibilities/labelable/labelable"; import type { Labelable } from "../../../../common/utils/composable-responsibilities/labelable/labelable";
import type { MaybeShowable } from "../../../../common/utils/composable-responsibilities/showable/showable"; import type { MaybeShowable } from "../../../../common/utils/composable-responsibilities/showable/showable";
import type { Orderable } from "../../../../common/utils/composable-responsibilities/orderable/orderable"; import type { Orderable, MaybeOrderable } from "@k8slens/utilities";
import type { GetSeparator } from "../../../../common/utils/add-separator/add-separator"; import type { GetSeparator } from "../../../../common/utils/add-separator/add-separator";
import type { Composite } from "../../../../common/utils/composite/get-composite/get-composite"; import type { Composite } from "../../../../common/utils/composite/get-composite/get-composite";
@ -50,6 +50,7 @@ export type PreferencePage =
& Discriminable<"page"> & Discriminable<"page">
& ParentOfChildComposite & ParentOfChildComposite
& ChildOfParentComposite & ChildOfParentComposite
& MaybeOrderable
& MaybeShowable & MaybeShowable
& RenderableWithSiblings<PreferencePage>; & RenderableWithSiblings<PreferencePage>;
@ -57,6 +58,7 @@ export type PreferenceBlock =
& Discriminable<"block"> & Discriminable<"block">
& ParentOfChildComposite & ParentOfChildComposite
& ChildOfParentComposite & ChildOfParentComposite
& MaybeOrderable
& MaybeShowable & MaybeShowable
& RenderableWithSiblings<PreferenceBlock>; & RenderableWithSiblings<PreferenceBlock>;

View File

@ -8,16 +8,19 @@ import type { RootComposite } from "../../../../common/utils/composite/interface
import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable"; import type { Discriminable } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable";
import type { ChildrenAreSeparated } from "./preference-item-injection-token"; import type { ChildrenAreSeparated } from "./preference-item-injection-token";
import styles from "./preference-tab-root.module.scss"; import styles from "./preference-tab-root.module.scss";
import type { Orderable } from "@k8slens/utilities";
export type PreferenceTabsRoot = export type PreferenceTabsRoot =
& Discriminable<"preference-tabs-root"> & Discriminable<"preference-tabs-root">
& RootComposite & RootComposite
& ChildrenAreSeparated; & ChildrenAreSeparated
& Orderable;
export const preferenceTabsRoot: PreferenceTabsRoot = { export const preferenceTabsRoot: PreferenceTabsRoot = {
kind: "preference-tabs-root" as const, kind: "preference-tabs-root" as const,
id: "preference-tabs", id: "preference-tabs",
parentId: undefined, parentId: undefined,
orderNumber: Infinity,
childSeparator: () => ( childSeparator: () => (
<div className={styles.TabSeparator}> <div className={styles.TabSeparator}>

View File

@ -7,13 +7,12 @@ import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-f
import { computed } from "mobx"; import { computed } from "mobx";
import type { PreferenceItemTypes } from "./preference-item-injection-token"; import type { PreferenceItemTypes } from "./preference-item-injection-token";
import { preferenceItemInjectionToken } from "./preference-item-injection-token"; import { preferenceItemInjectionToken } from "./preference-item-injection-token";
import { pipeline } from "@ogre-tools/fp";
import type { PreferenceTabsRoot } from "./preference-tab-root"; import type { PreferenceTabsRoot } from "./preference-tab-root";
import { preferenceTabsRoot } from "./preference-tab-root"; import { preferenceTabsRoot } from "./preference-tab-root";
import logErrorInjectable from "../../../../common/log-error.injectable"; import logErrorInjectable from "../../../../common/log-error.injectable";
import { isShown } from "../../../../common/utils/composable-responsibilities/showable/showable"; import { isShown } from "../../../../common/utils/composable-responsibilities/showable/showable";
import { orderByOrderNumber } from "../../../../common/utils/composable-responsibilities/orderable/orderable";
import { getCompositeFor } from "../../../../common/utils/composite/get-composite/get-composite"; import { getCompositeFor } from "../../../../common/utils/composite/get-composite/get-composite";
import { byOrderNumber } from "@k8slens/utilities";
const preferencesCompositeInjectable = getInjectable({ const preferencesCompositeInjectable = getInjectable({
id: "preferences-composite", id: "preferences-composite",
@ -27,27 +26,25 @@ const preferencesCompositeInjectable = getInjectable({
getId: (x) => x.id, getId: (x) => x.id,
getParentId: (x) => x.parentId, getParentId: (x) => x.parentId,
handleMissingParentIds: (ids) => { handleMissingParentIds: ({ missingParentIds, availableParentIds }) => {
logError( const missingIds = missingParentIds.join('", "');
`Tried to create preferences, but encountered references to unknown ids: "${ids.missingParentIds.join( const availableIds = availableParentIds.join("\n");
'", "',
)}".\n\nAvailable ids are:\n\n${ids.availableParentIds.join("\n")}`, logError([
); `Tried to create preferences, but encountered references to unknown ids: "${missingIds}".`,
"Available ids are:",
availableIds,
].join("\n\n"));
}, },
transformChildren: (children) => transformChildren: (children) => (
pipeline( children
children.filter(isShown), .filter(isShown)
orderByOrderNumber, .sort(byOrderNumber)
), ),
}); });
return computed(() => return computed(() => getComposite([preferenceTabsRoot, ...preferenceItems.get()]));
pipeline(
[preferenceTabsRoot, ...preferenceItems.get()],
getComposite,
),
);
}, },
}); });

View File

@ -12,7 +12,7 @@ import { backoffCaller, withConcurrencyLimit } from "@k8slens/utilities";
import requestKubeApiResourcesForInjectable from "./request-kube-api-resources-for.injectable"; import requestKubeApiResourcesForInjectable from "./request-kube-api-resources-for.injectable";
import type { AsyncResult } from "@k8slens/utilities"; import type { AsyncResult } from "@k8slens/utilities";
import broadcastConnectionUpdateInjectable from "./broadcast-connection-update.injectable"; import broadcastConnectionUpdateInjectable from "./broadcast-connection-update.injectable";
import { byOrderNumber } from "../../common/utils/composable-responsibilities/orderable/orderable"; import { byOrderNumber } from "@k8slens/utilities";
export type RequestApiResources = (cluster: Cluster) => AsyncResult<KubeApiResource[], Error>; export type RequestApiResources = (cluster: Cluster) => AsyncResult<KubeApiResource[], Error>;

View File

@ -5,7 +5,7 @@
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
import { computed } from "mobx"; import { computed } from "mobx";
import { byOrderNumber } from "../../../../common/utils/composable-responsibilities/orderable/orderable"; import { byOrderNumber } from "@k8slens/utilities";
import type { CatalogEntity } from "../../../api/catalog-entity"; import type { CatalogEntity } from "../../../api/catalog-entity";
import { catalogEntityDetailItemInjectionToken } from "./token"; import { catalogEntityDetailItemInjectionToken } from "./token";

View File

@ -5,39 +5,30 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import type { import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { computed } from "mobx";
import clusterOverviewRouteInjectable from "../../../common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable"; import clusterOverviewRouteInjectable from "../../../common/front-end-routing/routes/cluster/overview/cluster-overview-route.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToClusterOverviewInjectable from "../../../common/front-end-routing/routes/cluster/overview/navigate-to-cluster-overview.injectable"; import navigateToClusterOverviewInjectable from "../../../common/front-end-routing/routes/cluster/overview/navigate-to-cluster-overview.injectable";
const clusterOverviewSidebarItemsInjectable = getInjectable({ const clusterOverviewSidebarItemInjectable = getInjectable({
id: "cluster-overview-sidebar-items", id: "cluster-overview-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(clusterOverviewRouteInjectable); const route = di.inject(clusterOverviewRouteInjectable);
const navigateToClusterOverview = di.inject(navigateToClusterOverviewInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "cluster-overview",
id: "cluster-overview", parentId: null,
parentId: null, title: "Cluster",
title: "Cluster", getIcon: () => <Icon svg="kube" />,
getIcon: () => <Icon svg="kube" />, onClick: di.inject(navigateToClusterOverviewInjectable),
onClick: navigateToClusterOverview, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default clusterOverviewSidebarItemsInjectable; export default clusterOverviewSidebarItemInjectable;

View File

@ -10,6 +10,7 @@ import type { IComputedValue } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import type { NodeStore } from "../nodes/store"; import type { NodeStore } from "../nodes/store";
import type { PodStore } from "../workloads-pods/store"; import type { PodStore } from "../workloads-pods/store";
import { byOrderNumber } from "@k8slens/utilities";
import { TabLayout } from "../layout/tab-layout"; import { TabLayout } from "../layout/tab-layout";
import { Spinner } from "../spinner"; import { Spinner } from "../spinner";
import { ClusterIssues } from "./cluster-issues"; import { ClusterIssues } from "./cluster-issues";
@ -25,7 +26,6 @@ import nodeStoreInjectable from "../nodes/store.injectable";
import enabledMetricsInjectable from "../../api/catalog/entity/metrics-enabled.injectable"; import enabledMetricsInjectable from "../../api/catalog/entity/metrics-enabled.injectable";
import type { ClusterOverviewUIBlock } from "@k8slens/metrics"; import type { ClusterOverviewUIBlock } from "@k8slens/metrics";
import { clusterOverviewUIBlockInjectionToken } from "@k8slens/metrics"; import { clusterOverviewUIBlockInjectionToken } from "@k8slens/metrics";
import { orderByOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
import type { ClusterMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable"; import type { ClusterMetricData } from "../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
import clusterOverviewMetricsInjectable from "./cluster-metrics.injectable"; import clusterOverviewMetricsInjectable from "./cluster-metrics.injectable";
@ -56,10 +56,9 @@ class NonInjectedClusterOverview extends React.Component<Dependencies> {
return ( return (
<> <>
{ {
orderByOrderNumber(this.props.uiBlocks.get()) [...this.props.uiBlocks.get()]
.map((block) => ( .sort(byOrderNumber)
<block.Component key={block.id} /> .map(block => <block.Component key={block.id}/>)
))
} }
<ClusterIssues /> <ClusterIssues />
</> </>

View File

@ -34,7 +34,7 @@ import navigateToDaemonsetsInjectable from "../../../../common/front-end-routing
import navigateToStatefulsetsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/statefulsets/navigate-to-statefulsets.injectable"; import navigateToStatefulsetsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/statefulsets/navigate-to-statefulsets.injectable";
import navigateToJobsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/jobs/navigate-to-jobs.injectable"; import navigateToJobsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/jobs/navigate-to-jobs.injectable";
import navigateToCronJobsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/navigate-to-cron-jobs.injectable"; import navigateToCronJobsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/navigate-to-cron-jobs.injectable";
import navigateToCustomResourcesInjectable from "../../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/navigate-to-custom-resources.injectable"; import navigateToCustomResourcesInjectable from "../../../../common/front-end-routing/routes/cluster/custom-resources/navigate-to-custom-resources.injectable";
import navigateToEntitySettingsInjectable from "../../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable"; import navigateToEntitySettingsInjectable from "../../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
// TODO: Importing from features is not OK. Make commands to comply with Open Closed Principle to allow moving implementation under a feature // TODO: Importing from features is not OK. Make commands to comply with Open Closed Principle to allow moving implementation under a feature

View File

@ -3,36 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import horizontalPodAutoscalersRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable"; import horizontalPodAutoscalersRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/horizontal-pod-autoscalers-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToHorizontalPodAutoscalersInjectable from "../../../common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/navigate-to-horizontal-pod-autoscalers.injectable"; import navigateToHorizontalPodAutoscalersInjectable from "../../../common/front-end-routing/routes/cluster/config/horizontal-pod-autoscalers/navigate-to-horizontal-pod-autoscalers.injectable";
const horizontalPodAutoScalersSidebarItemsInjectable = getInjectable({ const horizontalPodAutoScalersSidebarItemInjectable = getInjectable({
id: "horizontal-pod-auto-scalers-sidebar-items", id: "horizontal-pod-auto-scalers-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(horizontalPodAutoscalersRouteInjectable); const route = di.inject(horizontalPodAutoscalersRouteInjectable);
const navigateToHorizontalPodAutoscalers = di.inject(navigateToHorizontalPodAutoscalersInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "horizontal-pod-auto-scalers",
id: "horizontal-pod-auto-scalers", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "HPA",
title: "HPA", onClick: di.inject(navigateToHorizontalPodAutoscalersInjectable),
onClick: navigateToHorizontalPodAutoscalers, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 50,
orderNumber: 50, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default horizontalPodAutoScalersSidebarItemsInjectable; export default horizontalPodAutoScalersSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import leasesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/leases/leases-route.injectable"; import leasesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/leases/leases-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToLeasesInjectable from "../../../common/front-end-routing/routes/cluster/config/leases/navigate-to-leases.injectable"; import navigateToLeasesInjectable from "../../../common/front-end-routing/routes/cluster/config/leases/navigate-to-leases.injectable";
const leasesSidebarItemsInjectable = getInjectable({ const leasesSidebarItemInjectable = getInjectable({
id: "leases-sidebar-items", id: "leases-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(leasesRouteInjectable); const route = di.inject(leasesRouteInjectable);
const navigateToLeases = di.inject(navigateToLeasesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "leases",
id: "leases", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Leases",
title: "Leases", onClick: di.inject(navigateToLeasesInjectable),
onClick: navigateToLeases, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 80,
orderNumber: 80, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default leasesSidebarItemsInjectable; export default leasesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import limitRangesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable"; import limitRangesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/limit-ranges/limit-ranges-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToLimitRangesInjectable from "../../../common/front-end-routing/routes/cluster/config/limit-ranges/navigate-to-limit-ranges.injectable"; import navigateToLimitRangesInjectable from "../../../common/front-end-routing/routes/cluster/config/limit-ranges/navigate-to-limit-ranges.injectable";
const limitRangesSidebarItemsInjectable = getInjectable({ const limitRangesSidebarItemInjectable = getInjectable({
id: "limit-ranges-sidebar-items", id: "limit-ranges-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(limitRangesRouteInjectable); const route = di.inject(limitRangesRouteInjectable);
const navigateToLimitRanges = di.inject(navigateToLimitRangesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "limit-ranges",
id: "limit-ranges", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Limit Ranges",
title: "Limit Ranges", onClick: di.inject(navigateToLimitRangesInjectable),
onClick: navigateToLimitRanges, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 40,
orderNumber: 40, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default limitRangesSidebarItemsInjectable; export default limitRangesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import configMapsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable"; import configMapsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/config-maps/config-maps-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToConfigMapsInjectable from "../../../common/front-end-routing/routes/cluster/config/config-maps/navigate-to-config-maps.injectable"; import navigateToConfigMapsInjectable from "../../../common/front-end-routing/routes/cluster/config/config-maps/navigate-to-config-maps.injectable";
const configMapsSidebarItemsInjectable = getInjectable({ const configMapsSidebarItemInjectable = getInjectable({
id: "config-maps-sidebar-items", id: "config-maps-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(configMapsRouteInjectable); const route = di.inject(configMapsRouteInjectable);
const navigateToConfigMaps = di.inject(navigateToConfigMapsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "config-maps",
id: "config-maps", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "ConfigMaps",
title: "ConfigMaps", onClick: di.inject(navigateToConfigMapsInjectable),
onClick: navigateToConfigMaps, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default configMapsSidebarItemsInjectable; export default configMapsSidebarItemInjectable;

View File

@ -3,37 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import mutatingWebhookConfigurationsRouteInjectable import mutatingWebhookConfigurationsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable";
from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable"; import navigateToMutatingWebhookConfigurationsInjectable from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable";
import navigateToMutatingWebhookConfigurationsInjectable import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable";
const mutatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({ const mutatingWebhookConfigurationsSidebarItemInjectable = getInjectable({
id: "mutating-webhook-configurations-sidebar-items", id: "mutating-webhook-configurations-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(mutatingWebhookConfigurationsRouteInjectable); const route = di.inject(mutatingWebhookConfigurationsRouteInjectable);
const navigateToPage = di.inject(navigateToMutatingWebhookConfigurationsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "mutating-webhook-configurations",
id: "mutating-webhook-configurations", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Mutating Webhook Configs",
title: "Mutating Webhook Configs", onClick: di.inject(navigateToMutatingWebhookConfigurationsInjectable),
onClick: navigateToPage, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 100,
orderNumber: 100, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default mutatingWebhookConfigurationsSidebarItemsInjectable; export default mutatingWebhookConfigurationsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import podDisruptionBudgetsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable"; import podDisruptionBudgetsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/pod-disruption-budgets/pod-disruption-budgets-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPodDisruptionBudgetsInjectable from "../../../common/front-end-routing/routes/cluster/config/pod-disruption-budgets/navigate-to-pod-disruption-budgets.injectable"; import navigateToPodDisruptionBudgetsInjectable from "../../../common/front-end-routing/routes/cluster/config/pod-disruption-budgets/navigate-to-pod-disruption-budgets.injectable";
const podDisruptionBudgetsSidebarItemsInjectable = getInjectable({ const podDisruptionBudgetsSidebarItemInjectable = getInjectable({
id: "pod-disruption-budgets-sidebar-items", id: "pod-disruption-budgets-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(podDisruptionBudgetsRouteInjectable); const route = di.inject(podDisruptionBudgetsRouteInjectable);
const navigateToPodDisruptionBudgets = di.inject(navigateToPodDisruptionBudgetsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "pod-disruption-budgets",
id: "pod-disruption-budgets", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Pod Disruption Budgets",
title: "Pod Disruption Budgets", onClick: di.inject(navigateToPodDisruptionBudgetsInjectable),
onClick: navigateToPodDisruptionBudgets, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 60,
orderNumber: 60, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default podDisruptionBudgetsSidebarItemsInjectable; export default podDisruptionBudgetsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import priorityClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable"; import priorityClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/priority-classes/priority-classes-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPriorityClassesInjectable from "../../../common/front-end-routing/routes/cluster/config/priority-classes/navigate-to-priority-classes.injectable"; import navigateToPriorityClassesInjectable from "../../../common/front-end-routing/routes/cluster/config/priority-classes/navigate-to-priority-classes.injectable";
const priorityClassesSidebarItemsInjectable = getInjectable({ const priorityClassesSidebarItemInjectable = getInjectable({
id: "priority-classes-sidebar-items", id: "priority-classes-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(priorityClassesRouteInjectable); const route = di.inject(priorityClassesRouteInjectable);
const navigateToPriorityClasses = di.inject(navigateToPriorityClassesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "priority-classes",
id: "priority-classes", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Priority Classes",
title: "Priority Classes", onClick: di.inject(navigateToPriorityClassesInjectable),
onClick: navigateToPriorityClasses, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 70,
orderNumber: 70, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default priorityClassesSidebarItemsInjectable; export default priorityClassesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import resourceQuotasRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable"; import resourceQuotasRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/resource-quotas/resource-quotas-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToResourceQuotasInjectable from "../../../common/front-end-routing/routes/cluster/config/resource-quotas/navigate-to-resource-quotas.injectable"; import navigateToResourceQuotasInjectable from "../../../common/front-end-routing/routes/cluster/config/resource-quotas/navigate-to-resource-quotas.injectable";
const resourceQuotasSidebarItemsInjectable = getInjectable({ const resourceQuotasSidebarItemInjectable = getInjectable({
id: "resource-quotas-sidebar-items", id: "resource-quotas-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(resourceQuotasRouteInjectable); const route = di.inject(resourceQuotasRouteInjectable);
const navigateToResourceQuotas = di.inject(navigateToResourceQuotasInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "resource-quotas",
id: "resource-quotas", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Resource Quotas",
title: "Resource Quotas", onClick: di.inject(navigateToResourceQuotasInjectable),
onClick: navigateToResourceQuotas, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 30,
orderNumber: 30, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default resourceQuotasSidebarItemsInjectable; export default resourceQuotasSidebarItemInjectable;

View File

@ -1,38 +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 { computed } from "mobx";
import runtimeClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToRuntimeClassesInjectable from "../../../common/front-end-routing/routes/cluster/config/runtime-classes/navigate-to-runtime-classes.injectable";
const runtimeClassesSidebarItemsInjectable = getInjectable({
id: "runtime-classes-sidebar-items",
instantiate: (di) => {
const route = di.inject(runtimeClassesRouteInjectable);
const navigateToRuntimeClasses = di.inject(navigateToRuntimeClassesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [
{
id: "runtime-classes",
parentId: configSidebarItemId,
title: "Runtime Classes",
onClick: navigateToRuntimeClasses,
isActive: routeIsActive,
isVisible: route.isEnabled,
orderNumber: 70,
},
]);
},
injectionToken: sidebarItemsInjectionToken,
});
export default runtimeClassesSidebarItemsInjectable;

View File

@ -0,0 +1,33 @@
/**
* 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 runtimeClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/runtime-classes/runtime-classes-route.injectable";
import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToRuntimeClassesInjectable from "../../../common/front-end-routing/routes/cluster/config/runtime-classes/navigate-to-runtime-classes.injectable";
const runtimeClassesSidebarItemInjectable = getInjectable({
id: "runtime-classes-sidebar-item",
instantiate: (di) => {
const route = di.inject(runtimeClassesRouteInjectable);
return {
id: "runtime-classes",
parentId: di.inject(configSidebarItemInjectable).id,
title: "Runtime Classes",
onClick: di.inject(navigateToRuntimeClassesInjectable),
isActive: di.inject(routeIsActiveInjectable, route),
isVisible: route.isEnabled,
orderNumber: 70,
};
},
injectionToken: sidebarItemInjectionToken,
});
export default runtimeClassesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import secretsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable"; import secretsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/secrets/secrets-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToSecretsInjectable from "../../../common/front-end-routing/routes/cluster/config/secrets/navigate-to-secrets.injectable"; import navigateToSecretsInjectable from "../../../common/front-end-routing/routes/cluster/config/secrets/navigate-to-secrets.injectable";
const secretsSidebarItemsInjectable = getInjectable({ const secretsSidebarItemInjectable = getInjectable({
id: "secrets-sidebar-items", id: "secrets-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(secretsRouteInjectable); const route = di.inject(secretsRouteInjectable);
const navigateToSecrets = di.inject(navigateToSecretsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "secrets",
id: "secrets", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Secrets",
title: "Secrets", onClick: di.inject(navigateToSecretsInjectable),
onClick: navigateToSecrets, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default secretsSidebarItemsInjectable; export default secretsSidebarItemInjectable;

View File

@ -3,37 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import validatingWebhookConfigurationsRouteInjectable import validatingWebhookConfigurationsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/validating-webhook-configurations-route.injectable";
from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/validating-webhook-configurations-route.injectable"; import navigateToValidatingWebhookConfigurationsInjectable from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/navigate-to-validating-webhook-configurations.injectable";
import navigateToValidatingWebhookConfigurationsInjectable import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/navigate-to-validating-webhook-configurations.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable";
const validatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({ const validatingWebhookConfigurationsSidebarItemInjectable = getInjectable({
id: "validating-webhook-configurations-sidebar-items", id: "validating-webhook-configurations-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(validatingWebhookConfigurationsRouteInjectable); const route = di.inject(validatingWebhookConfigurationsRouteInjectable);
const navigateToPage = di.inject(navigateToValidatingWebhookConfigurationsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "validating-webhook-configurations",
id: "validating-webhook-configurations", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "Validating Webhook Configs",
title: "Validating Webhook Configs", onClick: di.inject(navigateToValidatingWebhookConfigurationsInjectable),
onClick: navigateToPage, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 100,
orderNumber: 100, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default validatingWebhookConfigurationsSidebarItemsInjectable; export default validatingWebhookConfigurationsSidebarItemInjectable;

View File

@ -3,36 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import verticalPodAutoscalersRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/vertical-pod-autoscalers/vertical-pod-autoscalers-route.injectable"; import verticalPodAutoscalersRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/vertical-pod-autoscalers/vertical-pod-autoscalers-route.injectable";
import { configSidebarItemId } from "../config/config-sidebar-items.injectable"; import configSidebarItemInjectable from "../config/config-sidebar-items.injectable";
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToVerticalPodAutoscalersInjectable from "../../../common/front-end-routing/routes/cluster/config/vertical-pod-autoscalers/navigate-to-vertical-pod-autoscalers.injectable"; import navigateToVerticalPodAutoscalersInjectable from "../../../common/front-end-routing/routes/cluster/config/vertical-pod-autoscalers/navigate-to-vertical-pod-autoscalers.injectable";
const verticalPodAutoScalersSidebarItemsInjectable = getInjectable({ const verticalPodAutoScalersSidebarItemInjectable = getInjectable({
id: "vertical-pod-auto-scalers-sidebar-items", id: "vertical-pod-auto-scalers-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(verticalPodAutoscalersRouteInjectable); const route = di.inject(verticalPodAutoscalersRouteInjectable);
const navigateToVerticalPodAutoscalers = di.inject(navigateToVerticalPodAutoscalersInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "vertical-pod-auto-scalers",
id: "vertical-pod-auto-scalers", parentId: di.inject(configSidebarItemInjectable).id,
parentId: configSidebarItemId, title: "VPA",
title: "VPA", onClick: di.inject(navigateToVerticalPodAutoscalersInjectable),
onClick: navigateToVerticalPodAutoscalers, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 50,
orderNumber: 50, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default verticalPodAutoScalersSidebarItemsInjectable; export default verticalPodAutoScalersSidebarItemInjectable;

View File

@ -5,32 +5,22 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import type { import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { computed } from "mobx";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
export const configSidebarItemId = "config"; const configSidebarItemInjectable = getInjectable({
id: "config-sidebar-item",
const configSidebarItemsInjectable = getInjectable({ instantiate: () => ({
id: "config-sidebar-items", id: "config",
parentId: null,
title: "Config",
getIcon: () => <Icon material="list" />,
onClick: noop,
orderNumber: 40,
}),
instantiate: () => injectionToken: sidebarItemInjectionToken,
computed((): SidebarItemRegistration[] => [
{
id: configSidebarItemId,
parentId: null,
title: "Config",
getIcon: () => <Icon material="list" />,
onClick: noop,
orderNumber: 40,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default configSidebarItemsInjectable; export default configSidebarItemInjectable;

View File

@ -4,7 +4,7 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token"; import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token";
import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable"; import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resource-definitions.injectable";
import { CustomResourceDefinitions } from "./crd-list"; import { CustomResourceDefinitions } from "./crd-list";
const crdListRouteComponentInjectable = getInjectable({ const crdListRouteComponentInjectable = getInjectable({

View File

@ -0,0 +1,86 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { SidebarItemRegistration } from "@k8slens/cluster-sidebar";
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type { CustomResourceDefinition } from "@k8slens/kube-object";
import { iter, noop, computedAnd } from "@k8slens/utilities";
import { getInjectable } from "@ogre-tools/injectable";
import { matches } from "lodash";
import { computed } from "mobx";
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources-route.injectable";
import navigateToCustomResourcesInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/navigate-to-custom-resources.injectable";
import { shouldShowResourceInjectionToken } from "../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import routePathParametersInjectable from "../../routes/route-path-parameters.injectable";
import customResourcesSidebarItemInjectable from "./custom-resources-sidebar-items.injectable";
import customResourceDefinitionsInjectable from "./custom-resources.injectable";
const customResourceDefinitionGroupsSidebarItemsComputedInjectable = getInjectable({
id: "custom-resource-definition-groups-sidebar-items-computed",
instantiate: (di) => {
const customResourceDefinitions = di.inject(customResourceDefinitionsInjectable);
const navigateToCustomResources = di.inject(navigateToCustomResourcesInjectable);
const customResourcesRoute = di.inject(customResourcesRouteInjectable);
const pathParameters = di.inject(routePathParametersInjectable, customResourcesRoute);
const toCustomResourceGroupToSidebarItems = ([group, definitions]: [string, CustomResourceDefinition[]], index: number) => {
const customResourceGroupSidebarItem = getInjectable({
id: `custom-resource-group-${group}-sidebar-item`,
instantiate: (di): SidebarItemRegistration => ({
id: `custom-resource-group-${group}`,
parentId: di.inject(customResourcesSidebarItemInjectable).id,
onClick: noop,
title: group,
orderNumber: 10 * index,
}),
injectionToken: sidebarItemInjectionToken,
});
const customResourceSidebarItems = definitions.map((definition, index) => {
const parameters = {
group: definition.getGroup(),
name: definition.getPluralName(),
};
return getInjectable({
id: `custom-resource-group-${group}/${definition.getPluralName()}-sidebar-item`,
instantiate: (di): SidebarItemRegistration => ({
id: `custom-resource-group-${group}/${definition.getPluralName()}`,
parentId: di.inject(customResourceGroupSidebarItem).id,
onClick: () => navigateToCustomResources(parameters),
title: definition.getResourceKind(),
isActive: computedAnd(
di.inject(routeIsActiveInjectable, customResourcesRoute),
computed(() => matches(parameters)(pathParameters.get())),
),
isVisible: di.inject(shouldShowResourceInjectionToken, {
group: definition.getGroup(),
apiName: definition.getPluralName(),
}),
orderNumber: 10 * index,
}),
injectionToken: sidebarItemInjectionToken,
});
});
return [
customResourceGroupSidebarItem,
...customResourceSidebarItems,
];
};
return computed(() => {
const customResourceDefinitionGroups = (
iter.chain(customResourceDefinitions.get().values())
.map((crd) => [crd.getGroup(), crd] as const)
.toMap()
);
return Array.from(customResourceDefinitionGroups.entries(), toCustomResourceGroupToSidebarItems)
.flat();
});
},
});
export default customResourceDefinitionGroupsSidebarItemsComputedInjectable;

View File

@ -0,0 +1,29 @@
/**
* 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 { reaction } from "mobx";
import { injectableDifferencingRegistratorWith } from "../../../common/utils/registrator-helper";
import { beforeClusterFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens";
import customResourceDefinitionGroupsSidebarItemsComputedInjectable from "./custom-resource-definition-groups-sidebar-items-computed.injectable";
const customResourceDefinitionGroupsSidebarItemsRegistratorInjectable = getInjectable({
id: "custom-resource-definition-groups-sidebar-items-registrator",
instantiate: (di) => ({
run: () => {
const sidebarItems = di.inject(customResourceDefinitionGroupsSidebarItemsComputedInjectable);
const injectableDifferencingRegistrator = injectableDifferencingRegistratorWith(di);
reaction(
() => sidebarItems.get(),
injectableDifferencingRegistrator,
{ fireImmediately: true },
);
},
}),
injectionToken: beforeClusterFrameStartsSecondInjectionToken,
});
export default customResourceDefinitionGroupsSidebarItemsRegistratorInjectable;

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { getInjectable } from "@ogre-tools/injectable";
import customResourceDefinitionsRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resource-definitions.injectable";
import navigateToCustomResourcesInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/navigate-to-custom-resources.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import customResourcesSidebarItemInjectable from "./custom-resources-sidebar-items.injectable";
const customResourceDefinitionsSidebarItemInjectable = getInjectable({
id: "custom-resource-definitions-sidebar-item",
instantiate: (di) => {
const customResourceDefinitionsRoute = di.inject(customResourceDefinitionsRouteInjectable);
return {
id: "custom-resource-definitions",
parentId: di.inject(customResourcesSidebarItemInjectable).id,
title: "Definitions",
onClick: di.inject(navigateToCustomResourcesInjectable),
isActive: di.inject(routeIsActiveInjectable, customResourceDefinitionsRoute),
isVisible: customResourceDefinitionsRoute.isEnabled,
orderNumber: 10,
};
},
injectionToken: sidebarItemInjectionToken,
});
export default customResourceDefinitionsSidebarItemInjectable;

View File

@ -1,59 +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 { noop } from "lodash/fp";
import { computed } from "mobx";
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon";
import React from "react";
import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable";
import sidebarItemsForDefinitionGroupsInjectable from "./sidebar-items-for-definition-groups.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToCrdListInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/navigate-to-crd-list.injectable";
const customResourceSidebarItemsInjectable = getInjectable({
id: "custom-resource-sidebar-items",
instantiate: (di) => {
const navigateToCrdList = di.inject(navigateToCrdListInjectable);
const crdListRoute = di.inject(crdListRouteInjectable);
const crdListRouteIsActive = di.inject(routeIsActiveInjectable, crdListRoute);
const definitionGroupSidebarItems = di.inject(sidebarItemsForDefinitionGroupsInjectable);
return computed((): SidebarItemRegistration[] => {
const definitionsItem = {
id: "definitions",
parentId: "custom-resources",
title: "Definitions",
onClick: navigateToCrdList,
isActive: crdListRouteIsActive,
isVisible: crdListRoute.isEnabled,
orderNumber: 10,
};
const childrenAndGrandChildren = computed(() => [
definitionsItem,
...definitionGroupSidebarItems.get(),
]);
const parentItem: SidebarItemRegistration = {
id: "custom-resources",
parentId: null,
title: "Custom Resources",
getIcon: () => <Icon material="extension" />,
onClick: noop,
isVisible: computed(() => childrenAndGrandChildren.get().some(item => item.isVisible?.get())),
orderNumber: 110,
};
return [parentItem, definitionsItem, ...definitionGroupSidebarItems.get()];
});
},
injectionToken: sidebarItemsInjectionToken,
});
export default customResourceSidebarItemsInjectable;

View File

@ -4,7 +4,7 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { CustomResources } from "./crd-resources"; import { CustomResources } from "./crd-resources";
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable"; import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources-route.injectable";
import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token"; import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token";
const customResourcesRouteComponentInjectable = getInjectable({ const customResourcesRouteComponentInjectable = getInjectable({

View File

@ -5,7 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { computed } from "mobx";
import routePathParametersInjectable from "../../routes/route-path-parameters.injectable"; import routePathParametersInjectable from "../../routes/route-path-parameters.injectable";
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable"; import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources-route.injectable";
const customResourcesRouteParametersInjectable = getInjectable({ const customResourcesRouteParametersInjectable = getInjectable({
id: "custom-resources-route-parameters", id: "custom-resources-route-parameters",

View File

@ -0,0 +1,24 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { noop } from "@k8slens/utilities";
import { getInjectable } from "@ogre-tools/injectable";
import React from "react";
import { Icon } from "../icon";
const customResourcesSidebarItemInjectable = getInjectable({
id: "custom-resources-sidebar-item",
instantiate: () => ({
id: "custom-resources",
parentId: null,
title: "Custom Resources",
getIcon: () => <Icon material="extension" />,
onClick: noop,
orderNumber: 110,
}),
injectionToken: sidebarItemInjectionToken,
});
export default customResourcesSidebarItemInjectable;

View File

@ -1,81 +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 { computed } from "mobx";
import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable";
import customResourceDefinitionsInjectable from "./custom-resources.injectable";
import { groupBy, matches, noop, some, toPairs } from "lodash/fp";
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable";
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToCustomResourcesInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/navigate-to-custom-resources.injectable";
import routePathParametersInjectable from "../../routes/route-path-parameters.injectable";
const sidebarItemsForDefinitionGroupsInjectable = getInjectable({
id: "sidebar-items-for-definition-groups",
instantiate: (di) => {
const customResourceDefinitions = di.inject(
customResourceDefinitionsInjectable,
);
const crdRoute = di.inject(customResourcesRouteInjectable);
const crdRouteIsActive = di.inject(routeIsActiveInjectable, crdRoute);
const crdListRoute = di.inject(crdListRouteInjectable);
const pathParameters = di.inject(routePathParametersInjectable, crdRoute);
const navigateToCustomResources = di.inject(navigateToCustomResourcesInjectable);
return computed((): SidebarItemRegistration[] => {
const definitions = customResourceDefinitions.get();
const groupedCrds = toPairs(
groupBy((crd) => crd.getGroup(), definitions),
);
return groupedCrds.flatMap(([group, definitions]) => {
const childItems = definitions.map((crd) => {
const title = crd.getResourceKind();
const crdPathParameters = {
group: crd.getGroup(),
name: crd.getPluralName(),
};
return {
id: `custom-resource-definition-group-${group}-crd-${crd.getId()}`,
parentId: `custom-resource-definition-group-${group}`,
title,
onClick: () => navigateToCustomResources(crdPathParameters),
isActive: computed(
() =>
crdRouteIsActive.get() &&
matches(crdPathParameters, pathParameters.get()),
),
isVisible: crdListRoute.isEnabled,
orderNumber: 10,
};
});
return [
{
id: `custom-resource-definition-group-${group}`,
parentId: "custom-resources",
title: group,
onClick: noop,
isVisible: computed(() => some(item => item.isVisible.get(), childItems)),
orderNumber: 10,
},
...childItems,
];
});
});
},
});
export default sidebarItemsForDefinitionGroupsInjectable;

View File

@ -4,7 +4,7 @@
*/ */
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { action } from "mobx"; import { action } from "mobx";
import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable"; import { byOrderNumber } from "@k8slens/utilities";
import type { CatalogEntity } from "../../api/catalog-entity"; import type { CatalogEntity } from "../../api/catalog-entity";
import { observableHistoryInjectionToken } from "@k8slens/routing"; import { observableHistoryInjectionToken } from "@k8slens/routing";
import type { RegisteredEntitySetting } from "./extension-registrator.injectable"; import type { RegisteredEntitySetting } from "./extension-registrator.injectable";

View File

@ -5,7 +5,7 @@
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
import { computed } from "mobx"; import { computed } from "mobx";
import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable"; import { byOrderNumber } from "@k8slens/utilities";
import type { CatalogEntity } from "../../api/catalog-entity"; import type { CatalogEntity } from "../../api/catalog-entity";
import { entitySettingInjectionToken } from "./token"; import { entitySettingInjectionToken } from "./token";

View File

@ -3,42 +3,33 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import React from "react"; import React from "react";
import type { import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import eventsRouteInjectable from "../../../common/front-end-routing/routes/cluster/events/events-route.injectable"; import eventsRouteInjectable from "../../../common/front-end-routing/routes/cluster/events/events-route.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToEventsInjectable from "../../../common/front-end-routing/routes/cluster/events/navigate-to-events.injectable"; import navigateToEventsInjectable from "../../../common/front-end-routing/routes/cluster/events/navigate-to-events.injectable";
const eventsSidebarItemsInjectable = getInjectable({ const eventsSidebarItemInjectable = getInjectable({
id: "events-sidebar-items", id: "events-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(eventsRouteInjectable); const route = di.inject(eventsRouteInjectable);
const navigateToEvents = di.inject(navigateToEventsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "events",
id: "events", parentId: null,
parentId: null, getIcon: () => <Icon material="access_time" />,
getIcon: () => <Icon material="access_time" />, title: "Events",
title: "Events", onClick: di.inject(navigateToEventsInjectable),
onClick: navigateToEvents, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 80,
orderNumber: 80, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default eventsSidebarItemsInjectable; export default eventsSidebarItemInjectable;

View File

@ -3,35 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import helmChartsRouteInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/helm-charts-route.injectable"; import helmChartsRouteInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/helm-charts-route.injectable";
import { helmSidebarItemId } from "../helm/helm-sidebar-items.injectable"; import helmSidebarItemInjectable from "../helm/helm-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable"; import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
const helmChartsSidebarItemsInjectable = getInjectable({ const helmChartsSidebarItemInjectable = getInjectable({
id: "helm-charts-sidebar-items", id: "helm-charts-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(helmChartsRouteInjectable); const route = di.inject(helmChartsRouteInjectable);
const navigateToHelmCharts = di.inject(navigateToHelmChartsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "charts",
id: "charts", parentId: di.inject(helmSidebarItemInjectable).id,
parentId: helmSidebarItemId, title: "Charts",
title: "Charts", onClick: di.inject(navigateToHelmChartsInjectable),
onClick: navigateToHelmCharts, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default helmChartsSidebarItemsInjectable; export default helmChartsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import helmReleasesRouteInjectable from "../../../common/front-end-routing/routes/cluster/helm/releases/helm-releases-route.injectable"; import helmReleasesRouteInjectable from "../../../common/front-end-routing/routes/cluster/helm/releases/helm-releases-route.injectable";
import { helmSidebarItemId } from "../helm/helm-sidebar-items.injectable"; import helmSidebarItemInjectable from "../helm/helm-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToHelmReleasesInjectable from "../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable"; import navigateToHelmReleasesInjectable from "../../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable";
const helmReleasesSidebarItemsInjectable = getInjectable({ const helmReleasesSidebarItemInjectable = getInjectable({
id: "helm-releases-sidebar-items", id: "helm-releases-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(helmReleasesRouteInjectable); const route = di.inject(helmReleasesRouteInjectable);
const navigateToHelmReleases = di.inject(navigateToHelmReleasesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "releases",
id: "releases", parentId: di.inject(helmSidebarItemInjectable).id,
parentId: helmSidebarItemId, title: "Releases",
title: "Releases", onClick: di.inject(navigateToHelmReleasesInjectable),
onClick: navigateToHelmReleases, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default helmReleasesSidebarItemsInjectable; export default helmReleasesSidebarItemInjectable;

View File

@ -3,34 +3,24 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import React from "react"; import React from "react";
import type { import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
export const helmSidebarItemId = "helm"; const helmSidebarItemInjectable = getInjectable({
id: "helm-sidebar-item",
const helmSidebarItemsInjectable = getInjectable({ instantiate: () => ({
id: "helm-sidebar-items", id: "helm",
parentId: null,
getIcon: () => <Icon svg="helm" />,
title: "Helm",
onClick: noop,
orderNumber: 90,
}),
instantiate: () => injectionToken: sidebarItemInjectionToken,
computed((): SidebarItemRegistration[] => [
{
id: helmSidebarItemId,
parentId: null,
getIcon: () => <Icon svg="helm" />,
title: "Helm",
onClick: noop,
orderNumber: 90,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default helmSidebarItemsInjectable; export default helmSidebarItemInjectable;

View File

@ -5,8 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import React from "react"; import React from "react";
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
import type { SidebarItemRegistration } from "./sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "./sidebar-items.injectable";
import { computed } from "mobx"; import { computed } from "mobx";
import routesInjectable from "../../routes/routes.injectable"; import routesInjectable from "../../routes/routes.injectable";
import { matches, noop } from "lodash/fp"; import { matches, noop } from "lodash/fp";
@ -25,71 +24,66 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
const routes = di.inject(routesInjectable); const routes = di.inject(routesInjectable);
const extensionShouldBeEnabledForClusterFrame = di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension); const extensionShouldBeEnabledForClusterFrame = di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
const sidebarItemsForExtensionInjectable = getInjectable({ return computed(() => {
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}`, const extensionRoutes = routes.get().filter(matches({ extension }));
injectionToken: sidebarItemsInjectionToken,
instantiate: (di) => { return extension.clusterPageMenus.map((registration) => {
return computed(() => { const targetRoutePath = getExtensionRoutePath(
const extensionRoutes = routes.get().filter(matches({ extension })); extension,
registration.target?.pageId,
);
return extension.clusterPageMenus.map((registration) => { const targetRoute = extensionRoutes.find(
const targetRoutePath = getExtensionRoutePath( matches({ path: targetRoutePath }),
extension, );
registration.target?.pageId,
);
const targetRoute = extensionRoutes.find( const isVisible = computed(() => {
matches({ path: targetRoutePath }), if (!extensionShouldBeEnabledForClusterFrame.value.get()) {
); return false;
}
const isVisible = computed(() => { if (!registration.visible) {
if (!extensionShouldBeEnabledForClusterFrame.value.get()) { return true;
return false; }
}
if (!registration.visible) { return registration.visible.get();
return true;
}
return registration.visible.get();
});
const res: SidebarItemRegistration = {
id: `${extension.sanitizedExtensionId}-${registration.id}`,
orderNumber: registration.orderNumber ?? 9999,
parentId: registration.parentId
? `${extension.sanitizedExtensionId}-${registration.parentId}`
: null,
isVisible,
title: registration.title,
getIcon: registration.components.Icon
? () => <registration.components.Icon />
: undefined,
...(targetRoute
? {
onClick: () => navigateToRoute(targetRoute),
isActive: di.inject(
routeIsActiveInjectable,
targetRoute,
),
}
: { onClick: noop }),
};
return res;
});
}); });
},
});
return [ const id = registration.id ?
sidebarItemsForExtensionInjectable, `${extension.sanitizedExtensionId}-${registration.id}`
]; : extension.sanitizedExtensionId;
return getInjectable({
id: `${id}-sidebar-item`,
instantiate: () => ({
id,
orderNumber: registration.orderNumber ?? 9999,
parentId: registration.parentId
? `${extension.sanitizedExtensionId}-${registration.parentId}`
: null,
isVisible,
title: registration.title,
getIcon: registration.components.Icon
? () => <registration.components.Icon />
: undefined,
...(targetRoute
? {
onClick: () => navigateToRoute(targetRoute),
isActive: di.inject(
routeIsActiveInjectable,
targetRoute,
),
}
: { onClick: noop }),
}),
injectionToken: sidebarItemInjectionToken,
});
});
});
}, },
injectionToken: extensionRegistratorInjectionToken, injectionToken: extensionRegistratorInjectionToken,

View File

@ -8,7 +8,7 @@ import { observer } from "mobx-react";
import React from "react"; import React from "react";
import siblingTabsInjectable from "../../routes/sibling-tabs.injectable"; import siblingTabsInjectable from "../../routes/sibling-tabs.injectable";
import { TabLayout } from "./tab-layout-2"; import { TabLayout } from "./tab-layout-2";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable"; import type { HierarchicalSidebarItem } from "@k8slens/cluster-sidebar";
import type { StrictReactNode } from "@k8slens/utilities"; import type { StrictReactNode } from "@k8slens/utilities";
interface SiblingTabLayoutProps { interface SiblingTabLayoutProps {

View File

@ -6,15 +6,13 @@
import styles from "./sidebar-items.module.scss"; import styles from "./sidebar-items.module.scss";
import React from "react"; import React from "react";
import { computed, makeObservable } from "mobx";
import { cssNames } from "@k8slens/utilities";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { NavLink } from "react-router-dom"; import { NavLink } from "react-router-dom";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable"; import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
import sidebarStorageInjectable from "./sidebar-storage/sidebar-storage.injectable"; import sidebarStorageInjectable from "./sidebar-storage/sidebar-storage.injectable";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable"; import type { HierarchicalSidebarItem } from "@k8slens/cluster-sidebar";
import type { StorageLayer } from "../../utils/storage-helper"; import type { StorageLayer } from "../../utils/storage-helper";
interface Dependencies { interface Dependencies {
@ -25,97 +23,73 @@ export interface SidebarItemProps {
item: HierarchicalSidebarItem; item: HierarchicalSidebarItem;
} }
@observer const NonInjectedSidebarItem = observer((props: SidebarItemProps & Dependencies) => {
class NonInjectedSidebarItem extends React.Component< const { item, sidebarStorage } = props;
SidebarItemProps & Dependencies const id = item.id;
> { const expanded = sidebarStorage.get().expanded[id] ?? false;
static displayName = "SidebarItem"; const isExpandable = item.children.length > 0 && item.children.some(item => item.isVisible.get());
const isActive = item.isActive.get();
constructor(props: SidebarItemProps & Dependencies) { const toggleExpand = () => {
super(props); sidebarStorage.merge((draft) => {
makeObservable(this); draft.expanded[id] = !draft.expanded[id];
}
get id(): string {
return this.item.id;
}
@computed get expanded(): boolean {
return Boolean(this.props.sidebarStorage.get().expanded[this.id]);
}
@computed get isExpandable(): boolean {
return this.props.item.children.length > 0;
}
@computed get isActive(): boolean {
return this.props.item.isActive.get();
}
get item() {
return this.props.item;
}
toggleExpand = () => {
this.props.sidebarStorage.merge((draft) => {
draft.expanded[this.id] = !draft.expanded[this.id];
}); });
}; };
const renderSubMenu = () => {
renderSubMenu() {
const { isExpandable, expanded } = this;
if (!isExpandable || !expanded) { if (!isExpandable || !expanded) {
return null; return null;
} }
return ( return (
<ul className={cssNames(styles.subMenu, { [styles.active]: this.isActive })}> <div className={styles.subMenu}>
{this.props.item.children.map(item => <SidebarItem key={item.id} item={item} />)} {item.children.map((child) => (
</ul> <SidebarItem key={child.id} item={child} />
); ))}
}
render() {
return (
<div
className={styles.SidebarItem}
data-testid={`sidebar-item-${this.id}`}
data-is-active-test={this.isActive}
data-parent-id-test={this.item.parentId}
>
<NavLink
to={""}
isActive={() => this.isActive}
className={styles.navItem}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
if (this.isExpandable) {
this.toggleExpand();
} else {
this.item.onClick();
}
}}
data-testid={`sidebar-item-link-for-${this.id}`}
>
{this.item.getIcon?.()}
<span>{this.item.title}</span>
{this.isExpandable && (
<Icon
className={styles.expandIcon}
material={
this.expanded ? "keyboard_arrow_up" : "keyboard_arrow_down"
}
/>
)}
</NavLink>
{this.renderSubMenu()}
</div> </div>
); );
};
if (!item.isVisible.get()) {
return null;
} }
}
return (
<div
className={styles.SidebarItem}
data-testid={`sidebar-item-${id}`}
data-is-active-test={isActive}
data-parent-id-test={item.parentId}
>
<NavLink
to={""}
isActive={() => isActive}
className={styles.navItem}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
if (isExpandable) {
toggleExpand();
} else {
item.onClick();
}
}}
data-testid={`sidebar-item-link-for-${id}`}
>
{item.getIcon?.()}
<span>{item.title}</span>
{isExpandable && (
<Icon
className={styles.expandIcon}
material={expanded ? "keyboard_arrow_up" : "keyboard_arrow_down"}
data-testid={`sidebar-item-expand-icon-for-${id}`}
/>
)}
</NavLink>
{renderSubMenu()}
</div>
);
});
export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonInjectedSidebarItem, { export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonInjectedSidebarItem, {
getProps: (di, props) => ({ getProps: (di, props) => ({
@ -123,3 +97,5 @@ export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonIn
sidebarStorage: di.inject(sidebarStorageInjectable), sidebarStorage: di.inject(sidebarStorageInjectable),
}), }),
}); });
SidebarItem.displayName = "SidebarItem";

View File

@ -1,80 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import { computed } from "mobx";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable";
import type { SetRequired } from "type-fest";
import type { StrictReactNode } from "@k8slens/utilities";
export interface SidebarItemRegistration {
id: string;
parentId: string | null;
title: StrictReactNode;
onClick: () => void;
getIcon?: () => StrictReactNode;
isActive?: IComputedValue<boolean>;
isVisible?: IComputedValue<boolean>;
orderNumber: number;
}
export const sidebarItemsInjectionToken = getInjectionToken<
IComputedValue<SidebarItemRegistration[]>
>({ id: "sidebar-items-injection-token" });
export interface HierarchicalSidebarItem extends SetRequired<SidebarItemRegistration, "isActive" | "isVisible"> {
children: HierarchicalSidebarItem[];
}
const sidebarItemsInjectable = getInjectable({
id: "sidebar-items",
instantiate: (di) => {
const computedInjectMany = di.inject(computedInjectManyInjectable);
const sidebarItemRegistrations = computedInjectMany(sidebarItemsInjectionToken);
return computed((): HierarchicalSidebarItem[] => {
const registrations = sidebarItemRegistrations
.get()
.flatMap(reg => reg.get());
const getSidebarItemsHierarchy = (registrations: SidebarItemRegistration[]) => {
const impl = (parentId: string | null): HierarchicalSidebarItem[] => (
registrations
.filter((item) => item.parentId === parentId)
.map(({
isActive = computed(() => false),
isVisible = computed(() => true),
...registration
}) => {
const children = impl(registration.id);
return {
...registration,
children,
isVisible,
isActive: computed(() => {
if (children.length === 0) {
return isActive.get();
}
return children.some(child => child.isActive.get());
}),
};
})
.filter(({ isVisible }) => isVisible.get())
.sort(byOrderNumber)
);
return impl(null);
};
return getSidebarItemsHierarchy(registrations);
});
},
});
export default sidebarItemsInjectable;

View File

@ -12,8 +12,8 @@ import { SidebarItem } from "./sidebar-item";
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry"; import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
import { SidebarCluster } from "./sidebar-cluster"; import { SidebarCluster } from "./sidebar-cluster";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable"; import type { HierarchicalSidebarItem } from "@k8slens/cluster-sidebar";
import sidebarItemsInjectable from "./sidebar-items.injectable"; import { sidebarItemsInjectable } from "@k8slens/cluster-sidebar";
import type { IComputedValue } from "mobx"; import type { IComputedValue } from "mobx";
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";

View File

@ -11,7 +11,7 @@ import type { StrictReactNode } from "@k8slens/utilities";
import { cssNames } from "@k8slens/utilities"; import { cssNames } from "@k8slens/utilities";
import { Tab, Tabs } from "../tabs"; import { Tab, Tabs } from "../tabs";
import { ErrorBoundary } from "@k8slens/error-boundary"; import { ErrorBoundary } from "@k8slens/error-boundary";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable"; import type { HierarchicalSidebarItem } from "@k8slens/cluster-sidebar";
export interface TabLayoutProps { export interface TabLayoutProps {
tabs?: HierarchicalSidebarItem[]; tabs?: HierarchicalSidebarItem[];

View File

@ -3,41 +3,32 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import namespacesRouteInjectable from "../../../common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable"; import namespacesRouteInjectable from "../../../common/front-end-routing/routes/cluster/namespaces/namespaces-route.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToNamespacesInjectable from "../../../common/front-end-routing/routes/cluster/namespaces/navigate-to-namespaces.injectable"; import navigateToNamespacesInjectable from "../../../common/front-end-routing/routes/cluster/namespaces/navigate-to-namespaces.injectable";
const namespacesSidebarItemsInjectable = getInjectable({ const namespacesSidebarItemInjectable = getInjectable({
id: "namespaces", id: "namespaces-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(namespacesRouteInjectable); const route = di.inject(namespacesRouteInjectable);
const navigateToNamespaces = di.inject(navigateToNamespacesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "namespaces",
id: "namespaces", parentId: null,
parentId: null, getIcon: () => <Icon material="layers" />,
getIcon: () => <Icon material="layers" />, title: "Namespaces",
title: "Namespaces", onClick: di.inject(navigateToNamespacesInjectable),
onClick: navigateToNamespaces, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 70,
orderNumber: 70, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default namespacesSidebarItemsInjectable; export default namespacesSidebarItemInjectable;

View File

@ -3,35 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import endpointsRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable"; import endpointsRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/endpoints/endpoints-route.injectable";
import { networkSidebarItemId } from "../network/network-sidebar-items.injectable"; import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToEndpointsInjectable from "../../../common/front-end-routing/routes/cluster/network/endpoints/navigate-to-endpoints.injectable"; import navigateToEndpointsInjectable from "../../../common/front-end-routing/routes/cluster/network/endpoints/navigate-to-endpoints.injectable";
const endpointsSidebarItemsInjectable = getInjectable({ const endpointsSidebarItemInjectable = getInjectable({
id: "endpoints-sidebar-items", id: "endpoints-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(endpointsRouteInjectable); const route = di.inject(endpointsRouteInjectable);
const navigateToEndpoints = di.inject(navigateToEndpointsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "endpoints",
id: "endpoints", parentId: di.inject(networkSidebarItemInjectable).id,
parentId: networkSidebarItemId, title: "Endpoints",
title: "Endpoints", onClick: di.inject(navigateToEndpointsInjectable),
onClick: navigateToEndpoints, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default endpointsSidebarItemsInjectable; export default endpointsSidebarItemInjectable;

View File

@ -3,18 +3,15 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token";
routeSpecificComponentInjectionToken, import ingressClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/ingress-class/ingress-classes-route.injectable";
} from "../../routes/route-specific-component-injection-token";
import ingressClassesesRouteInjectable
from "../../../common/front-end-routing/routes/cluster/network/ingress-class/ingress-classeses-route.injectable";
import { IngressClasses } from "./ingress-classes"; import { IngressClasses } from "./ingress-classes";
const ingressClassesRouteComponentInjectable = getInjectable({ const ingressClassesRouteComponentInjectable = getInjectable({
id: "ingress-classes-route-component", id: "ingress-classes-route-component",
instantiate: (di) => ({ instantiate: (di) => ({
route: di.inject(ingressClassesesRouteInjectable), route: di.inject(ingressClassesRouteInjectable),
Component: IngressClasses, Component: IngressClasses,
}), }),

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { getInjectable } from "@ogre-tools/injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
import navigateToIngressClassesInjectable from "../../../common/front-end-routing/routes/cluster/network/ingress-class/navigate-to-ingress-classes.injectable";
import ingressClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/ingress-class/ingress-classes-route.injectable";
const ingressClassesSidebarItemInjectable = getInjectable({
id: "ingress-classes-sidebar-item",
instantiate: (di) => {
const ingressClassRoute = di.inject(ingressClassesRouteInjectable);
return {
id: "ingressclasses",
parentId: di.inject(networkSidebarItemInjectable).id,
title: "Ingress Classes",
onClick: di.inject(navigateToIngressClassesInjectable),
isActive: di.inject(routeIsActiveInjectable, ingressClassRoute),
isVisible: ingressClassRoute.isEnabled,
orderNumber: 31,
};
},
injectionToken: sidebarItemInjectionToken,
});
export default ingressClassesSidebarItemInjectable;

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { getInjectable } from "@ogre-tools/injectable";
import navigateToIngressesInjectable from "../../../common/front-end-routing/routes/cluster/network/ingress-class/navigate-to-ingress-classes.injectable";
import ingressesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
const ingressesSidebarItemInjectable = getInjectable({
id: "ingresses-sidebar-item",
instantiate: (di) => {
const ingressRoute = di.inject(ingressesRouteInjectable);
return {
id: "ingresses",
parentId: di.inject(networkSidebarItemInjectable).id,
title: "Ingresses",
onClick: di.inject(navigateToIngressesInjectable),
isActive: di.inject(routeIsActiveInjectable, ingressRoute),
isVisible: ingressRoute.isEnabled,
orderNumber: 30,
};
},
injectionToken: sidebarItemInjectionToken,
});
export default ingressesSidebarItemInjectable;

View File

@ -1,56 +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 type { IComputedValue } from "mobx";
import { computed } from "mobx";
import ingressesRouteInjectable
from "../../../common/front-end-routing/routes/cluster/network/ingresses/ingresses-route.injectable";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { networkSidebarItemId } from "../network/network-sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToIngressesInjectable
from "../../../common/front-end-routing/routes/cluster/network/ingresses/navigate-to-ingresses.injectable";
import ingressClassesesRouteInjectable
from "../../../common/front-end-routing/routes/cluster/network/ingress-class/ingress-classeses-route.injectable";
import navigateToIngressClassesInjectable
from "../../../common/front-end-routing/routes/cluster/network/ingress-class/navigate-to-ingress-classes.injectable";
const ingressesSidebarItemsInjectable = getInjectable({
id: "ingresses-sidebar-items",
instantiate: (di): IComputedValue<SidebarItemRegistration[]> => {
const ingressRoute = di.inject(ingressesRouteInjectable);
const ingressClassRoute = di.inject(ingressClassesesRouteInjectable);
return computed(() => [
{
id: "ingresses",
parentId: networkSidebarItemId,
title: "Ingresses",
onClick: di.inject(navigateToIngressesInjectable),
isActive: di.inject(routeIsActiveInjectable, ingressRoute),
isVisible: ingressRoute.isEnabled,
orderNumber: 30,
},
{
id: "ingressclasses",
parentId: networkSidebarItemId,
title: "Ingress Classes",
onClick: di.inject(navigateToIngressClassesInjectable),
isActive: di.inject(routeIsActiveInjectable, ingressClassRoute),
isVisible: ingressClassRoute.isEnabled,
orderNumber: 31,
},
]);
},
injectionToken: sidebarItemsInjectionToken,
});
export default ingressesSidebarItemsInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import networkPoliciesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable"; import networkPoliciesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/network-policies/network-policies-route.injectable";
import { networkSidebarItemId } from "../network/network-sidebar-items.injectable"; import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToNetworkPoliciesInjectable from "../../../common/front-end-routing/routes/cluster/network/network-policies/navigate-to-network-policies.injectable"; import navigateToNetworkPoliciesInjectable from "../../../common/front-end-routing/routes/cluster/network/network-policies/navigate-to-network-policies.injectable";
const networkPoliciesSidebarItemsInjectable = getInjectable({ const networkPoliciesSidebarItemInjectable = getInjectable({
id: "network-policies-sidebar-items", id: "network-policies-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(networkPoliciesRouteInjectable); const route = di.inject(networkPoliciesRouteInjectable);
const navigateToNetworkPolicies = di.inject(navigateToNetworkPoliciesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "network-policies",
id: "network-policies", parentId: di.inject(networkSidebarItemInjectable).id,
parentId: networkSidebarItemId, title: "Network Policies",
title: "Network Policies", onClick: di.inject(navigateToNetworkPoliciesInjectable),
onClick: navigateToNetworkPolicies, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 40,
orderNumber: 40, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default networkPoliciesSidebarItemsInjectable; export default networkPoliciesSidebarItemInjectable;

View File

@ -3,37 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import portForwardsRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/port-forwards/port-forwards-route.injectable"; import portForwardsRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/port-forwards/port-forwards-route.injectable";
import { networkSidebarItemId } from "../network/network-sidebar-items.injectable"; import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPortForwardsInjectable from "../../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable"; import navigateToPortForwardsInjectable from "../../../common/front-end-routing/routes/cluster/network/port-forwards/navigate-to-port-forwards.injectable";
const portForwardsSidebarItemsInjectable = getInjectable({ const portForwardsSidebarItemInjectable = getInjectable({
id: "port-forwards-sidebar-items", id: "port-forwards-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(portForwardsRouteInjectable); const route = di.inject(portForwardsRouteInjectable);
const navigateToPortForwards = di.inject(navigateToPortForwardsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "port-forwards",
id: "port-forwards", parentId: di.inject(networkSidebarItemInjectable).id,
parentId: networkSidebarItemId, title: "Port Forwarding",
onClick: di.inject(navigateToPortForwardsInjectable),
title: "Port Forwarding", isActive: di.inject(routeIsActiveInjectable, route),
onClick: navigateToPortForwards, isVisible: route.isEnabled,
isActive: routeIsActive, orderNumber: 50,
isVisible: route.isEnabled, };
orderNumber: 50,
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default portForwardsSidebarItemsInjectable; export default portForwardsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import servicesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/services/services-route.injectable"; import servicesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/services/services-route.injectable";
import { networkSidebarItemId } from "../network/network-sidebar-items.injectable"; import networkSidebarItemInjectable from "../network/network-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToServicesInjectable from "../../../common/front-end-routing/routes/cluster/network/services/navigate-to-services.injectable"; import navigateToServicesInjectable from "../../../common/front-end-routing/routes/cluster/network/services/navigate-to-services.injectable";
const servicesSidebarItemsInjectable = getInjectable({ const servicesSidebarItemInjectable = getInjectable({
id: "services-sidebar-items", id: "services-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(servicesRouteInjectable); const route = di.inject(servicesRouteInjectable);
const navigateToServices = di.inject(navigateToServicesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "services",
id: "services", parentId: di.inject(networkSidebarItemInjectable).id,
parentId: networkSidebarItemId, title: "Services",
title: "Services", onClick: di.inject(navigateToServicesInjectable),
onClick: navigateToServices, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default servicesSidebarItemsInjectable; export default servicesSidebarItemInjectable;

View File

@ -3,34 +3,24 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
export const networkSidebarItemId = "network"; const networkSidebarItemInjectable = getInjectable({
id: "network-sidebar-item",
const networkSidebarItemsInjectable = getInjectable({ instantiate: () => ({
id: "network-sidebar-items", id: "network",
parentId: null,
getIcon: () => <Icon material="device_hub" />,
title: "Network",
onClick: noop,
orderNumber: 50,
}),
instantiate: () => injectionToken: sidebarItemInjectionToken,
computed((): SidebarItemRegistration[] => [
{
id: networkSidebarItemId,
parentId: null,
getIcon: () => <Icon material="device_hub" />,
title: "Network",
onClick: noop,
orderNumber: 50,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default networkSidebarItemsInjectable; export default networkSidebarItemInjectable;

View File

@ -3,12 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
@ -16,29 +11,25 @@ import nodesRouteInjectable from "../../../common/front-end-routing/routes/clust
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToNodesInjectable from "../../../common/front-end-routing/routes/cluster/nodes/navigate-to-nodes.injectable"; import navigateToNodesInjectable from "../../../common/front-end-routing/routes/cluster/nodes/navigate-to-nodes.injectable";
const nodesSidebarItemsInjectable = getInjectable({ const nodesSidebarItemInjectable = getInjectable({
id: "nodes-sidebar-items", id: "nodes-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(nodesRouteInjectable); const route = di.inject(nodesRouteInjectable);
const navigateToNodes = di.inject(navigateToNodesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed((): SidebarItemRegistration[] => [ return {
{ id: "nodes",
id: "nodes", parentId: null,
parentId: null, getIcon: () => <Icon svg="nodes" />,
getIcon: () => <Icon svg="nodes" />, title: "Nodes",
title: "Nodes", onClick: di.inject(navigateToNodesInjectable),
onClick: navigateToNodes, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default nodesSidebarItemsInjectable; export default nodesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import podSecurityPoliciesRouteInjectable from "../../../common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable"; import podSecurityPoliciesRouteInjectable from "../../../common/front-end-routing/routes/cluster/user-management/pod-security-policies/pod-security-policies-route.injectable";
import { userManagementSidebarItemId } from "../user-management/user-management-sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPodSecurityPoliciesInjectable from "../../../common/front-end-routing/routes/cluster/user-management/pod-security-policies/navigate-to-pod-security-policies.injectable"; import navigateToPodSecurityPoliciesInjectable from "../../../common/front-end-routing/routes/cluster/user-management/pod-security-policies/navigate-to-pod-security-policies.injectable";
import userManagementSidebarItemInjectable from "../user-management/user-management-sidebar-items.injectable";
const podSecurityPoliciesSidebarItemsInjectable = getInjectable({ const podSecurityPoliciesSidebarItemInjectable = getInjectable({
id: "pod-security-policies-sidebar-items", id: "pod-security-policies-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(podSecurityPoliciesRouteInjectable); const route = di.inject(podSecurityPoliciesRouteInjectable);
const navigateToPodSecurityPolicies = di.inject(navigateToPodSecurityPoliciesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "pod-security-policies",
id: "pod-security-policies", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Pod Security Policies",
title: "Pod Security Policies", onClick: di.inject(navigateToPodSecurityPoliciesInjectable),
onClick: navigateToPodSecurityPolicies, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 60,
orderNumber: 60, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default podSecurityPoliciesSidebarItemsInjectable; export default podSecurityPoliciesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import storageClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable"; import storageClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/storage-classes/storage-classes-route.injectable";
import { storageSidebarItemId } from "../storage/storage-sidebar-items.injectable"; import storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToStorageClassesInjectable from "../../../common/front-end-routing/routes/cluster/storage/storage-classes/navigate-to-storage-classes.injectable"; import navigateToStorageClassesInjectable from "../../../common/front-end-routing/routes/cluster/storage/storage-classes/navigate-to-storage-classes.injectable";
const storageClassesSidebarItemsInjectable = getInjectable({ const storageClassesSidebarItemInjectable = getInjectable({
id: "storage-classes-sidebar-items", id: "storage-classes-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(storageClassesRouteInjectable); const route = di.inject(storageClassesRouteInjectable);
const navigateToStorageClasses = di.inject(navigateToStorageClassesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "storage-classes",
id: "storage-classes", parentId: di.inject(storageSidebarItemInjectable).id,
parentId: storageSidebarItemId, title: "Storage Classes",
title: "Storage Classes", onClick: di.inject(navigateToStorageClassesInjectable),
onClick: navigateToStorageClasses, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 30,
orderNumber: 30, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default storageClassesSidebarItemsInjectable; export default storageClassesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import persistentVolumeClaimsRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable"; import persistentVolumeClaimsRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volume-claims/persistent-volume-claims-route.injectable";
import { storageSidebarItemId } from "../storage/storage-sidebar-items.injectable"; import storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPersistentVolumeClaimsInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volume-claims/navigate-to-persistent-volume-claims.injectable"; import navigateToPersistentVolumeClaimsInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volume-claims/navigate-to-persistent-volume-claims.injectable";
const persistentVolumeClaimsSidebarItemsInjectable = getInjectable({ const persistentVolumeClaimsSidebarItemInjectable = getInjectable({
id: "persistent-volume-claims-sidebar-items", id: "persistent-volume-claims-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(persistentVolumeClaimsRouteInjectable); const route = di.inject(persistentVolumeClaimsRouteInjectable);
const navigateToPersistentVolumeClaims = di.inject(navigateToPersistentVolumeClaimsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "persistent-volume-claims",
id: "persistent-volume-claims", parentId: di.inject(storageSidebarItemInjectable).id,
parentId: storageSidebarItemId, title: "Persistent Volume Claims",
title: "Persistent Volume Claims", onClick: di.inject(navigateToPersistentVolumeClaimsInjectable),
onClick: navigateToPersistentVolumeClaims, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default persistentVolumeClaimsSidebarItemsInjectable; export default persistentVolumeClaimsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import persistentVolumesRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable"; import persistentVolumesRouteInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volumes/persistent-volumes-route.injectable";
import { storageSidebarItemId } from "../storage/storage-sidebar-items.injectable"; import storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToPersistentVolumesInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volumes/navigate-to-persistent-volumes.injectable"; import navigateToPersistentVolumesInjectable from "../../../common/front-end-routing/routes/cluster/storage/persistent-volumes/navigate-to-persistent-volumes.injectable";
const persistentVolumesSidebarItemsInjectable = getInjectable({ const persistentVolumesSidebarItemInjectable = getInjectable({
id: "persistent-volumes-sidebar-items", id: "persistent-volumes-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(persistentVolumesRouteInjectable); const route = di.inject(persistentVolumesRouteInjectable);
const navigateToPersistentVolumes = di.inject(navigateToPersistentVolumesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "persistent-volumes",
id: "persistent-volumes", parentId: di.inject(storageSidebarItemInjectable).id,
parentId: storageSidebarItemId, title: "Persistent Volumes",
title: "Persistent Volumes", onClick: di.inject(navigateToPersistentVolumesInjectable),
onClick: navigateToPersistentVolumes, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default persistentVolumesSidebarItemsInjectable; export default persistentVolumesSidebarItemInjectable;

View File

@ -3,34 +3,24 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
export const storageSidebarItemId = "storage"; const storageSidebarItemInjectable = getInjectable({
id: "storage-sidebar-item",
const storageSidebarItemsInjectable = getInjectable({ instantiate: () => ({
id: "storage-sidebar-items", id: "storage",
parentId: null,
getIcon: () => <Icon material="storage" />,
title: "Storage",
onClick: noop,
orderNumber: 60,
}),
instantiate: () => injectionToken: sidebarItemInjectionToken,
computed((): SidebarItemRegistration[] => [
{
id: storageSidebarItemId,
parentId: null,
getIcon: () => <Icon material="storage" />,
title: "Storage",
onClick: noop,
orderNumber: 60,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default storageSidebarItemsInjectable; export default storageSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import clusterRoleBindingsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable"; import clusterRoleBindingsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/cluster-role-bindings-route.injectable";
import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import { sidebarItemsInjectionToken } from "../../layout/sidebar-items.injectable";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import navigateToClusterRoleBindingsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/navigate-to-cluster-role-bindings.injectable"; import navigateToClusterRoleBindingsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-role-bindings/navigate-to-cluster-role-bindings.injectable";
import userManagementSidebarItemInjectable from "../user-management-sidebar-items.injectable";
const clusterRoleBindingsSidebarItemsInjectable = getInjectable({ const clusterRoleBindingsSidebarItemInjectable = getInjectable({
id: "cluster-role-bindings-sidebar-items", id: "cluster-role-bindings-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(clusterRoleBindingsRouteInjectable); const route = di.inject(clusterRoleBindingsRouteInjectable);
const navigateToClusterRoleBindings = di.inject(navigateToClusterRoleBindingsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "cluster-role-bindings",
id: "cluster-role-bindings", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Cluster Role Bindings",
title: "Cluster Role Bindings", onClick: di.inject(navigateToClusterRoleBindingsInjectable),
onClick: navigateToClusterRoleBindings, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 40,
orderNumber: 40, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default clusterRoleBindingsSidebarItemsInjectable; export default clusterRoleBindingsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import clusterRolesRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable"; import clusterRolesRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-roles/cluster-roles-route.injectable";
import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable"; import userManagementSidebarItemInjectable from "../user-management-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import navigateToClusterRolesInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-roles/navigate-to-cluster-roles.injectable"; import navigateToClusterRolesInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/cluster-roles/navigate-to-cluster-roles.injectable";
const clusterRolesSidebarItemsInjectable = getInjectable({ const clusterRolesSidebarItemInjectable = getInjectable({
id: "cluster-roles-sidebar-items", id: "cluster-roles-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(clusterRolesRouteInjectable); const route = di.inject(clusterRolesRouteInjectable);
const navigateToClusterRoles = di.inject(navigateToClusterRolesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "cluster-roles",
id: "cluster-roles", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Cluster Roles",
title: "Cluster Roles", onClick: di.inject(navigateToClusterRolesInjectable),
onClick: navigateToClusterRoles, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 20,
orderNumber: 20, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default clusterRolesSidebarItemsInjectable; export default clusterRolesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import roleBindingsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable"; import roleBindingsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/role-bindings/role-bindings-route.injectable";
import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable"; import userManagementSidebarItemInjectable from "../user-management-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import navigateToRoleBindingsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/role-bindings/navigate-to-role-bindings.injectable"; import navigateToRoleBindingsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/role-bindings/navigate-to-role-bindings.injectable";
const roleBindingsSidebarItemsInjectable = getInjectable({ const roleBindingsSidebarItemInjectable = getInjectable({
id: "role-bindings-sidebar-items", id: "role-bindings-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(roleBindingsRouteInjectable); const route = di.inject(roleBindingsRouteInjectable);
const navigateToRoleBindings = di.inject(navigateToRoleBindingsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "role-bindings",
id: "role-bindings", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Role Bindings",
title: "Role Bindings", onClick: di.inject(navigateToRoleBindingsInjectable),
onClick: navigateToRoleBindings, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 50,
orderNumber: 50, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default roleBindingsSidebarItemsInjectable; export default roleBindingsSidebarItemInjectable;

View File

@ -3,36 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import rolesRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable"; import rolesRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/roles/roles-route.injectable";
import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable"; import userManagementSidebarItemInjectable from "../user-management-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import navigateToRolesInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/roles/navigate-to-roles.injectable"; import navigateToRolesInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/roles/navigate-to-roles.injectable";
const rolesSidebarItemsInjectable = getInjectable({ const rolesSidebarItemInjectable = getInjectable({
id: "roles-sidebar-items", id: "roles-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(rolesRouteInjectable); const route = di.inject(rolesRouteInjectable);
const navigateToRoles = di.inject(navigateToRolesInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "roles",
id: "roles", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Roles",
title: "Roles", onClick: di.inject(navigateToRolesInjectable),
onClick: navigateToRoles, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 30,
orderNumber: 30, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default rolesSidebarItemsInjectable; export default rolesSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import serviceAccountsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable"; import serviceAccountsRouteInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/service-accounts/service-accounts-route.injectable";
import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable"; import userManagementSidebarItemInjectable from "../user-management-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
import navigateToServiceAccountsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/service-accounts/navigate-to-service-accounts.injectable"; import navigateToServiceAccountsInjectable from "../../../../common/front-end-routing/routes/cluster/user-management/service-accounts/navigate-to-service-accounts.injectable";
const serviceAccountsSidebarItemsInjectable = getInjectable({ const serviceAccountsSidebarItemInjectable = getInjectable({
id: "service-accounts-sidebar-items", id: "service-accounts-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(serviceAccountsRouteInjectable); const route = di.inject(serviceAccountsRouteInjectable);
const navigateToServiceAccounts = di.inject(navigateToServiceAccountsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "service-accounts",
id: "service-accounts", parentId: di.inject(userManagementSidebarItemInjectable).id,
parentId: userManagementSidebarItemId, title: "Service Accounts",
title: "Service Accounts", onClick: di.inject(navigateToServiceAccountsInjectable),
onClick: navigateToServiceAccounts, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 10,
orderNumber: 10, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default serviceAccountsSidebarItemsInjectable; export default serviceAccountsSidebarItemInjectable;

View File

@ -3,34 +3,24 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "@k8slens/icon"; import { Icon } from "@k8slens/icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
export const userManagementSidebarItemId = "user-management"; const userManagementSidebarItemInjectable = getInjectable({
id: "user-management-sidebar-item",
const userManagementSidebarItemsInjectable = getInjectable({ instantiate: () => ({
id: "user-management-sidebar-items", id: "user-management",
parentId: null,
getIcon: () => <Icon material="security" />,
title: "Access Control",
onClick: noop,
orderNumber: 100,
}),
instantiate: () => injectionToken: sidebarItemInjectionToken,
computed((): SidebarItemRegistration[] => [
{
id: userManagementSidebarItemId,
parentId: null,
getIcon: () => <Icon material="security" />,
title: "Access Control",
onClick: noop,
orderNumber: 100,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default userManagementSidebarItemsInjectable; export default userManagementSidebarItemInjectable;

View File

@ -3,36 +3,30 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import cronJobsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable"; import cronJobsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/cron-jobs-route.injectable";
import { workloadsSidebarItemId } from "../workloads/workloads-sidebar-items.injectable"; import workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToCronJobsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/navigate-to-cron-jobs.injectable"; import navigateToCronJobsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/navigate-to-cron-jobs.injectable";
const cronJobsSidebarItemsInjectable = getInjectable({ const cronJobsSidebarItemInjectable = getInjectable({
id: "cron-jobs-sidebar-items", id: "cron-jobs-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(cronJobsRouteInjectable); const route = di.inject(cronJobsRouteInjectable);
const navigateToCronJobs = di.inject(navigateToCronJobsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "cron-jobs",
id: "cron-jobs", parentId: di.inject(workloadsSidebarItemInjectable).id,
parentId: workloadsSidebarItemId, title: "CronJobs",
title: "CronJobs", onClick: di.inject(navigateToCronJobsInjectable),
onClick: navigateToCronJobs, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 80,
orderNumber: 80, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default cronJobsSidebarItemsInjectable; export default cronJobsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import daemonsetsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable"; import daemonsetsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/daemonsets/daemonsets-route.injectable";
import { workloadsSidebarItemId } from "../workloads/workloads-sidebar-items.injectable"; import workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToDaemonsetsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/daemonsets/navigate-to-daemonsets.injectable"; import navigateToDaemonsetsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/daemonsets/navigate-to-daemonsets.injectable";
const daemonsetsSidebarItemsInjectable = getInjectable({ const daemonsetsSidebarItemInjectable = getInjectable({
id: "daemonsets-sidebar-items", id: "daemonsets-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(daemonsetsRouteInjectable); const route = di.inject(daemonsetsRouteInjectable);
const navigateToDaemonsets = di.inject(navigateToDaemonsetsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "daemon-sets",
id: "daemon-sets", parentId: di.inject(workloadsSidebarItemInjectable).id,
parentId: workloadsSidebarItemId, title: "DaemonSets",
title: "DaemonSets", onClick: di.inject(navigateToDaemonsetsInjectable),
onClick: () => navigateToDaemonsets(), isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 40,
orderNumber: 40, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default daemonsetsSidebarItemsInjectable; export default daemonsetsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import deploymentsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable"; import deploymentsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/deployments/deployments-route.injectable";
import { workloadsSidebarItemId } from "../workloads/workloads-sidebar-items.injectable"; import workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToDeploymentsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/deployments/navigate-to-deployments.injectable"; import navigateToDeploymentsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/deployments/navigate-to-deployments.injectable";
const deploymentsSidebarItemsInjectable = getInjectable({ const deploymentsSidebarItemInjectable = getInjectable({
id: "deployments-sidebar-items", id: "deployments-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(deploymentsRouteInjectable); const route = di.inject(deploymentsRouteInjectable);
const navigateToDeployments = di.inject(navigateToDeploymentsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "deployments",
id: "deployments", parentId: di.inject(workloadsSidebarItemInjectable).id,
parentId: workloadsSidebarItemId, title: "Deployments",
title: "Deployments", onClick: di.inject(navigateToDeploymentsInjectable),
onClick: navigateToDeployments, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 30,
orderNumber: 30, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default deploymentsSidebarItemsInjectable; export default deploymentsSidebarItemInjectable;

View File

@ -3,36 +3,31 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
import jobsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable"; import jobsRouteInjectable from "../../../common/front-end-routing/routes/cluster/workloads/jobs/jobs-route.injectable";
import { workloadsSidebarItemId } from "../workloads/workloads-sidebar-items.injectable"; import workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable";
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar";
import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
import navigateToJobsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/jobs/navigate-to-jobs.injectable"; import navigateToJobsInjectable from "../../../common/front-end-routing/routes/cluster/workloads/jobs/navigate-to-jobs.injectable";
const jobsSidebarItemsInjectable = getInjectable({ const jobsSidebarItemInjectable = getInjectable({
id: "jobs-sidebar-items", id: "jobs-sidebar-item",
instantiate: (di) => { instantiate: (di) => {
const route = di.inject(jobsRouteInjectable); const route = di.inject(jobsRouteInjectable);
const navigateToJobs = di.inject(navigateToJobsInjectable);
const routeIsActive = di.inject(routeIsActiveInjectable, route);
return computed(() => [ return {
{ id: "jobs",
id: "jobs", parentId: di.inject(workloadsSidebarItemInjectable).id,
parentId: workloadsSidebarItemId, title: "Jobs",
title: "Jobs", onClick: di.inject(navigateToJobsInjectable),
onClick: navigateToJobs, isActive: di.inject(routeIsActiveInjectable, route),
isActive: routeIsActive, isVisible: route.isEnabled,
isVisible: route.isEnabled, orderNumber: 70,
orderNumber: 70, };
},
]);
}, },
injectionToken: sidebarItemsInjectionToken, injectionToken: sidebarItemInjectionToken,
}); });
export default jobsSidebarItemsInjectable; export default jobsSidebarItemInjectable;

Some files were not shown because too many files have changed in this diff Show More