2
0
Эх сурвалжийг харах

allow filtering jobs by last run status

Anukul Sangwan 4 жил өмнө
parent
commit
26b754fcb2

+ 23 - 13
dashboard/src/main/home/cluster-dashboard/ClusterDashboard.tsx

@@ -5,7 +5,7 @@ import monoweb from "assets/monoweb.png";
 import { Route, Switch } from "react-router-dom";
 
 import { Context } from "shared/Context";
-import { ChartType, ClusterType } from "shared/types";
+import { ChartType, ClusterType, JobStatusType } from "shared/types";
 import {
   getQueryParam,
   PorterUrl,
@@ -25,6 +25,7 @@ import api from "shared/api";
 import DashboardRoutes from "./dashboard/Routes";
 import GuardedRoute from "shared/auth/RouteGuard";
 import { withAuth, WithAuthProps } from "shared/auth/AuthorizationHoc";
+import LastRunStatusSelector from "./LastRunStatusSelector";
 
 type PropsType = RouteComponentProps &
   WithAuthProps & {
@@ -36,6 +37,7 @@ type PropsType = RouteComponentProps &
 type StateType = {
   namespace: string;
   sortType: string;
+  lastRunStatus: JobStatusType | null;
   currentChart: ChartType | null;
   isMetricsInstalled: boolean;
 };
@@ -47,6 +49,7 @@ class ClusterDashboard extends Component<PropsType, StateType> {
     sortType: localStorage.getItem("SortType")
       ? localStorage.getItem("SortType")
       : "Newest",
+    lastRunStatus: null as null,
     currentChart: null as ChartType | null,
     isMetricsInstalled: false,
   };
@@ -130,7 +133,7 @@ class ClusterDashboard extends Component<PropsType, StateType> {
     );
     return (
       <>
-        <ControlRow hasMultipleChilds={isAuthorizedToAdd}>
+        <ControlRow>
           {isAuthorizedToAdd && (
             <Button
               onClick={() =>
@@ -141,10 +144,14 @@ class ClusterDashboard extends Component<PropsType, StateType> {
             </Button>
           )}
           <SortFilterWrapper>
-            <SortSelector
-              setSortType={(sortType) => this.setState({ sortType })}
-              sortType={this.state.sortType}
-            />
+            {currentView === "jobs" && (
+              <LastRunStatusSelector
+                lastRunStatus={this.state.lastRunStatus}
+                setLastRunStatus={(lastRunStatus: JobStatusType) => {
+                  this.setState({ lastRunStatus });
+                }}
+              />
+            )}
             <NamespaceSelector
               setNamespace={(namespace) =>
                 this.setState({ namespace }, () => {
@@ -155,12 +162,17 @@ class ClusterDashboard extends Component<PropsType, StateType> {
               }
               namespace={this.state.namespace}
             />
+            <SortSelector
+              setSortType={(sortType) => this.setState({ sortType })}
+              sortType={this.state.sortType}
+            />
           </SortFilterWrapper>
         </ControlRow>
 
         <ChartList
           currentView={currentView}
           currentCluster={currentCluster}
+          lastRunStatus={this.state.lastRunStatus}
           namespace={this.state.namespace}
           sortType={this.state.sortType}
         />
@@ -239,12 +251,8 @@ const Br = styled.div`
 
 const ControlRow = styled.div`
   display: flex;
-  justify-content: ${(props: { hasMultipleChilds: boolean }) => {
-    if (props.hasMultipleChilds) {
-      return "space-between";
-    }
-    return "flex-end";
-  }};
+  margin-left: auto;
+  justify-content: space-between;
   align-items: center;
   margin-bottom: 35px;
   padding-left: 0px;
@@ -389,7 +397,9 @@ const Img = styled.img`
 `;
 
 const SortFilterWrapper = styled.div`
-  width: 468px;
   display: flex;
   justify-content: space-between;
+  > div:not(:first-child) {
+    margin-left: 30px;
+  }
 `;

+ 61 - 0
dashboard/src/main/home/cluster-dashboard/LastRunStatusSelector.tsx

@@ -0,0 +1,61 @@
+import React from "react";
+import styled from "styled-components";
+
+import Selector from "components/Selector";
+import { JobStatusType } from "shared/types";
+
+type PropsType = {
+  lastRunStatus: JobStatusType;
+  setLastRunStatus: (lastRunStatus: JobStatusType) => void;
+};
+
+const LastRunStatusSelector = (props: PropsType) => {
+  const options = [
+    {
+      label: "All",
+      value: null,
+    },
+  ].concat(
+    Object.entries(JobStatusType).map((status) => ({
+      label: status[0],
+      value: status[1],
+    }))
+  );
+
+  return (
+    <StyledLastRunStatusSelector>
+      <Label>
+        <i className="material-icons">filter_alt</i>
+        Last Run Status
+      </Label>
+      <Selector
+        activeValue={props.lastRunStatus}
+        setActiveValue={props.setLastRunStatus}
+        options={options}
+        dropdownLabel="Last Run Status"
+        width="150px"
+        dropdownWidth="230px"
+        closeOverlay={true}
+      />
+    </StyledLastRunStatusSelector>
+  );
+};
+
+export default LastRunStatusSelector;
+
+const Label = styled.div`
+  display: flex;
+  align-items: center;
+  margin-right: 12px;
+
+  > i {
+    margin-right: 8px;
+    font-size: 18px;
+  }
+`;
+
+const StyledLastRunStatusSelector = styled.div`
+  display: flex;
+  align-items: center;
+  font-size: 13px;
+`;

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/NamespaceSelector.tsx

@@ -100,7 +100,7 @@ export default class NamespaceSelector extends Component<PropsType, StateType> {
     return (
       <StyledNamespaceSelector>
         <Label>
-          <i className="material-icons">filter_alt</i> Filter
+          <i className="material-icons">filter_alt</i> Namespace
         </Label>
         <Selector
           activeValue={this.props.namespace}

+ 28 - 11
dashboard/src/main/home/cluster-dashboard/chart/ChartList.tsx

@@ -19,6 +19,7 @@ import { useWebsockets } from "shared/hooks/useWebsockets";
 
 type Props = {
   currentCluster: ClusterType;
+  lastRunStatus?: JobStatusType | null;
   namespace: string;
   // TODO Convert to enum
   sortType: string;
@@ -30,6 +31,7 @@ interface JobStatusWithTimeAndVersion extends JobStatusWithTimeType {
 }
 
 const ChartList: React.FunctionComponent<Props> = ({
+  lastRunStatus,
   namespace,
   sortType,
   currentView,
@@ -295,14 +297,29 @@ const ChartList: React.FunctionComponent<Props> = ({
   }, [namespace, currentView]);
 
   const filteredCharts = useMemo(() => {
-    const result = charts.filter((chart: ChartType) => {
-      return (
-        (currentView == "jobs" && chart.chart.metadata.name == "job") ||
-        ((currentView == "applications" ||
-          currentView == "cluster-dashboard") &&
-          chart.chart.metadata.name != "job")
-      );
-    });
+    const result = charts
+      .filter((chart: ChartType) => {
+        return (
+          (currentView == "jobs" && chart.chart.metadata.name == "job") ||
+          ((currentView == "applications" ||
+            currentView == "cluster-dashboard") &&
+            chart.chart.metadata.name != "job")
+        );
+      })
+      .filter((chart: ChartType) => {
+        if (currentView !== "jobs") {
+          return true;
+        }
+        if (lastRunStatus === null) {
+          return true;
+        }
+        const status: JobStatusWithTimeAndVersion = _.get(
+          jobStatus,
+          getChartKey(chart.name, chart.namespace),
+          null
+        );
+        return !status || status.status === lastRunStatus;
+      });
 
     if (sortType == "Newest") {
       result.sort((a: any, b: any) =>
@@ -321,7 +338,7 @@ const ChartList: React.FunctionComponent<Props> = ({
     }
 
     return result;
-  }, [charts, sortType]);
+  }, [charts, sortType, jobStatus, lastRunStatus]);
 
   const renderChartList = () => {
     if (isLoading || (!namespace && namespace !== "")) {
@@ -340,8 +357,8 @@ const ChartList: React.FunctionComponent<Props> = ({
       return (
         <Placeholder>
           <i className="material-icons">category</i> No
-          {currentView === "jobs" ? ` jobs` : ` charts`} found in this
-          namespace.
+          {currentView === "jobs" ? ` jobs` : ` charts`} found with the given
+          filters.
         </Placeholder>
       );
     }