+
{isLoading ? title : `${resources.length} ${title}`}
+ {isLoading ?
: (
+
+ {Object.keys(groups).filter(key => groups[key].count > 0).map((key, index) => (
+
+ ))}
+
+ )}
+
+ );
+});
+
+export type StatusGroupMapper = (resources: K8sResourceKind[], additionalResources?: {[key: string]: K8sResourceKind[]}) => {[key in InventoryStatusGroup | string]: {filterType?: string, statusIDs: string[], count: number}};
+
+type StatusProps = {
+ groupID: InventoryStatusGroup | string;
+ count: number;
+ statusIDs: string[];
+ kind: K8sKind;
+ namespace?: string;
+ filterType?: string;
+}
+
+type InventoryItemProps = {
+ resources: K8sResourceKind[];
+ additionalResources?: {[key: string]: K8sResourceKind[]};
+ mapper: StatusGroupMapper;
+ kind: K8sKind;
+ useAbbr?: boolean;
+ isLoading: boolean;
+ namespace?: string;
+}
diff --git a/frontend/public/components/dashboard/inventory-card/status-group.ts b/frontend/public/components/dashboard/inventory-card/status-group.ts
new file mode 100644
index 00000000000..2df76afe628
--- /dev/null
+++ b/frontend/public/components/dashboard/inventory-card/status-group.ts
@@ -0,0 +1,7 @@
+export enum InventoryStatusGroup {
+ OK = 'OK',
+ WARN = 'WARN',
+ ERROR = 'ERROR',
+ PROGRESS = 'PROGRESS',
+ NOT_MAPPED = 'NOT_MAPPED',
+}
diff --git a/frontend/public/components/dashboard/inventory-card/utils.ts b/frontend/public/components/dashboard/inventory-card/utils.ts
new file mode 100644
index 00000000000..f85049363f8
--- /dev/null
+++ b/frontend/public/components/dashboard/inventory-card/utils.ts
@@ -0,0 +1,50 @@
+import { podPhaseFilterReducer, nodeStatus } from '../../../module/k8s';
+import { pvcPhase } from '../../persistent-volume-claim';
+import { StatusGroupMapper } from './inventory-item';
+import { InventoryStatusGroup } from './status-group';
+
+const POD_PHASE_GROUP_MAPPING = {
+ [InventoryStatusGroup.OK]: ['Running', 'Succeeded'],
+ [InventoryStatusGroup.ERROR]: ['CrashLoopBackOff', 'Failed'],
+ [InventoryStatusGroup.PROGRESS]: ['Terminating', 'Pending'],
+ [InventoryStatusGroup.WARN]: ['Unknown'],
+};
+
+const PVC_STATUS_GROUP_MAPPING = {
+ [InventoryStatusGroup.OK]: ['Bound'],
+ [InventoryStatusGroup.ERROR]: ['Lost'],
+ [InventoryStatusGroup.PROGRESS]: ['Pending'],
+};
+
+const NODE_STATUS_GROUP_MAPPING = {
+ [InventoryStatusGroup.OK]: ['Ready'],
+ [InventoryStatusGroup.PROGRESS]: ['Not Ready'],
+};
+
+const getStatusGroups = (resources, mapping, mapper, filterType) => {
+ const groups = {
+ [InventoryStatusGroup.NOT_MAPPED]: {
+ statusIDs: [],
+ count: 0,
+ },
+ };
+ Object.keys(mapping).forEach(key => {
+ groups[key] = {
+ statusIDs: [...mapping[key]],
+ count: 0,
+ filterType,
+ };
+ });
+
+ resources.forEach(resource => {
+ const status = mapper(resource);
+ const group = Object.keys(mapping).find(key => mapping[key].includes(status)) || InventoryStatusGroup.NOT_MAPPED;
+ groups[group].count++;
+ });
+
+ return groups;
+};
+
+export const getPodStatusGroups: StatusGroupMapper = resources => getStatusGroups(resources, POD_PHASE_GROUP_MAPPING, podPhaseFilterReducer, 'pod-status');
+export const getNodeStatusGroups: StatusGroupMapper = resources => getStatusGroups(resources, NODE_STATUS_GROUP_MAPPING, nodeStatus, 'node-status');
+export const getPVCStatusGroups: StatusGroupMapper = resources => getStatusGroups(resources, PVC_STATUS_GROUP_MAPPING, pvcPhase, 'pvc-status');
diff --git a/frontend/public/components/dashboards-page/dashboards.tsx b/frontend/public/components/dashboards-page/dashboards.tsx
index 4dc53912bc1..37552fde784 100644
--- a/frontend/public/components/dashboards-page/dashboards.tsx
+++ b/frontend/public/components/dashboards-page/dashboards.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
+import { Map as ImmutableMap } from 'immutable';
import * as plugins from '../../plugins';
import { OverviewDashboard } from './overview-dashboard/overview-dashboard';
@@ -41,8 +42,8 @@ const tabs: Page[] = [
...getPluginTabPages(),
];
-const DashboardsPage_: React.FC