diff --git a/src/extensions/registries/workloads-overview-detail-registry.ts b/src/extensions/registries/workloads-overview-detail-registry.ts index b148a21f7c..9214d61c90 100644 --- a/src/extensions/registries/workloads-overview-detail-registry.ts +++ b/src/extensions/registries/workloads-overview-detail-registry.ts @@ -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; + Details: React.ComponentType<{}>; } export interface WorkloadsOverviewDetailRegistration { @@ -31,10 +32,16 @@ export interface WorkloadsOverviewDetailRegistration { priority?: number; } -export class WorkloadsOverviewDetailRegistry extends BaseRegistry { - getItems() { - const items = super.getItems(); +type RegisteredWorkloadsOverviewDetail = Required; - return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50)); +export class WorkloadsOverviewDetailRegistry extends BaseRegistry { + getItems() { + return orderBy(super.getItems(), "priority", "desc"); + } + + protected getRegisteredItem(item: WorkloadsOverviewDetailRegistration): RegisteredWorkloadsOverviewDetail { + const { priority = 50, ...rest } = item; + + return { priority, ...rest }; } } diff --git a/src/renderer/components/+workloads-overview/overview-statuses.scss b/src/renderer/components/+workloads-overview/overview-statuses.scss index 366839bbe8..8a8c96cc6b 100644 --- a/src/renderer/components/+workloads-overview/overview-statuses.scss +++ b/src/renderer/components/+workloads-overview/overview-statuses.scss @@ -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); diff --git a/src/renderer/components/+workloads-overview/overview-statuses.tsx b/src/renderer/components/+workloads-overview/overview-statuses.tsx index f20b9d25ff..e48c4ff8b8 100644 --- a/src/renderer/components/+workloads-overview/overview-statuses.tsx +++ b/src/renderer/components/+workloads-overview/overview-statuses.tsx @@ -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 (
-
-
Overview
- -
{workloads}
diff --git a/src/renderer/components/+workloads-overview/overview.scss b/src/renderer/components/+workloads-overview/overview.scss index 68b0bb9a95..ff7e84145a 100644 --- a/src/renderer/components/+workloads-overview/overview.scss +++ b/src/renderer/components/+workloads-overview/overview.scss @@ -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); + } + } } diff --git a/src/renderer/components/+workloads-overview/overview.tsx b/src/renderer/components/+workloads-overview/overview.tsx index 695e3edf95..a684a645aa 100644 --- a/src/renderer/components/+workloads-overview/overview.tsx +++ b/src/renderer/components/+workloads-overview/overview.tsx @@ -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 { } @observer export class WorkloadsOverview extends React.Component { + @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 ( + + {this.loadErrors.map((error, index) =>

{error}

)} + + ), + preferredPositions: TooltipPosition.BOTTOM, + }} + /> + ); + } + render() { - const items = WorkloadsOverviewDetailRegistry.getInstance().getItems().map((item, index) => { - return ( - - ); - }); + const items = WorkloadsOverviewDetailRegistry + .getInstance() + .getItems() + .map(({ components: { Details }}, index) => ( +
+ )); return (
+
+
Overview
+ {this.renderLoadErrors()} + +
{items}
); diff --git a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx index d74f05c839..4bfe34461e 100644 --- a/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx +++ b/src/renderer/components/kube-object-list-layout/kube-object-list-layout.tsx @@ -67,7 +67,7 @@ export class KubeObjectListLayout 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; }), diff --git a/src/renderer/initializers/workloads-overview-detail-registry.tsx b/src/renderer/initializers/workloads-overview-detail-registry.tsx index 172938ad23..e581f9f7e6 100644 --- a/src/renderer/initializers/workloads-overview-detail-registry.tsx +++ b/src/renderer/initializers/workloads-overview-detail-registry.tsx @@ -30,7 +30,7 @@ export function initWorkloadsOverviewDetailRegistry() { .add([ { components: { - Details: (props: any) => , + Details: OverviewStatuses, }, }, {