mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix CustomResourceDefinitions not being navigable
- Make buildURL more type safe Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
06ec1b39a4
commit
de6e86b8fb
@ -5,7 +5,7 @@
|
||||
|
||||
import { KubeCreationError, KubeObject } from "../kube-object";
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { crdResourcesURL } from "../../routes";
|
||||
import { customResourceDefinitionsURL } from "../../routes";
|
||||
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
|
||||
import type { KubeJsonApiData } from "../kube-json-api";
|
||||
|
||||
@ -99,7 +99,7 @@ export class CustomResourceDefinition extends KubeObject {
|
||||
}
|
||||
|
||||
getResourceUrl() {
|
||||
return crdResourcesURL({
|
||||
return customResourceDefinitionsURL({
|
||||
params: {
|
||||
group: this.getGroup(),
|
||||
name: this.getPluralName(),
|
||||
|
||||
@ -11,7 +11,7 @@ import { helmChartStore } from "../../../renderer/components/+helm-charts/helm-c
|
||||
import type { ItemObject } from "../../item.store";
|
||||
import { KubeObject } from "../kube-object";
|
||||
import type { JsonApiData } from "../json-api";
|
||||
import { buildURLPositional } from "../../utils/buildUrl";
|
||||
import { buildURL } from "../../utils/buildUrl";
|
||||
import type { KubeJsonApiData } from "../kube-json-api";
|
||||
|
||||
interface IReleasePayload {
|
||||
@ -77,16 +77,16 @@ interface EndpointQuery {
|
||||
all?: boolean;
|
||||
}
|
||||
|
||||
const endpoint = buildURLPositional<EndpointParams, EndpointQuery>("/v2/releases/:namespace?/:name?/:route?");
|
||||
const endpoint = buildURL<EndpointParams, EndpointQuery>("/v2/releases/:namespace?/:name?/:route?");
|
||||
|
||||
export async function listReleases(namespace?: string): Promise<HelmRelease[]> {
|
||||
const releases = await apiBase.get<HelmReleaseDto[]>(endpoint({ namespace }));
|
||||
const releases = await apiBase.get<HelmReleaseDto[]>(endpoint({ params: { namespace }}));
|
||||
|
||||
return releases.map(toHelmRelease);
|
||||
}
|
||||
|
||||
export async function getRelease(name: string, namespace: string): Promise<IReleaseDetails> {
|
||||
const path = endpoint({ name, namespace });
|
||||
const path = endpoint({ params: { name, namespace }});
|
||||
const { resources: rawResources, ...details } = await apiBase.get<IReleaseRawDetails>(path);
|
||||
const resources = rawResources.map(KubeObject.create);
|
||||
|
||||
@ -115,7 +115,7 @@ export async function updateRelease(name: string, namespace: string, payload: IR
|
||||
const chart = `${repo}/${rawChart}`;
|
||||
const values = yaml.load(rawValues);
|
||||
|
||||
return apiBase.put(endpoint({ name, namespace }), {
|
||||
return apiBase.put(endpoint({ params: { name, namespace }}), {
|
||||
data: {
|
||||
chart,
|
||||
values,
|
||||
@ -125,28 +125,28 @@ export async function updateRelease(name: string, namespace: string, payload: IR
|
||||
}
|
||||
|
||||
export async function deleteRelease(name: string, namespace: string): Promise<JsonApiData> {
|
||||
const path = endpoint({ name, namespace });
|
||||
const path = endpoint({ params: { name, namespace }});
|
||||
|
||||
return apiBase.del(path);
|
||||
}
|
||||
|
||||
export async function getReleaseValues(name: string, namespace: string, all?: boolean): Promise<string> {
|
||||
const route = "values";
|
||||
const path = endpoint({ name, namespace, route }, { all });
|
||||
const path = endpoint({ params: { name, namespace, route }, query: { all }});
|
||||
|
||||
return apiBase.get<string>(path);
|
||||
}
|
||||
|
||||
export async function getReleaseHistory(name: string, namespace: string): Promise<IReleaseRevision[]> {
|
||||
const route = "history";
|
||||
const path = endpoint({ name, namespace, route });
|
||||
const path = endpoint({ params: { name, namespace, route }});
|
||||
|
||||
return apiBase.get(path);
|
||||
}
|
||||
|
||||
export async function rollbackRelease(name: string, namespace: string, revision: number): Promise<JsonApiData> {
|
||||
const route = "rollback";
|
||||
const path = endpoint({ name, namespace, route });
|
||||
const path = endpoint({ params: { name, namespace, route }});
|
||||
const data = { revision };
|
||||
|
||||
return apiBase.put(path, { data });
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const addClusterRoute: RouteProps = {
|
||||
path: "/add-cluster",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export interface CatalogViewRouteParam {
|
||||
group?: string;
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export interface ClusterViewRouteParams {
|
||||
clusterId: string;
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const clusterRoute: RouteProps = {
|
||||
path: "/overview",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const configMapsRoute: RouteProps = {
|
||||
path: "/configmaps",
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import type { RouteProps as RouterProps } from "react-router";
|
||||
import type { URLParams } from "../utils/buildUrl";
|
||||
import { configMapsRoute, configMapsURL } from "./config-maps";
|
||||
import { hpaRoute } from "./hpa";
|
||||
@ -12,15 +12,15 @@ import { pdbRoute } from "./pod-disruption-budgets";
|
||||
import { resourceQuotaRoute } from "./resource-quotas";
|
||||
import { secretsRoute } from "./secrets";
|
||||
|
||||
export const configRoute: RouteProps = {
|
||||
export const configRoute: RouterProps = {
|
||||
path: [
|
||||
configMapsRoute,
|
||||
secretsRoute,
|
||||
resourceQuotaRoute,
|
||||
limitRangesRoute,
|
||||
hpaRoute,
|
||||
pdbRoute,
|
||||
].map(route => route.path.toString()),
|
||||
configMapsRoute.path,
|
||||
secretsRoute.path,
|
||||
resourceQuotaRoute.path,
|
||||
limitRangesRoute.path,
|
||||
hpaRoute.path,
|
||||
pdbRoute.path,
|
||||
],
|
||||
};
|
||||
|
||||
export const configURL = (params?: URLParams) => configMapsURL(params);
|
||||
|
||||
@ -3,29 +3,17 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const crdRoute: RouteProps = {
|
||||
path: "/crd",
|
||||
export const customResourcesRoute = "/crd";
|
||||
|
||||
export const customResourceDefinitionsRoute: RouteProps = {
|
||||
path: `${customResourcesRoute}/definitions/:group?/:name?`,
|
||||
};
|
||||
|
||||
export const crdDefinitionsRoute: RouteProps = {
|
||||
path: `${crdRoute.path}/definitions`,
|
||||
};
|
||||
|
||||
export const crdResourcesRoute: RouteProps = {
|
||||
path: `${crdRoute.path}/:group/:name`,
|
||||
};
|
||||
|
||||
export interface CRDListQuery {
|
||||
groups?: string;
|
||||
export interface CustomResourceDefinitionsRouteParams {
|
||||
group?: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface CRDRouteParams {
|
||||
group: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const crdURL = buildURL<{}, CRDListQuery>(crdDefinitionsRoute.path);
|
||||
export const crdResourcesURL = buildURL<CRDRouteParams>(crdResourcesRoute.path);
|
||||
export const customResourceDefinitionsURL = buildURL<CustomResourceDefinitionsRouteParams>(customResourceDefinitionsRoute.path);
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const endpointRoute: RouteProps = {
|
||||
path: "/endpoints",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export interface EntitySettingsRouteParams {
|
||||
entityId: string;
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const eventRoute: RouteProps = {
|
||||
path: "/events",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const extensionsRoute: RouteProps = {
|
||||
path: "/extensions",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
import { helmRoute } from "./helm";
|
||||
|
||||
export const helmChartsRoute: RouteProps = {
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const helmRoute: RouteProps = {
|
||||
path: "/helm",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const hpaRoute: RouteProps = {
|
||||
path: "/hpa",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const ingressRoute: RouteProps = {
|
||||
path: "/ingresses",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const limitRangesRoute: RouteProps = {
|
||||
path: "/limitranges",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const namespacesRoute: RouteProps = {
|
||||
path: "/namespaces",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const networkPoliciesRoute: RouteProps = {
|
||||
path: "/network-policies",
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import type { URLParams } from "../utils/buildUrl";
|
||||
import { endpointRoute } from "./endpoints";
|
||||
import { ingressRoute } from "./ingresses";
|
||||
import { networkPoliciesRoute } from "./network-policies";
|
||||
@ -21,4 +20,4 @@ export const networkRoute: RouteProps = {
|
||||
].map(route => route.path.toString()),
|
||||
};
|
||||
|
||||
export const networkURL = (params?: URLParams) => servicesURL(params);
|
||||
export const networkURL = servicesURL;
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const nodesRoute: RouteProps = {
|
||||
path: "/nodes",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const pdbRoute: RouteProps = {
|
||||
path: "/poddisruptionbudgets",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const portForwardsRoute: RouteProps = {
|
||||
path: "/port-forwards/:forwardport?",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const preferencesRoute: RouteProps = {
|
||||
path: "/preferences",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
import { helmRoute } from "./helm";
|
||||
|
||||
export const releaseRoute: RouteProps = {
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const resourceQuotaRoute: RouteProps = {
|
||||
path: "/resourcequotas",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const secretsRoute: RouteProps = {
|
||||
path: "/secrets",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const servicesRoute: RouteProps = {
|
||||
path: "/services",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const storageClassesRoute: RouteProps = {
|
||||
path: "/storage-classes",
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import type { URLParams } from "../utils/buildUrl";
|
||||
import { storageClassesRoute } from "./storage-classes";
|
||||
import { volumeClaimsRoute, volumeClaimsURL } from "./volume-claims";
|
||||
import { volumesRoute } from "./volumes";
|
||||
@ -17,4 +16,4 @@ export const storageRoute: RouteProps = {
|
||||
].map(route => route.path.toString()),
|
||||
};
|
||||
|
||||
export const storageURL = (params?: URLParams) => volumeClaimsURL(params);
|
||||
export const storageURL = volumeClaimsURL;
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL, URLParams } from "../utils/buildUrl";
|
||||
import type { RouteProps as RouterProps } from "react-router";
|
||||
import { buildURL, RouteProps, URLParams } from "../utils/buildUrl";
|
||||
|
||||
// Routes
|
||||
export const serviceAccountsRoute: RouteProps = {
|
||||
@ -26,15 +26,15 @@ export const clusterRoleBindingsRoute: RouteProps = {
|
||||
path: "/cluster-role-bindings",
|
||||
};
|
||||
|
||||
export const usersManagementRoute: RouteProps = {
|
||||
export const usersManagementRoute: RouterProps = {
|
||||
path: [
|
||||
serviceAccountsRoute,
|
||||
podSecurityPoliciesRoute,
|
||||
roleBindingsRoute,
|
||||
clusterRoleBindingsRoute,
|
||||
rolesRoute,
|
||||
clusterRolesRoute,
|
||||
].map(route => route.path.toString()),
|
||||
serviceAccountsRoute.path,
|
||||
podSecurityPoliciesRoute.path,
|
||||
roleBindingsRoute.path,
|
||||
clusterRoleBindingsRoute.path,
|
||||
rolesRoute.path,
|
||||
clusterRolesRoute.path,
|
||||
],
|
||||
};
|
||||
|
||||
// Route params
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const volumeClaimsRoute: RouteProps = {
|
||||
path: "/persistent-volume-claims",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const volumesRoute: RouteProps = {
|
||||
path: "/persistent-volumes",
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { buildURL, RouteProps } from "../utils/buildUrl";
|
||||
|
||||
export const welcomeRoute: RouteProps = {
|
||||
path: "/welcome",
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL, URLParams } from "../utils/buildUrl";
|
||||
import type { RouteProps as RouterProps } from "react-router";
|
||||
import { buildURL, RouteProps, URLParams } from "../utils/buildUrl";
|
||||
import type { KubeResource } from "../rbac";
|
||||
|
||||
// Routes
|
||||
@ -33,17 +33,17 @@ export const cronJobsRoute: RouteProps = {
|
||||
path: "/cronjobs",
|
||||
};
|
||||
|
||||
export const workloadsRoute: RouteProps = {
|
||||
export const workloadsRoute: RouterProps = {
|
||||
path: [
|
||||
overviewRoute,
|
||||
podsRoute,
|
||||
deploymentsRoute,
|
||||
daemonSetsRoute,
|
||||
statefulSetsRoute,
|
||||
replicaSetsRoute,
|
||||
jobsRoute,
|
||||
cronJobsRoute,
|
||||
].map(route => route.path.toString()),
|
||||
overviewRoute.path,
|
||||
podsRoute.path,
|
||||
deploymentsRoute.path,
|
||||
daemonSetsRoute.path,
|
||||
statefulSetsRoute.path,
|
||||
replicaSetsRoute.path,
|
||||
jobsRoute.path,
|
||||
cronJobsRoute.path,
|
||||
],
|
||||
};
|
||||
|
||||
// Route params
|
||||
|
||||
@ -4,32 +4,37 @@
|
||||
*/
|
||||
|
||||
import { compile } from "path-to-regexp";
|
||||
import type { RouteProps as RouterProps } from "react-router";
|
||||
import { format } from "url";
|
||||
|
||||
export interface URLParams<P extends object = {}, Q extends object = {}> {
|
||||
export interface RouteProps extends RouterProps {
|
||||
path?: string;
|
||||
}
|
||||
|
||||
type MaybeIfRecord<FieldName extends string, Type> = Type extends object
|
||||
? { [field in FieldName]?: Type }
|
||||
: {};
|
||||
|
||||
export type URLParams<P = unknown, Q = unknown> = {
|
||||
fragment?: string;
|
||||
} & MaybeIfRecord<"params", P> & MaybeIfRecord<"query", Q>;
|
||||
|
||||
interface InternalURLParams<P, Q> {
|
||||
fragment?: string;
|
||||
params?: P;
|
||||
query?: Q;
|
||||
fragment?: string;
|
||||
}
|
||||
|
||||
export function buildURL<P extends object = {}, Q extends object = {}>(path: string | any) {
|
||||
const pathBuilder = compile(String(path));
|
||||
export function buildURL<P = unknown, Q = unknown>(path: string): (urlParams?: URLParams<P, Q>) => string {
|
||||
const pathBuilder = compile(path);
|
||||
|
||||
return function ({ params, query, fragment }: URLParams<P, Q> = {}): string {
|
||||
const queryParams = query ? new URLSearchParams(Object.entries(query)).toString() : "";
|
||||
const parts = [
|
||||
pathBuilder(params),
|
||||
queryParams && `?${queryParams}`,
|
||||
fragment && `#${fragment}`,
|
||||
];
|
||||
return (urlParams) => {
|
||||
const { params = {}, query = {}, fragment } = urlParams as InternalURLParams<P, Q> ?? {};
|
||||
|
||||
return parts.filter(Boolean).join("");
|
||||
};
|
||||
}
|
||||
|
||||
export function buildURLPositional<P extends object = {}, Q extends object = {}>(path: string | any) {
|
||||
const builder = buildURL(path);
|
||||
|
||||
return function (params?: P, query?: Q, fragment?: string): string {
|
||||
return builder({ params, query, fragment });
|
||||
return format({
|
||||
pathname: pathBuilder(params),
|
||||
query: new URLSearchParams(query).toString(),
|
||||
search: fragment,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ enum columnId {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class CrdList extends React.Component {
|
||||
export class CustomResourceDefinitions extends React.Component {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
|
||||
@ -16,9 +16,9 @@ import { crdStore } from "./crd.store";
|
||||
import type { TableSortCallbacks } from "../table";
|
||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||
import { parseJsonPath } from "../../utils/jsonPath";
|
||||
import type { CRDRouteParams } from "../../../common/routes";
|
||||
import type { CustomResourceDefinitionsRouteParams } from "../../../common/routes";
|
||||
|
||||
interface Props extends RouteComponentProps<CRDRouteParams> {
|
||||
interface Props extends RouteComponentProps<CustomResourceDefinitionsRouteParams> {
|
||||
}
|
||||
|
||||
enum columnId {
|
||||
@ -28,7 +28,7 @@ enum columnId {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class CrdResources extends React.Component<Props> {
|
||||
export class CustomResourceDefinitionObjectList extends React.Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
@ -93,16 +93,12 @@ export class CrdResources extends React.Component<Props> {
|
||||
renderTableHeader={[
|
||||
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
|
||||
isNamespaced && { title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
|
||||
...extraColumns.map(column => {
|
||||
const { name } = column;
|
||||
|
||||
return {
|
||||
...extraColumns.map(({ name }) => ({
|
||||
title: name,
|
||||
className: name.toLowerCase(),
|
||||
sortBy: name,
|
||||
id: name,
|
||||
};
|
||||
}),
|
||||
})),
|
||||
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
|
||||
]}
|
||||
renderTableContents={crdInstance => [
|
||||
|
||||
@ -3,55 +3,69 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { computed, IComputedValue } from "mobx";
|
||||
import { comparer, computed, IComputedValue } from "mobx";
|
||||
import React from "react";
|
||||
import type { RouteComponentProps } from "react-router";
|
||||
import type { RequireExactlyOne } from "type-fest";
|
||||
import type { CustomResourceDefinition } from "../../../common/k8s-api/endpoints";
|
||||
import { crdURL, crdDefinitionsRoute } from "../../../common/routes";
|
||||
import { customResourceDefinitionsURL, customResourceDefinitionsRoute, CustomResourceDefinitionsRouteParams } from "../../../common/routes";
|
||||
import type { TabLayoutRoute } from "../layout/tab-layout";
|
||||
import { CrdList } from "./crd-list";
|
||||
import { CrdResources } from "./crd-resources";
|
||||
import { CustomResourceDefinitions } from "./crd-list";
|
||||
import { CustomResourceDefinitionObjectList } from "./crd-resources";
|
||||
import groupedCustomResourceDefinitionsInjectable from "./grouped-custom-resources.injectable";
|
||||
|
||||
export interface CustomResourceTabLayoutRoute extends TabLayoutRoute {
|
||||
export interface CustomResourceTabLayoutRoute extends Omit<TabLayoutRoute, "component"> {
|
||||
id: string;
|
||||
component: React.ComponentType<RouteComponentProps<CustomResourceDefinitionsRouteParams>>;
|
||||
}
|
||||
|
||||
export interface CustomResourceGroupTabLayoutRoute extends CustomResourceTabLayoutRoute {
|
||||
subRoutes?: CustomResourceTabLayoutRoute[];
|
||||
}
|
||||
export type CustomResourceGroupTabLayoutRoute = Omit<TabLayoutRoute, "component"> & {
|
||||
id: string;
|
||||
} & RequireExactlyOne<{
|
||||
subRoutes: CustomResourceTabLayoutRoute[];
|
||||
component: React.ComponentType<{}>;
|
||||
}>;
|
||||
|
||||
interface Dependencies {
|
||||
customResourcesDefinitions: IComputedValue<Map<string, CustomResourceDefinition[]>>;
|
||||
}
|
||||
|
||||
function getRouteTabs({ customResourcesDefinitions }: Dependencies) {
|
||||
function getRouteTabs({ customResourcesDefinitions }: Dependencies): IComputedValue<CustomResourceGroupTabLayoutRoute[]> {
|
||||
return computed(() => {
|
||||
const definitionsUrl = customResourceDefinitionsURL();
|
||||
|
||||
const tabs: CustomResourceGroupTabLayoutRoute[] = [
|
||||
{
|
||||
id: "definitions",
|
||||
title: "Definitions",
|
||||
component: CrdList,
|
||||
url: crdURL(),
|
||||
routePath: String(crdDefinitionsRoute.path),
|
||||
component: () => <CustomResourceDefinitions />,
|
||||
url: definitionsUrl,
|
||||
routePath: definitionsUrl,
|
||||
exact: true,
|
||||
},
|
||||
];
|
||||
|
||||
for (const [group, definitions] of customResourcesDefinitions.get()) {
|
||||
const groupUrl = customResourceDefinitionsURL({ params: { group }});
|
||||
|
||||
tabs.push({
|
||||
id: `crd-group:${group}`,
|
||||
title: group,
|
||||
routePath: crdURL({ query: { groups: group }}),
|
||||
component: CrdResources,
|
||||
url: groupUrl,
|
||||
routePath: groupUrl,
|
||||
subRoutes: definitions.map(crd => ({
|
||||
id: `crd-resource:${crd.getResourceApiBase()}`,
|
||||
title: crd.getResourceKind(),
|
||||
routePath: crd.getResourceUrl(),
|
||||
component: CrdResources,
|
||||
url: crd.getResourceUrl(),
|
||||
routePath: customResourceDefinitionsRoute.path,
|
||||
component: (props) => <CustomResourceDefinitionObjectList {...props} />,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}, {
|
||||
equals: comparer.shallow,
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Redirect, Route, Switch } from "react-router";
|
||||
import { TabLayout } from "../layout/tab-layout";
|
||||
import { crdURL } from "../../../common/routes";
|
||||
import { customResourceDefinitionsURL } from "../../../common/routes";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { CustomResourceGroupTabLayoutRoute } from "./route-tabs.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
@ -21,16 +21,26 @@ const NonInjectedCustomResourcesRoute = observer(({ routes }: Dependencies) => (
|
||||
<TabLayout>
|
||||
<Switch>
|
||||
{
|
||||
routes.get().map(({ id, component, routePath, exact }) => (
|
||||
routes.get()
|
||||
.flatMap(({ id, component, routePath, exact, subRoutes }) => (
|
||||
subRoutes?.map(({ id, component, routePath, exact }) => (
|
||||
<Route
|
||||
key={id}
|
||||
component={component}
|
||||
path={routePath}
|
||||
exact={exact}
|
||||
/>
|
||||
)) ?? (
|
||||
<Route
|
||||
key={id}
|
||||
component={component}
|
||||
path={routePath}
|
||||
exact={exact}
|
||||
/>
|
||||
)
|
||||
))
|
||||
}
|
||||
<Redirect to={crdURL()}/>
|
||||
<Redirect to={customResourceDefinitionsURL()}/>
|
||||
</Switch>
|
||||
</TabLayout>
|
||||
));
|
||||
|
||||
@ -9,7 +9,7 @@ import { observer } from "mobx-react";
|
||||
import customResourcesRouteTabsInjectable, { type CustomResourceGroupTabLayoutRoute } from "./route-tabs.injectable";
|
||||
import type { IsAllowedResource } from "../../../common/utils/is-allowed-resource.injectable";
|
||||
import isAllowedResourceInjectable from "../../../common/utils/is-allowed-resource.injectable";
|
||||
import { crdURL, crdRoute } from "../../../common/routes";
|
||||
import { customResourceDefinitionsURL, customResourcesRoute } from "../../../common/routes";
|
||||
import { isActiveRoute } from "../../navigation";
|
||||
import { Icon } from "../icon";
|
||||
import { SidebarItem } from "../layout/sidebar-item";
|
||||
@ -35,8 +35,8 @@ const NonInjectedCustomResourcesSidebarItem = observer(({ routes, isAllowedResou
|
||||
<SidebarItem
|
||||
id="custom-resources"
|
||||
text="Custom Resources"
|
||||
url={crdURL()}
|
||||
isActive={isActiveRoute(crdRoute)}
|
||||
url={customResourceDefinitionsURL()}
|
||||
isActive={isActiveRoute(customResourcesRoute)}
|
||||
isHidden={!isAllowedResource("customresourcedefinitions")}
|
||||
icon={<Icon material="extension"/>}
|
||||
>
|
||||
@ -45,13 +45,13 @@ const NonInjectedCustomResourcesSidebarItem = observer(({ routes, isAllowedResou
|
||||
key={route.id}
|
||||
id={route.id}
|
||||
text={route.title}
|
||||
url={route.routePath}
|
||||
url={route.url}
|
||||
>
|
||||
{route.subRoutes?.map((subRoute) => (
|
||||
<SidebarItem
|
||||
key={subRoute.id}
|
||||
id={subRoute.id}
|
||||
url={subRoute.routePath}
|
||||
url={subRoute.url}
|
||||
text={subRoute.title}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -154,7 +154,7 @@ function getInternalCommands({ openCommandDialog, getEntitySettingItems, createT
|
||||
id: "cluster.viewCustomResourceDefinitions",
|
||||
title: "Cluster: View Custom Resource Definitions",
|
||||
isActive: isKubernetesClusterActive,
|
||||
action: ({ navigate }) => navigate(routes.crdURL()),
|
||||
action: ({ navigate }) => navigate(routes.customResourceDefinitionsURL()),
|
||||
},
|
||||
{
|
||||
id: "entity.viewSettings",
|
||||
|
||||
@ -23,7 +23,7 @@ export interface TabLayoutProps {
|
||||
export interface TabLayoutRoute {
|
||||
routePath: string;
|
||||
title: React.ReactNode;
|
||||
component: React.ComponentType<any>;
|
||||
component: React.ComponentType<{}>;
|
||||
url?: string; // page-url, if not provided `routePath` is used (doesn't work when path has some :placeholder(s))
|
||||
exact?: boolean; // route-path matching rule
|
||||
default?: boolean; // initial tab to open with provided `url, by default tabs[0] is used
|
||||
|
||||
@ -155,7 +155,7 @@ class NonInjectedClusterFrame extends React.Component<Dependencies> {
|
||||
<Route component={StorageRoute} {...routes.storageRoute}/>
|
||||
<Route component={NamespacesRoute} {...routes.namespacesRoute}/>
|
||||
<Route component={Events} {...routes.eventRoute}/>
|
||||
<Route component={CustomResourcesRoute} {...routes.crdRoute}/>
|
||||
<Route component={CustomResourcesRoute} {...routes.customResourcesRoute}/>
|
||||
<Route component={UserManagementRoute} {...routes.usersManagementRoute}/>
|
||||
<Route component={HelmRoute} {...routes.helmRoute}/>
|
||||
{this.renderExtensionTabLayoutRoutes()}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user