mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Catch and display load errors for WorkloadsOverview (#4393)
This commit is contained in:
parent
0e5fc65806
commit
78a4e2a126
@ -19,11 +19,12 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { orderBy } from "lodash";
|
||||
import type React from "react";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
|
||||
export interface WorkloadsOverviewDetailComponents {
|
||||
Details: React.ComponentType<any>;
|
||||
Details: React.ComponentType<{}>;
|
||||
}
|
||||
|
||||
export interface WorkloadsOverviewDetailRegistration {
|
||||
@ -31,10 +32,16 @@ export interface WorkloadsOverviewDetailRegistration {
|
||||
priority?: number;
|
||||
}
|
||||
|
||||
export class WorkloadsOverviewDetailRegistry extends BaseRegistry<WorkloadsOverviewDetailRegistration> {
|
||||
getItems() {
|
||||
const items = super.getItems();
|
||||
type RegisteredWorkloadsOverviewDetail = Required<WorkloadsOverviewDetailRegistration>;
|
||||
|
||||
return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
|
||||
export class WorkloadsOverviewDetailRegistry extends BaseRegistry<WorkloadsOverviewDetailRegistration, RegisteredWorkloadsOverviewDetail> {
|
||||
getItems() {
|
||||
return orderBy(super.getItems(), "priority", "desc");
|
||||
}
|
||||
|
||||
protected getRegisteredItem(item: WorkloadsOverviewDetailRegistration): RegisteredWorkloadsOverviewDetail {
|
||||
const { priority = 50, ...rest } = item;
|
||||
|
||||
return { priority, ...rest };
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,15 +25,6 @@
|
||||
min-width: $unit * 75;
|
||||
background: var(--contentColor);
|
||||
|
||||
> .header {
|
||||
position: relative;
|
||||
padding: $padding * 2;
|
||||
|
||||
h5 {
|
||||
color: var(--textColorPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
.workloads {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, 180px);
|
||||
|
||||
@ -27,7 +27,6 @@ import { OverviewWorkloadStatus } from "./overview-workload-status";
|
||||
import { Link } from "react-router-dom";
|
||||
import { workloadStores } from "../+workloads";
|
||||
import { namespaceStore } from "../+namespaces/namespace.store";
|
||||
import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
|
||||
import type { KubeResource } from "../../../common/rbac";
|
||||
import { ResourceNames } from "../../utils/rbac";
|
||||
import { boundMethod } from "../../utils";
|
||||
@ -73,10 +72,6 @@ export class OverviewStatuses extends React.Component {
|
||||
|
||||
return (
|
||||
<div className="OverviewStatuses">
|
||||
<div className="header flex gaps align-center">
|
||||
<h5 className="box grow">Overview</h5>
|
||||
<NamespaceSelectFilter />
|
||||
</div>
|
||||
<div className="workloads">
|
||||
{workloads}
|
||||
</div>
|
||||
|
||||
@ -22,4 +22,18 @@
|
||||
.WorkloadsOverview {
|
||||
--flex-gap: #{$padding * 2};
|
||||
min-height: 100%;
|
||||
|
||||
.header {
|
||||
background: var(--contentColor);
|
||||
position: relative;
|
||||
padding: $padding * 2;
|
||||
|
||||
h5 {
|
||||
color: var(--textColorPrimary);
|
||||
}
|
||||
|
||||
.Icon.load-error {
|
||||
color: var(--colorWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,36 +33,77 @@ import { replicaSetStore } from "../+workloads-replicasets/replicasets.store";
|
||||
import { jobStore } from "../+workloads-jobs/job.store";
|
||||
import { cronJobStore } from "../+workloads-cronjobs/cronjob.store";
|
||||
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
|
||||
import { clusterContext } from "../context";
|
||||
import { WorkloadsOverviewDetailRegistry } from "../../../extensions/registries";
|
||||
import type { WorkloadsOverviewRouteParams } from "../../../common/routes";
|
||||
import { makeObservable, observable, reaction } from "mobx";
|
||||
import { clusterContext } from "../context";
|
||||
import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
|
||||
import { Icon } from "../icon";
|
||||
import { TooltipPosition } from "../tooltip";
|
||||
|
||||
interface Props extends RouteComponentProps<WorkloadsOverviewRouteParams> {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WorkloadsOverview extends React.Component<Props> {
|
||||
@observable loadErrors: string[] = [];
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
kubeWatchApi.subscribeStores([
|
||||
podsStore, deploymentStore, daemonSetStore, statefulSetStore, replicaSetStore,
|
||||
jobStore, cronJobStore, eventStore,
|
||||
], {
|
||||
preload: true,
|
||||
namespaces: clusterContext.contextNamespaces,
|
||||
onLoadFailure: error => this.loadErrors.push(String(error)),
|
||||
}),
|
||||
reaction(() => clusterContext.contextNamespaces.slice(), () => {
|
||||
// clear load errors
|
||||
this.loadErrors.length = 0;
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
renderLoadErrors() {
|
||||
if (this.loadErrors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Icon
|
||||
material="warning"
|
||||
className="load-error"
|
||||
tooltip={{
|
||||
children: (
|
||||
<>
|
||||
{this.loadErrors.map((error, index) => <p key={index}>{error}</p>)}
|
||||
</>
|
||||
),
|
||||
preferredPositions: TooltipPosition.BOTTOM,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const items = WorkloadsOverviewDetailRegistry.getInstance().getItems().map((item, index) => {
|
||||
return (
|
||||
<item.components.Details key={`workload-overview-${index}`}/>
|
||||
);
|
||||
});
|
||||
const items = WorkloadsOverviewDetailRegistry
|
||||
.getInstance()
|
||||
.getItems()
|
||||
.map(({ components: { Details }}, index) => (
|
||||
<Details key={`workload-overview-${index}`}/>
|
||||
));
|
||||
|
||||
return (
|
||||
<div className="WorkloadsOverview flex column gaps">
|
||||
<div className="header flex gaps align-center">
|
||||
<h5 className="box grow">Overview</h5>
|
||||
{this.renderLoadErrors()}
|
||||
<NamespaceSelectFilter />
|
||||
</div>
|
||||
{items}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -67,7 +67,7 @@ export class KubeObjectListLayout<K extends KubeObject> extends React.Component<
|
||||
const { store, dependentStores = [], subscribeStores } = this.props;
|
||||
const stores = Array.from(new Set([store, ...dependentStores]));
|
||||
const reactions: Disposer[] = [
|
||||
reaction(() => clusterContext.contextNamespaces.length, () => {
|
||||
reaction(() => clusterContext.contextNamespaces.slice(), () => {
|
||||
// clear load errors
|
||||
this.loadErrors.length = 0;
|
||||
}),
|
||||
|
||||
@ -30,7 +30,7 @@ export function initWorkloadsOverviewDetailRegistry() {
|
||||
.add([
|
||||
{
|
||||
components: {
|
||||
Details: (props: any) => <OverviewStatuses {...props} />,
|
||||
Details: OverviewStatuses,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user