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

Revert "chore: Extract sidebar item injection token into separate package"

This reverts commit 8ac66380ad.
This commit is contained in:
Sebastian Malton 2023-05-23 09:09:13 -04:00
parent cb0e8764ac
commit 8f4aa497cc
113 changed files with 1678 additions and 5646 deletions

View File

@ -179,7 +179,6 @@
"dependencies": { "dependencies": {
"@k8slens/application": "^6.5.0-alpha.8", "@k8slens/application": "^6.5.0-alpha.8",
"@k8slens/application-for-electron-main": "^6.5.0-alpha.7", "@k8slens/application-for-electron-main": "^6.5.0-alpha.7",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/core": "^6.5.0-alpha.13", "@k8slens/core": "^6.5.0-alpha.13",
"@k8slens/ensure-binaries": "^6.5.0-alpha.6", "@k8slens/ensure-binaries": "^6.5.0-alpha.6",
"@k8slens/event-emitter": "^1.0.0-alpha.5", "@k8slens/event-emitter": "^1.0.0-alpha.5",

View File

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

View File

@ -25,7 +25,6 @@ import { keyboardShortcutsFeature } from "@k8slens/keyboard-shortcuts";
import { reactApplicationFeature } from "@k8slens/react-application"; 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 { clusterSidebarFeature } from "@k8slens/cluster-sidebar";
const environment = "renderer"; const environment = "renderer";
@ -50,8 +49,7 @@ runInAction(() => {
keyboardShortcutsFeature, keyboardShortcutsFeature,
reactApplicationFeature, reactApplicationFeature,
routingFeature, routingFeature,
metricsFeature, metricsFeature
clusterSidebarFeature,
); );
autoRegister({ autoRegister({

26
package-lock.json generated
View File

@ -3959,10 +3959,6 @@
"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
@ -34925,7 +34921,6 @@
"dependencies": { "dependencies": {
"@k8slens/application": "^6.5.0-alpha.8", "@k8slens/application": "^6.5.0-alpha.8",
"@k8slens/application-for-electron-main": "^6.5.0-alpha.7", "@k8slens/application-for-electron-main": "^6.5.0-alpha.7",
"@k8slens/cluster-sidebar": "^1.0.0-alpha.0",
"@k8slens/core": "^6.5.0-alpha.13", "@k8slens/core": "^6.5.0-alpha.13",
"@k8slens/ensure-binaries": "^6.5.0-alpha.6", "@k8slens/ensure-binaries": "^6.5.0-alpha.6",
"@k8slens/event-emitter": "^1.0.0-alpha.5", "@k8slens/event-emitter": "^1.0.0-alpha.5",
@ -35136,26 +35131,6 @@
"@ogre-tools/injectable": "^16.1.0" "@ogre-tools/injectable": "^16.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-alpha.13", "version": "6.5.0-alpha.13",
@ -35351,7 +35326,6 @@
"@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/kubectl-versions": "^1.0.0-alpha.0", "@k8slens/kubectl-versions": "^1.0.0-alpha.0",

View File

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

View File

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

View File

@ -1,8 +0,0 @@
/**
* 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

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

View File

@ -1,48 +0,0 @@
{
"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

@ -1,14 +0,0 @@
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

@ -1,62 +0,0 @@
/* 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

@ -1,37 +0,0 @@
/**
* 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

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

View File

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

View File

@ -290,7 +290,6 @@
"@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/kubectl-versions": "^1.0.0-alpha.0", "@k8slens/kubectl-versions": "^1.0.0-alpha.0",

View File

@ -0,0 +1,21 @@
/**
* 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

@ -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 { navigateToRouteInjectionToken } from "../../../navigate-to-route-injection-token"; import crdListRouteInjectable from "./crd-list-route.injectable";
import crdListRouteInjectable from "./custom-resource-definitions.injectable"; import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token";
const navigateToCrdListInjectable = getInjectable({ const navigateToCrdListInjectable = getInjectable({
id: "navigate-to-crd-list", id: "navigate-to-crd-list",

View File

@ -1,24 +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 { 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,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,7 +14,8 @@ 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) => navigateToRoute(route, { parameters }); return (parameters?: CustomResourcesPathParameters) =>
navigateToRoute(route, { parameters });
}, },
}); });

View File

@ -1,24 +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 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

@ -0,0 +1,30 @@
/**
* 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 ingressClassesRouteInjectable from "./ingress-classes-route.injectable"; import ingressClassesesRouteInjectable from "./ingress-classeses-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(ingressClassesRouteInjectable); const route = di.inject(ingressClassesesRouteInjectable);
return () => navigateToRoute(route); return () => navigateToRoute(route);
}, },

View File

@ -0,0 +1,25 @@
/**
* 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,17 +4,18 @@
*/ */
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"> & Orderable; export type MenuItemRoot = Discriminable<"root"> & RootComposite<"root">;
const applicationMenuItemCompositeInjectable = getInjectable({ const applicationMenuItemCompositeInjectable = getInjectable({
id: "application-menu-item-composite", id: "application-menu-item-composite",
@ -23,30 +24,40 @@ const applicationMenuItemCompositeInjectable = getInjectable({
const menuItems = di.inject(applicationMenuItemsInjectable); const menuItems = di.inject(applicationMenuItemsInjectable);
const logError = di.inject(logErrorInjectable); const logError = di.inject(logErrorInjectable);
const getComposite = getCompositeFor<ApplicationMenuItemTypes | MenuItemRoot>({ return computed((): Composite<ApplicationMenuItemTypes | MenuItemRoot> => {
getId: (x) => x.id, const items = menuItems.get();
getParentId: (x) => x.parentId,
transformChildren: (children) => (
[...children]
.sort(byOrderNumber)
.filter(isShown)
),
handleMissingParentIds: ({ missingParentIds }) => {
const ids = missingParentIds.join('", "');
logError(`[MENU]: cannot render menu item for missing parentIds: "${ids}"`); return pipeline(
}, [
{
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 "@k8slens/utilities"; import type { Orderable } from "../../../../common/utils/composable-responsibilities/orderable/orderable";
export interface MayHaveKeyboardShortcut { export interface MayHaveKeyboardShortcut {
keyboardShortcut?: string; keyboardShortcut?: string;

View File

@ -1,244 +0,0 @@
/**
* 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,8 +5,9 @@
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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable";
import { runInAction } from "mobx"; import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sidebar-items.injectable";
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";
@ -22,14 +23,7 @@ describe("cluster - order of sidebar items", () => {
builder.beforeWindowStart(({ windowDi }) => { builder.beforeWindowStart(({ windowDi }) => {
runInAction(() => { runInAction(() => {
windowDi.register( windowDi.register(testSidebarItemsInjectable);
someParentSidebarItemInjectable,
someOtherParentSidebarItemInjectable,
someAnotherParentSidebarItemInjectable,
someChildSidebarItemInjectable,
someOtherChildSidebarItemInjectable,
someAnotherChildSidebarItemInjectable,
);
}); });
}); });
}); });
@ -84,74 +78,54 @@ describe("cluster - order of sidebar items", () => {
}); });
}); });
const someParentSidebarItemInjectable = getInjectable({ const testSidebarItemsInjectable = getInjectable({
id: "some-parent-sidebar-item", id: "some-sidebar-item-injectable",
instantiate: () => ({
id: "some-parent-id",
parentId: null,
title: "Some parent",
onClick: noop,
orderNumber: 42,
}),
injectionToken: sidebarItemInjectionToken,
});
const someOtherParentSidebarItemInjectable = getInjectable({ instantiate: () =>
id: "some-other-parent-sidebar-item", computed((): SidebarItemRegistration[] => [
instantiate: () => ({ {
id: "some-other-parent-id", id: "some-parent-id",
parentId: null, parentId: null,
title: "Some other parent", title: "Some parent",
onClick: noop, onClick: noop,
orderNumber: 126, orderNumber: 42,
}), },
injectionToken: sidebarItemInjectionToken, {
}); id: "some-other-parent-id",
parentId: null,
title: "Some other parent",
onClick: noop,
orderNumber: 126,
},
{
id: "some-another-parent-id",
parentId: null,
title: "Some another parent",
onClick: noop,
orderNumber: 84,
},
{
id: "some-child-id",
parentId: "some-parent-id",
title: "Some child",
onClick: noop,
orderNumber: 168,
},
{
id: "some-other-child-id",
parentId: "some-parent-id",
title: "Some other child",
onClick: noop,
orderNumber: 252,
},
{
id: "some-another-child-id",
parentId: "some-parent-id",
title: "Some another child",
onClick: noop,
orderNumber: 210,
},
]),
const someAnotherParentSidebarItemInjectable = getInjectable({ injectionToken: sidebarItemsInjectionToken,
id: "some-another-parent-sidebar-item",
instantiate: () => ({
id: "some-another-parent-id",
parentId: null,
title: "Some another parent",
onClick: noop,
orderNumber: 84,
}),
injectionToken: sidebarItemInjectionToken,
});
const someChildSidebarItemInjectable = getInjectable({
id: "some-child-sidebar-item",
instantiate: (di) => ({
id: "some-child-id",
parentId: di.inject(someParentSidebarItemInjectable).id,
title: "Some child",
onClick: noop,
orderNumber: 168,
}),
injectionToken: sidebarItemInjectionToken,
});
const someOtherChildSidebarItemInjectable = getInjectable({
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,7 +8,8 @@ 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable";
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";
@ -43,12 +44,9 @@ describe("cluster - sidebar and tab navigation for core", () => {
beforeEach(() => { beforeEach(() => {
builder.beforeWindowStart(({ windowDi }) => { builder.beforeWindowStart(({ windowDi }) => {
runInAction(() => { runInAction(() => {
windowDi.register( windowDi.register(testRouteInjectable);
testRouteInjectable, windowDi.register(testRouteComponentInjectable);
testRouteComponentInjectable, windowDi.register(testSidebarItemsInjectable);
someParentSidebarItemInjectable,
someChildSidebarItemInjectable,
);
}); });
}); });
}); });
@ -294,36 +292,36 @@ describe("cluster - sidebar and tab navigation for core", () => {
}); });
}); });
const someParentSidebarItemInjectable = getInjectable({ const testSidebarItemsInjectable = getInjectable({
id: "some-parent-sidebar-item", id: "some-sidebar-items-injectable",
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 { return computed((): SidebarItemRegistration[] => [
id: "some-child-id", {
parentId: di.inject(someParentSidebarItemInjectable).id, id: "some-parent-id",
title: "Some child", parentId: null,
onClick: () => navigateToRoute(route), title: "Some parent",
isActive: routeIsActive, onClick: noop,
orderNumber: 168, getIcon: () => <div data-testid="some-icon-for-parent" />,
}; 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,8 +4,9 @@
*/ */
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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "../../renderer/components/layout/sidebar-items.injectable";
import { runInAction } from "mobx"; import { sidebarItemsInjectionToken } from "../../renderer/components/layout/sidebar-items.injectable";
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";
@ -101,16 +102,18 @@ const testSidebarItemsInjectable = getInjectable({
const testRoute = di.inject(testRouteInjectable); const testRoute = di.inject(testRouteInjectable);
const navigateToRoute = di.inject(navigateToRouteInjectionToken); const navigateToRoute = di.inject(navigateToRouteInjectionToken);
return { return computed((): SidebarItemRegistration[] => [
id: "some-item-id", {
parentId: null, id: "some-item-id",
title: "Some item", parentId: null,
onClick: () => navigateToRoute(testRoute), title: "Some item",
isVisible: testRoute.isEnabled, onClick: () => navigateToRoute(testRoute),
orderNumber: 42, isVisible: testRoute.isEnabled,
}; orderNumber: 42,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });

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, MaybeOrderable } from "@k8slens/utilities"; import type { Orderable } from "../../../../common/utils/composable-responsibilities/orderable/orderable";
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,7 +50,6 @@ export type PreferencePage =
& Discriminable<"page"> & Discriminable<"page">
& ParentOfChildComposite & ParentOfChildComposite
& ChildOfParentComposite & ChildOfParentComposite
& MaybeOrderable
& MaybeShowable & MaybeShowable
& RenderableWithSiblings<PreferencePage>; & RenderableWithSiblings<PreferencePage>;
@ -58,7 +57,6 @@ export type PreferenceBlock =
& Discriminable<"block"> & Discriminable<"block">
& ParentOfChildComposite & ParentOfChildComposite
& ChildOfParentComposite & ChildOfParentComposite
& MaybeOrderable
& MaybeShowable & MaybeShowable
& RenderableWithSiblings<PreferenceBlock>; & RenderableWithSiblings<PreferenceBlock>;

View File

@ -8,19 +8,16 @@ 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,12 +7,13 @@ 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",
@ -26,25 +27,27 @@ const preferencesCompositeInjectable = getInjectable({
getId: (x) => x.id, getId: (x) => x.id,
getParentId: (x) => x.parentId, getParentId: (x) => x.parentId,
handleMissingParentIds: ({ missingParentIds, availableParentIds }) => { handleMissingParentIds: (ids) => {
const missingIds = missingParentIds.join('", "'); logError(
const availableIds = availableParentIds.join("\n"); `Tried to create preferences, but encountered references to unknown ids: "${ids.missingParentIds.join(
'", "',
logError([ )}".\n\nAvailable ids are:\n\n${ids.availableParentIds.join("\n")}`,
`Tried to create preferences, but encountered references to unknown ids: "${missingIds}".`, );
"Available ids are:",
availableIds,
].join("\n\n"));
}, },
transformChildren: (children) => ( transformChildren: (children) =>
children pipeline(
.filter(isShown) children.filter(isShown),
.sort(byOrderNumber) orderByOrderNumber,
), ),
}); });
return computed(() => getComposite([preferenceTabsRoot, ...preferenceItems.get()])); return computed(() =>
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 "@k8slens/utilities"; import { byOrderNumber } from "../../common/utils/composable-responsibilities/orderable/orderable";
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 "@k8slens/utilities"; import { byOrderNumber } from "../../../../common/utils/composable-responsibilities/orderable/orderable";
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,30 +5,39 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import React from "react"; import React from "react";
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type {
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 clusterOverviewSidebarItemInjectable = getInjectable({ const clusterOverviewSidebarItemsInjectable = getInjectable({
id: "cluster-overview-sidebar-item", id: "cluster-overview-sidebar-items",
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 { return computed((): SidebarItemRegistration[] => [
id: "cluster-overview", {
parentId: null, id: "cluster-overview",
title: "Cluster", parentId: null,
getIcon: () => <Icon svg="kube" />, title: "Cluster",
onClick: di.inject(navigateToClusterOverviewInjectable), getIcon: () => <Icon svg="kube" />,
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToClusterOverview,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default clusterOverviewSidebarItemInjectable; export default clusterOverviewSidebarItemsInjectable;

View File

@ -10,7 +10,6 @@ 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";
@ -26,6 +25,7 @@ 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,9 +56,10 @@ class NonInjectedClusterOverview extends React.Component<Dependencies> {
return ( return (
<> <>
{ {
[...this.props.uiBlocks.get()] orderByOrderNumber(this.props.uiBlocks.get())
.sort(byOrderNumber) .map((block) => (
.map(block => <block.Component key={block.id}/>) <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/navigate-to-custom-resources.injectable"; import navigateToCustomResourcesInjectable from "../../../../common/front-end-routing/routes/cluster/custom-resources/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,30 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-sidebar-items.injectable";
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
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 horizontalPodAutoScalersSidebarItemInjectable = getInjectable({ const horizontalPodAutoScalersSidebarItemsInjectable = getInjectable({
id: "horizontal-pod-auto-scalers-sidebar-item", id: "horizontal-pod-auto-scalers-sidebar-items",
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 { return computed((): SidebarItemRegistration[] => [
id: "horizontal-pod-auto-scalers", {
parentId: di.inject(configSidebarItemInjectable).id, id: "horizontal-pod-auto-scalers",
title: "HPA", parentId: configSidebarItemId,
onClick: di.inject(navigateToHorizontalPodAutoscalersInjectable), title: "HPA",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToHorizontalPodAutoscalers,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 50, isVisible: route.isEnabled,
}; orderNumber: 50,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default horizontalPodAutoScalersSidebarItemInjectable; export default horizontalPodAutoScalersSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 leasesSidebarItemInjectable = getInjectable({ const leasesSidebarItemsInjectable = getInjectable({
id: "leases-sidebar-item", id: "leases-sidebar-items",
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 { return computed(() => [
id: "leases", {
parentId: di.inject(configSidebarItemInjectable).id, id: "leases",
title: "Leases", parentId: configSidebarItemId,
onClick: di.inject(navigateToLeasesInjectable), title: "Leases",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToLeases,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 80, isVisible: route.isEnabled,
}; orderNumber: 80,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default leasesSidebarItemInjectable; export default leasesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 limitRangesSidebarItemInjectable = getInjectable({ const limitRangesSidebarItemsInjectable = getInjectable({
id: "limit-ranges-sidebar-item", id: "limit-ranges-sidebar-items",
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 { return computed(() => [
id: "limit-ranges", {
parentId: di.inject(configSidebarItemInjectable).id, id: "limit-ranges",
title: "Limit Ranges", parentId: configSidebarItemId,
onClick: di.inject(navigateToLimitRangesInjectable), title: "Limit Ranges",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToLimitRanges,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 40, isVisible: route.isEnabled,
}; orderNumber: 40,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default limitRangesSidebarItemInjectable; export default limitRangesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 configMapsSidebarItemInjectable = getInjectable({ const configMapsSidebarItemsInjectable = getInjectable({
id: "config-maps-sidebar-item", id: "config-maps-sidebar-items",
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 { return computed(() => [
id: "config-maps", {
parentId: di.inject(configSidebarItemInjectable).id, id: "config-maps",
title: "ConfigMaps", parentId: configSidebarItemId,
onClick: di.inject(navigateToConfigMapsInjectable), title: "ConfigMaps",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToConfigMaps,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default configMapsSidebarItemInjectable; export default configMapsSidebarItemsInjectable;

View File

@ -3,30 +3,37 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
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 from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable"; import mutatingWebhookConfigurationsRouteInjectable
import navigateToMutatingWebhookConfigurationsInjectable from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable"; from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable";
import configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import navigateToMutatingWebhookConfigurationsInjectable
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 mutatingWebhookConfigurationsSidebarItemInjectable = getInjectable({ const mutatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({
id: "mutating-webhook-configurations-sidebar-item", id: "mutating-webhook-configurations-sidebar-items",
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 { return computed(() => [
id: "mutating-webhook-configurations", {
parentId: di.inject(configSidebarItemInjectable).id, id: "mutating-webhook-configurations",
title: "Mutating Webhook Configs", parentId: configSidebarItemId,
onClick: di.inject(navigateToMutatingWebhookConfigurationsInjectable), title: "Mutating Webhook Configs",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPage,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 100, isVisible: route.isEnabled,
}; orderNumber: 100,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default mutatingWebhookConfigurationsSidebarItemInjectable; export default mutatingWebhookConfigurationsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 podDisruptionBudgetsSidebarItemInjectable = getInjectable({ const podDisruptionBudgetsSidebarItemsInjectable = getInjectable({
id: "pod-disruption-budgets-sidebar-item", id: "pod-disruption-budgets-sidebar-items",
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 { return computed(() => [
id: "pod-disruption-budgets", {
parentId: di.inject(configSidebarItemInjectable).id, id: "pod-disruption-budgets",
title: "Pod Disruption Budgets", parentId: configSidebarItemId,
onClick: di.inject(navigateToPodDisruptionBudgetsInjectable), title: "Pod Disruption Budgets",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPodDisruptionBudgets,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 60, isVisible: route.isEnabled,
}; orderNumber: 60,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default podDisruptionBudgetsSidebarItemInjectable; export default podDisruptionBudgetsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 priorityClassesSidebarItemInjectable = getInjectable({ const priorityClassesSidebarItemsInjectable = getInjectable({
id: "priority-classes-sidebar-item", id: "priority-classes-sidebar-items",
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 { return computed(() => [
id: "priority-classes", {
parentId: di.inject(configSidebarItemInjectable).id, id: "priority-classes",
title: "Priority Classes", parentId: configSidebarItemId,
onClick: di.inject(navigateToPriorityClassesInjectable), title: "Priority Classes",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPriorityClasses,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 70, isVisible: route.isEnabled,
}; orderNumber: 70,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default priorityClassesSidebarItemInjectable; export default priorityClassesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 resourceQuotasSidebarItemInjectable = getInjectable({ const resourceQuotasSidebarItemsInjectable = getInjectable({
id: "resource-quotas-sidebar-item", id: "resource-quotas-sidebar-items",
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 { return computed(() => [
id: "resource-quotas", {
parentId: di.inject(configSidebarItemInjectable).id, id: "resource-quotas",
title: "Resource Quotas", parentId: configSidebarItemId,
onClick: di.inject(navigateToResourceQuotasInjectable), title: "Resource Quotas",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToResourceQuotas,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 30, isVisible: route.isEnabled,
}; orderNumber: 30,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default resourceQuotasSidebarItemInjectable; export default resourceQuotasSidebarItemsInjectable;

View File

@ -0,0 +1,38 @@
/**
* 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

@ -1,33 +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 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,31 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-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 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 secretsSidebarItemInjectable = getInjectable({ const secretsSidebarItemsInjectable = getInjectable({
id: "secrets-sidebar-item", id: "secrets-sidebar-items",
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 { return computed(() => [
id: "secrets", {
parentId: di.inject(configSidebarItemInjectable).id, id: "secrets",
title: "Secrets", parentId: configSidebarItemId,
onClick: di.inject(navigateToSecretsInjectable), title: "Secrets",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToSecrets,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default secretsSidebarItemInjectable; export default secretsSidebarItemsInjectable;

View File

@ -3,30 +3,37 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
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 from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/validating-webhook-configurations-route.injectable"; import validatingWebhookConfigurationsRouteInjectable
import navigateToValidatingWebhookConfigurationsInjectable from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/navigate-to-validating-webhook-configurations.injectable"; from "../../../common/front-end-routing/routes/cluster/config/validating-webhook-configurations/validating-webhook-configurations-route.injectable";
import configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import navigateToValidatingWebhookConfigurationsInjectable
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 validatingWebhookConfigurationsSidebarItemInjectable = getInjectable({ const validatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({
id: "validating-webhook-configurations-sidebar-item", id: "validating-webhook-configurations-sidebar-items",
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 { return computed(() => [
id: "validating-webhook-configurations", {
parentId: di.inject(configSidebarItemInjectable).id, id: "validating-webhook-configurations",
title: "Validating Webhook Configs", parentId: configSidebarItemId,
onClick: di.inject(navigateToValidatingWebhookConfigurationsInjectable), title: "Validating Webhook Configs",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPage,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 100, isVisible: route.isEnabled,
}; orderNumber: 100,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default validatingWebhookConfigurationsSidebarItemInjectable; export default validatingWebhookConfigurationsSidebarItemsInjectable;

View File

@ -3,30 +3,36 @@
* 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 configSidebarItemInjectable from "../config/config-sidebar-items.injectable"; import { configSidebarItemId } from "../config/config-sidebar-items.injectable";
import { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
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 verticalPodAutoScalersSidebarItemInjectable = getInjectable({ const verticalPodAutoScalersSidebarItemsInjectable = getInjectable({
id: "vertical-pod-auto-scalers-sidebar-item", id: "vertical-pod-auto-scalers-sidebar-items",
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 { return computed((): SidebarItemRegistration[] => [
id: "vertical-pod-auto-scalers", {
parentId: di.inject(configSidebarItemInjectable).id, id: "vertical-pod-auto-scalers",
title: "VPA", parentId: configSidebarItemId,
onClick: di.inject(navigateToVerticalPodAutoscalersInjectable), title: "VPA",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToVerticalPodAutoscalers,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 50, isVisible: route.isEnabled,
}; orderNumber: 50,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default verticalPodAutoScalersSidebarItemInjectable; export default verticalPodAutoScalersSidebarItemsInjectable;

View File

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

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/custom-resource-definitions.injectable"; import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable";
import { CustomResourceDefinitions } from "./crd-list"; import { CustomResourceDefinitions } from "./crd-list";
const crdListRouteComponentInjectable = getInjectable({ const crdListRouteComponentInjectable = getInjectable({

View File

@ -1,86 +0,0 @@
/**
* 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

@ -1,29 +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 { 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

@ -1,30 +0,0 @@
/**
* 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

@ -0,0 +1,59 @@
/**
* 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 "../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-route.injectable"; import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/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-route.injectable"; import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable";
const customResourcesRouteParametersInjectable = getInjectable({ const customResourcesRouteParametersInjectable = getInjectable({
id: "custom-resources-route-parameters", id: "custom-resources-route-parameters",

View File

@ -1,24 +0,0 @@
/**
* 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

@ -0,0 +1,81 @@
/**
* 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 "@k8slens/utilities"; import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable";
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 "@k8slens/utilities"; import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable";
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,34 +3,42 @@
* 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 "../icon"; import { Icon } from "../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 eventsSidebarItemInjectable = getInjectable({ const eventsSidebarItemsInjectable = getInjectable({
id: "events-sidebar-item", id: "events-sidebar-items",
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 { return computed((): SidebarItemRegistration[] => [
id: "events", {
parentId: null, id: "events",
getIcon: () => <Icon material="access_time" />, parentId: null,
title: "Events", getIcon: () => <Icon material="access_time" />,
onClick: di.inject(navigateToEventsInjectable), title: "Events",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToEvents,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 80, isVisible: route.isEnabled,
}; orderNumber: 80,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default eventsSidebarItemInjectable; export default eventsSidebarItemsInjectable;

View File

@ -3,30 +3,35 @@
* 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 helmSidebarItemInjectable from "../helm/helm-sidebar-items.injectable"; import { helmSidebarItemId } from "../helm/helm-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 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 helmChartsSidebarItemInjectable = getInjectable({ const helmChartsSidebarItemsInjectable = getInjectable({
id: "helm-charts-sidebar-item", id: "helm-charts-sidebar-items",
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 { return computed(() => [
id: "charts", {
parentId: di.inject(helmSidebarItemInjectable).id, id: "charts",
title: "Charts", parentId: helmSidebarItemId,
onClick: di.inject(navigateToHelmChartsInjectable), title: "Charts",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToHelmCharts,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default helmChartsSidebarItemInjectable; export default helmChartsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 helmSidebarItemInjectable from "../helm/helm-sidebar-items.injectable"; import { helmSidebarItemId } from "../helm/helm-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 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 helmReleasesSidebarItemInjectable = getInjectable({ const helmReleasesSidebarItemsInjectable = getInjectable({
id: "helm-releases-sidebar-item", id: "helm-releases-sidebar-items",
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 { return computed(() => [
id: "releases", {
parentId: di.inject(helmSidebarItemInjectable).id, id: "releases",
title: "Releases", parentId: helmSidebarItemId,
onClick: di.inject(navigateToHelmReleasesInjectable), title: "Releases",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToHelmReleases,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default helmReleasesSidebarItemInjectable; export default helmReleasesSidebarItemsInjectable;

View File

@ -3,24 +3,34 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
const helmSidebarItemInjectable = getInjectable({ export const helmSidebarItemId = "helm";
id: "helm-sidebar-item",
instantiate: () => ({ const helmSidebarItemsInjectable = getInjectable({
id: "helm", id: "helm-sidebar-items",
parentId: null,
getIcon: () => <Icon svg="helm" />,
title: "Helm",
onClick: noop,
orderNumber: 90,
}),
injectionToken: sidebarItemInjectionToken, instantiate: () =>
computed((): SidebarItemRegistration[] => [
{
id: helmSidebarItemId,
parentId: null,
getIcon: () => <Icon svg="helm" />,
title: "Helm",
onClick: noop,
orderNumber: 90,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default helmSidebarItemInjectable; export default helmSidebarItemsInjectable;

View File

@ -5,7 +5,8 @@
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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import type { SidebarItemRegistration } from "./sidebar-items.injectable";
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";
@ -24,66 +25,71 @@ 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);
return computed(() => { const sidebarItemsForExtensionInjectable = getInjectable({
const extensionRoutes = routes.get().filter(matches({ extension })); id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}`,
injectionToken: sidebarItemsInjectionToken,
return extension.clusterPageMenus.map((registration) => { instantiate: (di) => {
const targetRoutePath = getExtensionRoutePath( return computed(() => {
extension, const extensionRoutes = routes.get().filter(matches({ extension }));
registration.target?.pageId,
);
const targetRoute = extensionRoutes.find( return extension.clusterPageMenus.map((registration) => {
matches({ path: targetRoutePath }), const targetRoutePath = getExtensionRoutePath(
); extension,
registration.target?.pageId,
);
const isVisible = computed(() => { const targetRoute = extensionRoutes.find(
if (!extensionShouldBeEnabledForClusterFrame.value.get()) { matches({ path: targetRoutePath }),
return false; );
}
if (!registration.visible) { const isVisible = computed(() => {
return true; if (!extensionShouldBeEnabledForClusterFrame.value.get()) {
} return false;
return registration.visible.get();
});
const id = registration.id ?
`${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 }),
}), if (!registration.visible) {
injectionToken: sidebarItemInjectionToken, 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 [
sidebarItemsForExtensionInjectable,
];
}, },
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 "@k8slens/cluster-sidebar"; import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
import type { StrictReactNode } from "@k8slens/utilities"; import type { StrictReactNode } from "@k8slens/utilities";
interface SiblingTabLayoutProps { interface SiblingTabLayoutProps {

View File

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

View File

@ -0,0 +1,80 @@
/**
* 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 "@k8slens/cluster-sidebar"; import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
import { sidebarItemsInjectable } from "@k8slens/cluster-sidebar"; import sidebarItemsInjectable from "./sidebar-items.injectable";
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 "@k8slens/cluster-sidebar"; import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
export interface TabLayoutProps { export interface TabLayoutProps {
tabs?: HierarchicalSidebarItem[]; tabs?: HierarchicalSidebarItem[];

View File

@ -3,32 +3,41 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../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 namespacesSidebarItemInjectable = getInjectable({ const namespacesSidebarItemsInjectable = getInjectable({
id: "namespaces-sidebar-item", id: "namespaces",
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 { return computed((): SidebarItemRegistration[] => [
id: "namespaces", {
parentId: null, id: "namespaces",
getIcon: () => <Icon material="layers" />, parentId: null,
title: "Namespaces", getIcon: () => <Icon material="layers" />,
onClick: di.inject(navigateToNamespacesInjectable), title: "Namespaces",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToNamespaces,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 70, isVisible: route.isEnabled,
}; orderNumber: 70,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default namespacesSidebarItemInjectable; export default namespacesSidebarItemsInjectable;

View File

@ -3,30 +3,35 @@
* 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 networkSidebarItemInjectable from "../network/network-sidebar-items.injectable"; import { networkSidebarItemId } from "../network/network-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 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 endpointsSidebarItemInjectable = getInjectable({ const endpointsSidebarItemsInjectable = getInjectable({
id: "endpoints-sidebar-item", id: "endpoints-sidebar-items",
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 { return computed(() => [
id: "endpoints", {
parentId: di.inject(networkSidebarItemInjectable).id, id: "endpoints",
title: "Endpoints", parentId: networkSidebarItemId,
onClick: di.inject(navigateToEndpointsInjectable), title: "Endpoints",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToEndpoints,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default endpointsSidebarItemInjectable; export default endpointsSidebarItemsInjectable;

View File

@ -3,15 +3,18 @@
* 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 { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token"; import {
import ingressClassesRouteInjectable from "../../../common/front-end-routing/routes/cluster/network/ingress-class/ingress-classes-route.injectable"; routeSpecificComponentInjectionToken,
} 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(ingressClassesRouteInjectable), route: di.inject(ingressClassesesRouteInjectable),
Component: IngressClasses, Component: IngressClasses,
}), }),

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 { 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

@ -1,30 +0,0 @@
/**
* 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

@ -0,0 +1,56 @@
/**
* 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,31 +3,36 @@
* 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 networkSidebarItemInjectable from "../network/network-sidebar-items.injectable"; import { networkSidebarItemId } from "../network/network-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 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 networkPoliciesSidebarItemInjectable = getInjectable({ const networkPoliciesSidebarItemsInjectable = getInjectable({
id: "network-policies-sidebar-item", id: "network-policies-sidebar-items",
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 { return computed(() => [
id: "network-policies", {
parentId: di.inject(networkSidebarItemInjectable).id, id: "network-policies",
title: "Network Policies", parentId: networkSidebarItemId,
onClick: di.inject(navigateToNetworkPoliciesInjectable), title: "Network Policies",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToNetworkPolicies,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 40, isVisible: route.isEnabled,
}; orderNumber: 40,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default networkPoliciesSidebarItemInjectable; export default networkPoliciesSidebarItemsInjectable;

View File

@ -3,31 +3,37 @@
* 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 networkSidebarItemInjectable from "../network/network-sidebar-items.injectable"; import { networkSidebarItemId } from "../network/network-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 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 portForwardsSidebarItemInjectable = getInjectable({ const portForwardsSidebarItemsInjectable = getInjectable({
id: "port-forwards-sidebar-item", id: "port-forwards-sidebar-items",
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 { return computed(() => [
id: "port-forwards", {
parentId: di.inject(networkSidebarItemInjectable).id, id: "port-forwards",
title: "Port Forwarding", parentId: networkSidebarItemId,
onClick: di.inject(navigateToPortForwardsInjectable),
isActive: di.inject(routeIsActiveInjectable, route), title: "Port Forwarding",
isVisible: route.isEnabled, onClick: navigateToPortForwards,
orderNumber: 50, isActive: routeIsActive,
}; isVisible: route.isEnabled,
orderNumber: 50,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default portForwardsSidebarItemInjectable; export default portForwardsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 networkSidebarItemInjectable from "../network/network-sidebar-items.injectable"; import { networkSidebarItemId } from "../network/network-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 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 servicesSidebarItemInjectable = getInjectable({ const servicesSidebarItemsInjectable = getInjectable({
id: "services-sidebar-item", id: "services-sidebar-items",
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 { return computed(() => [
id: "services", {
parentId: di.inject(networkSidebarItemInjectable).id, id: "services",
title: "Services", parentId: networkSidebarItemId,
onClick: di.inject(navigateToServicesInjectable), title: "Services",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToServices,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default servicesSidebarItemInjectable; export default servicesSidebarItemsInjectable;

View File

@ -3,24 +3,34 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
const networkSidebarItemInjectable = getInjectable({ export const networkSidebarItemId = "network";
id: "network-sidebar-item",
instantiate: () => ({ const networkSidebarItemsInjectable = getInjectable({
id: "network", id: "network-sidebar-items",
parentId: null,
getIcon: () => <Icon material="device_hub" />,
title: "Network",
onClick: noop,
orderNumber: 50,
}),
injectionToken: sidebarItemInjectionToken, instantiate: () =>
computed((): SidebarItemRegistration[] => [
{
id: networkSidebarItemId,
parentId: null,
getIcon: () => <Icon material="device_hub" />,
title: "Network",
onClick: noop,
orderNumber: 50,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default networkSidebarItemInjectable; export default networkSidebarItemsInjectable;

View File

@ -3,10 +3,12 @@
* 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 type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import { import {
sidebarItemInjectionToken, sidebarItemsInjectionToken,
} from "@k8slens/cluster-sidebar"; } from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import React from "react"; import React from "react";
@ -14,25 +16,29 @@ 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 nodesSidebarItemInjectable = getInjectable({ const nodesSidebarItemsInjectable = getInjectable({
id: "nodes-sidebar-item", id: "nodes-sidebar-items",
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 { return computed((): SidebarItemRegistration[] => [
id: "nodes", {
parentId: null, id: "nodes",
getIcon: () => <Icon svg="nodes" />, parentId: null,
title: "Nodes", getIcon: () => <Icon svg="nodes" />,
onClick: di.inject(navigateToNodesInjectable), title: "Nodes",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToNodes,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default nodesSidebarItemInjectable; export default nodesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { userManagementSidebarItemId } from "../user-management/user-management-sidebar-items.injectable";
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 podSecurityPoliciesSidebarItemInjectable = getInjectable({ const podSecurityPoliciesSidebarItemsInjectable = getInjectable({
id: "pod-security-policies-sidebar-item", id: "pod-security-policies-sidebar-items",
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 { return computed(() => [
id: "pod-security-policies", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "pod-security-policies",
title: "Pod Security Policies", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToPodSecurityPoliciesInjectable), title: "Pod Security Policies",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPodSecurityPolicies,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 60, isVisible: route.isEnabled,
}; orderNumber: 60,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default podSecurityPoliciesSidebarItemInjectable; export default podSecurityPoliciesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable"; import { storageSidebarItemId } from "../storage/storage-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 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 storageClassesSidebarItemInjectable = getInjectable({ const storageClassesSidebarItemsInjectable = getInjectable({
id: "storage-classes-sidebar-item", id: "storage-classes-sidebar-items",
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 { return computed(() => [
id: "storage-classes", {
parentId: di.inject(storageSidebarItemInjectable).id, id: "storage-classes",
title: "Storage Classes", parentId: storageSidebarItemId,
onClick: di.inject(navigateToStorageClassesInjectable), title: "Storage Classes",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToStorageClasses,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 30, isVisible: route.isEnabled,
}; orderNumber: 30,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default storageClassesSidebarItemInjectable; export default storageClassesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable"; import { storageSidebarItemId } from "../storage/storage-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 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 persistentVolumeClaimsSidebarItemInjectable = getInjectable({ const persistentVolumeClaimsSidebarItemsInjectable = getInjectable({
id: "persistent-volume-claims-sidebar-item", id: "persistent-volume-claims-sidebar-items",
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 { return computed(() => [
id: "persistent-volume-claims", {
parentId: di.inject(storageSidebarItemInjectable).id, id: "persistent-volume-claims",
title: "Persistent Volume Claims", parentId: storageSidebarItemId,
onClick: di.inject(navigateToPersistentVolumeClaimsInjectable), title: "Persistent Volume Claims",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPersistentVolumeClaims,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default persistentVolumeClaimsSidebarItemInjectable; export default persistentVolumeClaimsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 storageSidebarItemInjectable from "../storage/storage-sidebar-items.injectable"; import { storageSidebarItemId } from "../storage/storage-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 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 persistentVolumesSidebarItemInjectable = getInjectable({ const persistentVolumesSidebarItemsInjectable = getInjectable({
id: "persistent-volumes-sidebar-item", id: "persistent-volumes-sidebar-items",
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 { return computed(() => [
id: "persistent-volumes", {
parentId: di.inject(storageSidebarItemInjectable).id, id: "persistent-volumes",
title: "Persistent Volumes", parentId: storageSidebarItemId,
onClick: di.inject(navigateToPersistentVolumesInjectable), title: "Persistent Volumes",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToPersistentVolumes,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default persistentVolumesSidebarItemInjectable; export default persistentVolumesSidebarItemsInjectable;

View File

@ -3,24 +3,34 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
const storageSidebarItemInjectable = getInjectable({ export const storageSidebarItemId = "storage";
id: "storage-sidebar-item",
instantiate: () => ({ const storageSidebarItemsInjectable = getInjectable({
id: "storage", id: "storage-sidebar-items",
parentId: null,
getIcon: () => <Icon material="storage" />,
title: "Storage",
onClick: noop,
orderNumber: 60,
}),
injectionToken: sidebarItemInjectionToken, instantiate: () =>
computed((): SidebarItemRegistration[] => [
{
id: storageSidebarItemId,
parentId: null,
getIcon: () => <Icon material="storage" />,
title: "Storage",
onClick: noop,
orderNumber: 60,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default storageSidebarItemInjectable; export default storageSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { userManagementSidebarItemId } from "../user-management-sidebar-items.injectable";
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 clusterRoleBindingsSidebarItemInjectable = getInjectable({ const clusterRoleBindingsSidebarItemsInjectable = getInjectable({
id: "cluster-role-bindings-sidebar-item", id: "cluster-role-bindings-sidebar-items",
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 { return computed(() => [
id: "cluster-role-bindings", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "cluster-role-bindings",
title: "Cluster Role Bindings", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToClusterRoleBindingsInjectable), title: "Cluster Role Bindings",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToClusterRoleBindings,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 40, isVisible: route.isEnabled,
}; orderNumber: 40,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default clusterRoleBindingsSidebarItemInjectable; export default clusterRoleBindingsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 userManagementSidebarItemInjectable from "../user-management-sidebar-items.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 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 clusterRolesSidebarItemInjectable = getInjectable({ const clusterRolesSidebarItemsInjectable = getInjectable({
id: "cluster-roles-sidebar-item", id: "cluster-roles-sidebar-items",
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 { return computed(() => [
id: "cluster-roles", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "cluster-roles",
title: "Cluster Roles", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToClusterRolesInjectable), title: "Cluster Roles",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToClusterRoles,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 20, isVisible: route.isEnabled,
}; orderNumber: 20,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default clusterRolesSidebarItemInjectable; export default clusterRolesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 userManagementSidebarItemInjectable from "../user-management-sidebar-items.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 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 roleBindingsSidebarItemInjectable = getInjectable({ const roleBindingsSidebarItemsInjectable = getInjectable({
id: "role-bindings-sidebar-item", id: "role-bindings-sidebar-items",
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 { return computed(() => [
id: "role-bindings", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "role-bindings",
title: "Role Bindings", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToRoleBindingsInjectable), title: "Role Bindings",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToRoleBindings,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 50, isVisible: route.isEnabled,
}; orderNumber: 50,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default roleBindingsSidebarItemInjectable; export default roleBindingsSidebarItemsInjectable;

View File

@ -3,30 +3,36 @@
* 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 userManagementSidebarItemInjectable from "../user-management-sidebar-items.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 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 rolesSidebarItemInjectable = getInjectable({ const rolesSidebarItemsInjectable = getInjectable({
id: "roles-sidebar-item", id: "roles-sidebar-items",
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 { return computed(() => [
id: "roles", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "roles",
title: "Roles", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToRolesInjectable), title: "Roles",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToRoles,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 30, isVisible: route.isEnabled,
}; orderNumber: 30,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default rolesSidebarItemInjectable; export default rolesSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 userManagementSidebarItemInjectable from "../user-management-sidebar-items.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 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 serviceAccountsSidebarItemInjectable = getInjectable({ const serviceAccountsSidebarItemsInjectable = getInjectable({
id: "service-accounts-sidebar-item", id: "service-accounts-sidebar-items",
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 { return computed(() => [
id: "service-accounts", {
parentId: di.inject(userManagementSidebarItemInjectable).id, id: "service-accounts",
title: "Service Accounts", parentId: userManagementSidebarItemId,
onClick: di.inject(navigateToServiceAccountsInjectable), title: "Service Accounts",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToServiceAccounts,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 10, isVisible: route.isEnabled,
}; orderNumber: 10,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default serviceAccountsSidebarItemInjectable; export default serviceAccountsSidebarItemsInjectable;

View File

@ -3,24 +3,34 @@
* 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 { sidebarItemInjectionToken } from "@k8slens/cluster-sidebar"; import { computed } from "mobx";
import type {
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
import {
sidebarItemsInjectionToken,
} from "../layout/sidebar-items.injectable";
import { Icon } from "../icon"; import { Icon } from "../icon";
import React from "react"; import React from "react";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
const userManagementSidebarItemInjectable = getInjectable({ export const userManagementSidebarItemId = "user-management";
id: "user-management-sidebar-item",
instantiate: () => ({ const userManagementSidebarItemsInjectable = getInjectable({
id: "user-management", id: "user-management-sidebar-items",
parentId: null,
getIcon: () => <Icon material="security" />,
title: "Access Control",
onClick: noop,
orderNumber: 100,
}),
injectionToken: sidebarItemInjectionToken, instantiate: () =>
computed((): SidebarItemRegistration[] => [
{
id: userManagementSidebarItemId,
parentId: null,
getIcon: () => <Icon material="security" />,
title: "Access Control",
onClick: noop,
orderNumber: 100,
},
]),
injectionToken: sidebarItemsInjectionToken,
}); });
export default userManagementSidebarItemInjectable; export default userManagementSidebarItemsInjectable;

View File

@ -3,30 +3,36 @@
* 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 workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable"; import { workloadsSidebarItemId } from "../workloads/workloads-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 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 cronJobsSidebarItemInjectable = getInjectable({ const cronJobsSidebarItemsInjectable = getInjectable({
id: "cron-jobs-sidebar-item", id: "cron-jobs-sidebar-items",
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 { return computed(() => [
id: "cron-jobs", {
parentId: di.inject(workloadsSidebarItemInjectable).id, id: "cron-jobs",
title: "CronJobs", parentId: workloadsSidebarItemId,
onClick: di.inject(navigateToCronJobsInjectable), title: "CronJobs",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToCronJobs,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 80, isVisible: route.isEnabled,
}; orderNumber: 80,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default cronJobsSidebarItemInjectable; export default cronJobsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable"; import { workloadsSidebarItemId } from "../workloads/workloads-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 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 daemonsetsSidebarItemInjectable = getInjectable({ const daemonsetsSidebarItemsInjectable = getInjectable({
id: "daemonsets-sidebar-item", id: "daemonsets-sidebar-items",
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 { return computed(() => [
id: "daemon-sets", {
parentId: di.inject(workloadsSidebarItemInjectable).id, id: "daemon-sets",
title: "DaemonSets", parentId: workloadsSidebarItemId,
onClick: di.inject(navigateToDaemonsetsInjectable), title: "DaemonSets",
isActive: di.inject(routeIsActiveInjectable, route), onClick: () => navigateToDaemonsets(),
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 40, isVisible: route.isEnabled,
}; orderNumber: 40,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default daemonsetsSidebarItemInjectable; export default daemonsetsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable"; import { workloadsSidebarItemId } from "../workloads/workloads-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 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 deploymentsSidebarItemInjectable = getInjectable({ const deploymentsSidebarItemsInjectable = getInjectable({
id: "deployments-sidebar-item", id: "deployments-sidebar-items",
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 { return computed(() => [
id: "deployments", {
parentId: di.inject(workloadsSidebarItemInjectable).id, id: "deployments",
title: "Deployments", parentId: workloadsSidebarItemId,
onClick: di.inject(navigateToDeploymentsInjectable), title: "Deployments",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToDeployments,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 30, isVisible: route.isEnabled,
}; orderNumber: 30,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default deploymentsSidebarItemInjectable; export default deploymentsSidebarItemsInjectable;

View File

@ -3,31 +3,36 @@
* 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 workloadsSidebarItemInjectable from "../workloads/workloads-sidebar-items.injectable"; import { workloadsSidebarItemId } from "../workloads/workloads-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 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 jobsSidebarItemInjectable = getInjectable({ const jobsSidebarItemsInjectable = getInjectable({
id: "jobs-sidebar-item", id: "jobs-sidebar-items",
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 { return computed(() => [
id: "jobs", {
parentId: di.inject(workloadsSidebarItemInjectable).id, id: "jobs",
title: "Jobs", parentId: workloadsSidebarItemId,
onClick: di.inject(navigateToJobsInjectable), title: "Jobs",
isActive: di.inject(routeIsActiveInjectable, route), onClick: navigateToJobs,
isVisible: route.isEnabled, isActive: routeIsActive,
orderNumber: 70, isVisible: route.isEnabled,
}; orderNumber: 70,
},
]);
}, },
injectionToken: sidebarItemInjectionToken, injectionToken: sidebarItemsInjectionToken,
}); });
export default jobsSidebarItemInjectable; export default jobsSidebarItemsInjectable;

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