mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
auto-refresh menu, no-clusters page + navigation fixes
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
1 parent
408f64c184
commit
fe06643a8e
13 files changed
+109
-90
No files matched your search
@@ -8,7 +8,7 @@ import type { KubeObjectStore } from "../kube-object.store";
|
||||
import { KubeApi } from "./kube-api";
|
||||
import { apiManager } from "./api-manager";
|
||||
import { apiPrefix, isDevelopment } from "../../common/vars";
|
||||
import { clusterStore } from "../../common/cluster-store";
|
||||
import { getHostedCluster } from "../../common/cluster-store";
|
||||
|
||||
export interface IKubeWatchEvent<T = any> {
|
||||
type: "ADDED" | "MODIFIED" | "DELETED";
|
||||
@@ -61,7 +61,7 @@ export class KubeWatchApi {
|
||||
}
|
||||
|
||||
protected getQuery(): Partial<IKubeWatchRouteQuery> {
|
||||
const { isAdmin, allowedNamespaces } = clusterStore.activeCluster;
|
||||
const { isAdmin, allowedNamespaces } = getHostedCluster();
|
||||
return {
|
||||
api: this.activeApis.map(api => {
|
||||
if (isAdmin) return api.getWatchUrl();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { clusterStore } from "../../common/cluster-store";
|
||||
import { getHostedCluster } from "../../common/cluster-store";
|
||||
|
||||
// todo: refactor / move to cluster-store.ts?
|
||||
|
||||
@@ -6,7 +6,7 @@ export function isAllowedResource(resources: string | string[]) {
|
||||
if (!Array.isArray(resources)) {
|
||||
resources = [resources];
|
||||
}
|
||||
const allowedResources = clusterStore.activeCluster?.allowedResources || [];
|
||||
const { allowedResources } = getHostedCluster();
|
||||
for (const resource of resources) {
|
||||
if (!allowedResources.includes(resource)) {
|
||||
return false;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { HelmRelease, helmReleasesApi, IReleaseCreatePayload, IReleaseUpdatePayl
|
||||
import { ItemStore } from "../../item.store";
|
||||
import { Secret } from "../../api/endpoints";
|
||||
import { secretsStore } from "../+config-secrets/secrets.store";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
import { getHostedCluster } from "../../../common/cluster-store";
|
||||
|
||||
@autobind()
|
||||
export class ReleaseStore extends ItemStore<HelmRelease> {
|
||||
@@ -58,7 +58,7 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
|
||||
this.isLoading = true;
|
||||
let items;
|
||||
try {
|
||||
const { isAdmin, allowedNamespaces } = clusterStore.activeCluster;
|
||||
const { isAdmin, allowedNamespaces } = getHostedCluster();
|
||||
items = await this.loadItems(!isAdmin ? allowedNamespaces : null);
|
||||
} finally {
|
||||
if (items) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
position: relative;
|
||||
opacity: .75;
|
||||
border-radius: $radius;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.active, &.interactive:hover {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "./app.scss";
|
||||
import React from "react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { autorun, computed, observable } from "mobx";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { Redirect, Route, Switch } from "react-router";
|
||||
import { Notifications } from "./notifications";
|
||||
import { NotFound } from "./+404";
|
||||
@@ -28,7 +28,7 @@ import { CustomResources } from "./+custom-resources/custom-resources";
|
||||
import { crdRoute } from "./+custom-resources";
|
||||
import { isAllowedResource } from "../api/rbac";
|
||||
import { AddCluster, addClusterRoute } from "./+add-cluster";
|
||||
import { LandingPage, landingRoute } from "./+landing-page";
|
||||
import { LandingPage, landingRoute, landingURL } from "./+landing-page";
|
||||
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
|
||||
import { Workspaces, workspacesRoute } from "./+workspaces";
|
||||
import { ErrorBoundary } from "./error-boundary";
|
||||
@@ -44,36 +44,41 @@ import { navigate, navigation } from "../navigation";
|
||||
export class App extends React.Component {
|
||||
@observable isReady = false;
|
||||
|
||||
@computed get clusterReady(): boolean {
|
||||
const cluster = getHostedCluster();
|
||||
if (cluster) {
|
||||
return cluster.initialized && cluster.accessible;
|
||||
}
|
||||
get cluster() {
|
||||
return getHostedCluster()
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await clusterIpc.activate.invokeFromRenderer(); // refresh state, reconnect, etc.
|
||||
this.isReady = true;
|
||||
|
||||
if (this.cluster) {
|
||||
await clusterIpc.activate.invokeFromRenderer(); // refresh state, reconnect, etc.
|
||||
}
|
||||
disposeOnUnmount(this, [
|
||||
autorun(() => {
|
||||
if (!this.clusterReady) {
|
||||
navigate(clusterStatusURL());
|
||||
} else if (clusterStatusURL() == navigation.getPath()) {
|
||||
navigate("/"); // redirect when cluster accessible
|
||||
}
|
||||
reaction(() => this.startURL, this.onStartUrlChange, {
|
||||
fireImmediately: true
|
||||
})
|
||||
])
|
||||
this.isReady = true;
|
||||
}
|
||||
|
||||
protected onStartUrlChange = (startURL: string) => {
|
||||
const path = navigation.getPath();
|
||||
const redirectRequired = ["/", clusterStatusURL()].includes(path);
|
||||
if (redirectRequired || !this.cluster?.accessible) {
|
||||
navigate(startURL);
|
||||
}
|
||||
}
|
||||
|
||||
get startURL() {
|
||||
if (!this.clusterReady) {
|
||||
return clusterStatusURL();
|
||||
if (this.cluster) {
|
||||
if (!this.cluster.accessible) {
|
||||
return clusterStatusURL();
|
||||
}
|
||||
if (isAllowedResource(["events", "nodes", "pods"])) {
|
||||
return clusterURL();
|
||||
}
|
||||
return workloadsURL();
|
||||
}
|
||||
if (isAllowedResource(["events", "nodes", "pods"])) {
|
||||
return clusterURL();
|
||||
}
|
||||
return workloadsURL();
|
||||
return landingURL();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -87,19 +92,23 @@ export class App extends React.Component {
|
||||
<Route component={Preferences} {...preferencesRoute}/>
|
||||
<Route component={Workspaces} {...workspacesRoute}/>
|
||||
<Route component={AddCluster} {...addClusterRoute}/>
|
||||
<Route component={Cluster} {...clusterRoute}/>
|
||||
<Route component={ClusterStatus} {...clusterStatusRoute}/>
|
||||
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
|
||||
<Route component={Nodes} {...nodesRoute}/>
|
||||
<Route component={Workloads} {...workloadsRoute}/>
|
||||
<Route component={Config} {...configRoute}/>
|
||||
<Route component={Network} {...networkRoute}/>
|
||||
<Route component={Storage} {...storageRoute}/>
|
||||
<Route component={Namespaces} {...namespacesRoute}/>
|
||||
<Route component={Events} {...eventRoute}/>
|
||||
<Route component={CustomResources} {...crdRoute}/>
|
||||
<Route component={UserManagement} {...usersManagementRoute}/>
|
||||
<Route component={Apps} {...appsRoute}/>
|
||||
{this.cluster && (
|
||||
<>
|
||||
<Route component={Cluster} {...clusterRoute}/>
|
||||
<Route component={ClusterStatus} {...clusterStatusRoute}/>
|
||||
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
|
||||
<Route component={Nodes} {...nodesRoute}/>
|
||||
<Route component={Workloads} {...workloadsRoute}/>
|
||||
<Route component={Config} {...configRoute}/>
|
||||
<Route component={Network} {...networkRoute}/>
|
||||
<Route component={Storage} {...storageRoute}/>
|
||||
<Route component={Namespaces} {...namespacesRoute}/>
|
||||
<Route component={Events} {...eventRoute}/>
|
||||
<Route component={CustomResources} {...crdRoute}/>
|
||||
<Route component={UserManagement} {...usersManagementRoute}/>
|
||||
<Route component={Apps} {...appsRoute}/>
|
||||
</>
|
||||
)}
|
||||
<Redirect exact from="/" to={this.startURL}/>
|
||||
<Route component={NotFound}/>
|
||||
</Switch>
|
||||
|
||||
@@ -21,13 +21,16 @@ export class ClusterStatus extends React.Component {
|
||||
}
|
||||
|
||||
@computed get cluster() {
|
||||
return getHostedCluster()
|
||||
return getHostedCluster();
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.authOutput = [{ data: "Connecting ...\n" }];
|
||||
ipcRenderer.on(`kube-auth:${this.cluster.id}`, (evt, res) => {
|
||||
this.authOutput.push(res);
|
||||
this.authOutput = [{ data: "Connecting..." }];
|
||||
ipcRenderer.on(`kube-auth:${this.cluster.id}`, (evt, res: KubeAuthProxyResponse) => {
|
||||
this.authOutput.push({
|
||||
data: res.data.trimRight(),
|
||||
error: res.error,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,7 +39,7 @@ export class ClusterStatus extends React.Component {
|
||||
}
|
||||
|
||||
reconnect = async () => {
|
||||
this.authOutput = [{ data: "Reconnecting ...\n" }];
|
||||
this.authOutput = [{ data: "Reconnecting..." }];
|
||||
this.isReconnecting = true;
|
||||
await clusterIpc.activate.invokeFromRenderer();
|
||||
this.isReconnecting = false;
|
||||
|
||||
@@ -56,8 +56,8 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
menu.append(new MenuItem({
|
||||
label: _i18n._(t`Disconnect`),
|
||||
click: async () => {
|
||||
await clusterIpc.disconnect.invokeFromRenderer();
|
||||
navigate(clusterStatusURL());
|
||||
await clusterIpc.disconnect.invokeFromRenderer();
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ErrorBoundary } from "../error-boundary";
|
||||
import { Dock } from "../dock";
|
||||
import { navigate, navigation } from "../../navigation";
|
||||
import { themeStore } from "../../theme.store";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
import { getHostedCluster } from "../../../common/cluster-store";
|
||||
|
||||
export interface TabRoute extends RouteProps {
|
||||
title: React.ReactNode;
|
||||
@@ -47,7 +47,7 @@ export class MainLayout extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const { className, contentClass, headerClass, tabs, footer, footerClass, children } = this.props;
|
||||
const clusterName = clusterStore.activeCluster?.contextName;
|
||||
const { contextName: clusterName } = getHostedCluster();
|
||||
const routePath = navigation.location.pathname;
|
||||
return (
|
||||
<div className={cssNames("MainLayout", className, themeStore.activeTheme.type)}>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ItemStore } from "./item.store";
|
||||
import { apiManager } from "./api/api-manager";
|
||||
import { IKubeApiQueryParams, KubeApi } from "./api/kube-api";
|
||||
import { KubeJsonApiData } from "./api/kube-json-api";
|
||||
import { clusterStore } from "../common/cluster-store";
|
||||
import { getHostedCluster } from "../common/cluster-store";
|
||||
|
||||
@autobind()
|
||||
export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemStore<T> {
|
||||
@@ -76,7 +76,7 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
||||
this.isLoading = true;
|
||||
let items: T[];
|
||||
try {
|
||||
const { isAdmin, allowedNamespaces } = clusterStore.activeCluster;
|
||||
const { isAdmin, allowedNamespaces } = getHostedCluster();
|
||||
items = await this.loadItems(!isAdmin ? allowedNamespaces : null);
|
||||
items = this.filterItemsOnLoad(items);
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user