This is an automated email from the ASF dual-hosted git repository.

pierrejeambrun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new d67b38365d UI Add Cluster Activity Page (#31123)
d67b38365d is described below

commit d67b38365d7f97a6ba334135d45535e8525f5979
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Thu Jun 1 23:17:40 2023 +0200

    UI Add Cluster Activity Page (#31123)
    
    * Dashboard init view
    
    * Live metrics and first page layout
    
    * Rebase and UI improvements
    
    * Add DagRun to dashboard
    
    * Update wording.
    
    * Add filter bar
    
    * Add historical data metrics
    
    * Drop colors for now fix type
    
    * Update following code review
    
    * Use State colors
    
    * Handle data fetch errors
    
    * Add simple top component test
    
    * Add cluster_activity tests
    
    * Add labels to filter bar and period duration for visualization
    
    * FilterBar style
    
    * Sort legend in PieChart
    
    * Add triggerer to health card
    
    * Update UI and wording following Jed review
---
 airflow/security/permissions.py                    |   20 +-
 airflow/www/extensions/init_appbuilder_links.py    |    4 +-
 airflow/www/jest-setup.js                          |    1 +
 airflow/www/package.json                           |    4 +-
 airflow/www/security.py                            |    2 +
 airflow/www/static/js/api/index.ts                 |   16 +-
 airflow/www/static/js/api/useDagRuns.tsx           |   50 +
 airflow/www/static/js/api/useDags.tsx              |   40 +
 airflow/www/static/js/api/useHealth.ts             |   37 +
 .../www/static/js/api/useHistoricalMetricsData.ts  |   40 +
 airflow/www/static/js/api/usePools.ts              |   41 +
 .../historical-metrics/PieChart.tsx                |  147 +++
 .../cluster-activity/historical-metrics/index.tsx  |   95 ++
 .../www/static/js/cluster-activity/index.test.tsx  |  153 +++
 airflow/www/static/js/cluster-activity/index.tsx   |   64 ++
 .../js/cluster-activity/live-metrics/DagRuns.tsx   |  121 ++
 .../js/cluster-activity/live-metrics/Dags.tsx      |   69 ++
 .../js/cluster-activity/live-metrics/Health.tsx    |  116 ++
 .../js/cluster-activity/live-metrics/Pools.tsx     |  132 +++
 .../js/cluster-activity/live-metrics/index.tsx     |   61 +
 .../static/js/cluster-activity/nav/FilterBar.tsx   |  101 ++
 .../www/static/js/cluster-activity/useFilters.tsx  |   95 ++
 .../www/static/js/components/LoadingWrapper.tsx    |   53 +
 airflow/www/static/js/components/ReactECharts.tsx  |   93 ++
 airflow/www/static/js/dag/nav/FilterBar.tsx        |    7 +-
 airflow/www/static/js/types/index.ts               |   16 +-
 .../{datasets.html => cluster_activity.html}       |   18 +-
 airflow/www/templates/airflow/datasets.html        |    2 +
 airflow/www/views.py                               |   83 +-
 airflow/www/webpack.config.js                      |    1 +
 airflow/www/yarn.lock                              | 1177 ++++++++++++--------
 .../endpoints/test_dag_run_endpoint.py             |    1 +
 tests/www/test_security.py                         |    5 +-
 tests/www/views/test_views_cluster_activity.py     |  143 +++
 34 files changed, 2511 insertions(+), 497 deletions(-)

diff --git a/airflow/security/permissions.py b/airflow/security/permissions.py
index adf7af964e..3259b48dc3 100644
--- a/airflow/security/permissions.py
+++ b/airflow/security/permissions.py
@@ -22,25 +22,27 @@ RESOURCE_ADMIN_MENU = "Admin"
 RESOURCE_AIRFLOW = "Airflow"
 RESOURCE_AUDIT_LOG = "Audit Logs"
 RESOURCE_BROWSE_MENU = "Browse"
-RESOURCE_DAG = "DAGs"
-RESOURCE_DAG_PREFIX = "DAG:"
-RESOURCE_LOGIN = "Logins"
-RESOURCE_DOCS_MENU = "Docs"
-RESOURCE_DOCS = "Documentation"
 RESOURCE_CONFIG = "Configurations"
 RESOURCE_CONNECTION = "Connections"
-RESOURCE_DAG_DEPENDENCIES = "DAG Dependencies"
+RESOURCE_DAG = "DAGs"
 RESOURCE_DAG_CODE = "DAG Code"
+RESOURCE_DAG_DEPENDENCIES = "DAG Dependencies"
+RESOURCE_DAG_PREFIX = "DAG:"
 RESOURCE_DAG_RUN = "DAG Runs"
-RESOURCE_IMPORT_ERROR = "ImportError"
 RESOURCE_DAG_WARNING = "DAG Warnings"
+RESOURCE_CLUSTER_ACTIVITY = "Cluster Activity"
+RESOURCE_DATASET = "Datasets"
+RESOURCE_DOCS = "Documentation"
+RESOURCE_DOCS_MENU = "Docs"
+RESOURCE_IMPORT_ERROR = "ImportError"
 RESOURCE_JOB = "Jobs"
+RESOURCE_LOGIN = "Logins"
 RESOURCE_MY_PASSWORD = "My Password"
 RESOURCE_MY_PROFILE = "My Profile"
 RESOURCE_PASSWORD = "Passwords"
 RESOURCE_PERMISSION = "Permission Views"  # Refers to a Perm <-> View mapping, 
not an MVC View.
-RESOURCE_POOL = "Pools"
 RESOURCE_PLUGIN = "Plugins"
+RESOURCE_POOL = "Pools"
 RESOURCE_PROVIDER = "Providers"
 RESOURCE_RESOURCE = "View Menus"
 RESOURCE_ROLE = "Roles"
@@ -54,8 +56,6 @@ RESOURCE_USER_STATS_CHART = "User Stats Chart"
 RESOURCE_VARIABLE = "Variables"
 RESOURCE_WEBSITE = "Website"
 RESOURCE_XCOM = "XComs"
-RESOURCE_DATASET = "Datasets"
-
 
 # Action Constants
 ACTION_CAN_CREATE = "can_create"
diff --git a/airflow/www/extensions/init_appbuilder_links.py 
b/airflow/www/extensions/init_appbuilder_links.py
index f7d747013d..6ae049edcd 100644
--- a/airflow/www/extensions/init_appbuilder_links.py
+++ b/airflow/www/extensions/init_appbuilder_links.py
@@ -26,8 +26,10 @@ def init_appbuilder_links(app):
 
     appbuilder.add_link(name="DAGs", href="Airflow.index")
     appbuilder.menu.menu.insert(0, appbuilder.menu.menu.pop())  # Place in the 
first menu slot
-    appbuilder.add_link(name="Datasets", href="Airflow.datasets")
+    appbuilder.add_link(name="Cluster Activity", 
href="Airflow.cluster_activity")
     appbuilder.menu.menu.insert(1, appbuilder.menu.menu.pop())  # Place in the 
second menu slot
+    appbuilder.add_link(name="Datasets", href="Airflow.datasets")
+    appbuilder.menu.menu.insert(2, appbuilder.menu.menu.pop())  # Place in the 
third menu slot
 
     # Docs links
     appbuilder.add_link(name="Documentation", label="Documentation", 
href=get_docs_url(), category="Docs")
diff --git a/airflow/www/jest-setup.js b/airflow/www/jest-setup.js
index 0a13d7c644..fcab19bc8f 100644
--- a/airflow/www/jest-setup.js
+++ b/airflow/www/jest-setup.js
@@ -22,6 +22,7 @@
 import "@testing-library/jest-dom";
 import axios from "axios";
 import { setLogger } from "react-query";
+import "jest-canvas-mock";
 
 // eslint-disable-next-line import/no-extraneous-dependencies
 import moment from "moment-timezone";
diff --git a/airflow/www/package.json b/airflow/www/package.json
index 15d9279740..5eac374466 100644
--- a/airflow/www/package.json
+++ b/airflow/www/package.json
@@ -66,6 +66,7 @@
     "file-loader": "^6.0.0",
     "imports-loader": "^1.1.0",
     "jest": "^27.3.1",
+    "jest-canvas-mock": "^2.5.1",
     "mini-css-extract-plugin": "^1.6.2",
     "moment": "^2.29.4",
     "moment-locales-webpack-plugin": "^1.2.0",
@@ -86,7 +87,7 @@
     "webpack-manifest-plugin": "^4.0.0"
   },
   "dependencies": {
-    "@chakra-ui/react": "^2.2.0",
+    "@chakra-ui/react": "2.4.2",
     "@emotion/cache": "^11.9.3",
     "@emotion/react": "^11.9.3",
     "@emotion/styled": "^11",
@@ -107,6 +108,7 @@
     "dagre-d3": "^0.6.4",
     "datatables.net": "^1.11.4",
     "datatables.net-bs": "^1.11.4",
+    "echarts": "^5.4.2",
     "elkjs": "^0.7.1",
     "eonasdan-bootstrap-datetimepicker": "^4.17.47",
     "framer-motion": "^6.0.0",
diff --git a/airflow/www/security.py b/airflow/www/security.py
index b6bc48104c..890648009c 100644
--- a/airflow/www/security.py
+++ b/airflow/www/security.py
@@ -72,6 +72,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_CODE),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_RUN),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DATASET),
+        (permissions.ACTION_CAN_READ, permissions.RESOURCE_CLUSTER_ACTIVITY),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_IMPORT_ERROR),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_WARNING),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_JOB),
@@ -90,6 +91,7 @@ class AirflowSecurityManager(SecurityManager, LoggingMixin):
         (permissions.ACTION_CAN_ACCESS_MENU, 
permissions.RESOURCE_DAG_DEPENDENCIES),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DAG_RUN),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DATASET),
+        (permissions.ACTION_CAN_ACCESS_MENU, 
permissions.RESOURCE_CLUSTER_ACTIVITY),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DOCS),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DOCS_MENU),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_JOB),
diff --git a/airflow/www/static/js/api/index.ts 
b/airflow/www/static/js/api/index.ts
index 016ad3b48d..cd7b9dd5af 100644
--- a/airflow/www/static/js/api/index.ts
+++ b/airflow/www/static/js/api/index.ts
@@ -42,6 +42,11 @@ import useUpstreamDatasetEvents from 
"./useUpstreamDatasetEvents";
 import useTaskInstance from "./useTaskInstance";
 import useDag from "./useDag";
 import useDagCode from "./useDagCode";
+import useHealth from "./useHealth";
+import usePools from "./usePools";
+import useDags from "./useDags";
+import useDagRuns from "./useDagRuns";
+import useHistoricalMetricsData from "./useHistoricalMetricsData";
 
 axios.interceptors.response.use((res: AxiosResponse) =>
   res.data ? camelcaseKeys(res.data, { deep: true }) : res
@@ -52,7 +57,10 @@ axios.defaults.headers.common.Accept = "application/json";
 export {
   useClearRun,
   useClearTask,
-  useMarkTaskDryRun,
+  useDag,
+  useDagCode,
+  useDagRuns,
+  useDags,
   useDataset,
   useDatasetDependencies,
   useDatasetEvents,
@@ -60,16 +68,18 @@ export {
   useExtraLinks,
   useGraphData,
   useGridData,
+  useHealth,
   useMappedInstances,
   useMarkFailedRun,
   useMarkFailedTask,
   useMarkSuccessRun,
   useMarkSuccessTask,
+  useMarkTaskDryRun,
+  usePools,
   useQueueRun,
   useSetDagRunNote,
   useSetTaskInstanceNote,
   useTaskInstance,
   useUpstreamDatasetEvents,
-  useDag,
-  useDagCode,
+  useHistoricalMetricsData,
 };
diff --git a/airflow/www/static/js/api/useDagRuns.tsx 
b/airflow/www/static/js/api/useDagRuns.tsx
new file mode 100644
index 0000000000..5bc1a43748
--- /dev/null
+++ b/airflow/www/static/js/api/useDagRuns.tsx
@@ -0,0 +1,50 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios, { AxiosResponse } from "axios";
+import { useQuery } from "react-query";
+import type { API } from "src/types";
+
+import { getMetaValue } from "src/utils";
+
+const useDagRuns = ({
+  dagId,
+  state,
+  limit,
+  orderBy,
+}: API.GetDagRunsVariables) => {
+  const dagRunsUrl = getMetaValue("dag_runs_url").replace("__DAG_ID__", dagId);
+
+  return useQuery(
+    ["dagRuns", state, dagId, limit],
+    async () =>
+      axios.get<AxiosResponse, API.DAGRunCollection>(dagRunsUrl, {
+        params: {
+          state: state ? state.join(",") : state,
+          limit,
+          order_by: orderBy,
+        },
+      }),
+    {
+      refetchInterval: (autoRefreshInterval || 1) * 1000,
+    }
+  );
+};
+
+export default useDagRuns;
diff --git a/airflow/www/static/js/api/useDags.tsx 
b/airflow/www/static/js/api/useDags.tsx
new file mode 100644
index 0000000000..8939da21d9
--- /dev/null
+++ b/airflow/www/static/js/api/useDags.tsx
@@ -0,0 +1,40 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios, { AxiosResponse } from "axios";
+import { useQuery } from "react-query";
+import type { API } from "src/types";
+
+import { getMetaValue } from "src/utils";
+
+const dagsUrl = getMetaValue("dags_url");
+
+const useDags = ({ paused }: API.GetDagsVariables) =>
+  useQuery(
+    ["dags", paused],
+    async () =>
+      axios.get<AxiosResponse, API.DAGCollection>(dagsUrl, {
+        params: { paused },
+      }),
+    {
+      refetchInterval: (autoRefreshInterval || 1) * 1000,
+    }
+  );
+
+export default useDags;
diff --git a/airflow/www/static/js/api/useHealth.ts 
b/airflow/www/static/js/api/useHealth.ts
new file mode 100644
index 0000000000..ab86698507
--- /dev/null
+++ b/airflow/www/static/js/api/useHealth.ts
@@ -0,0 +1,37 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios, { AxiosResponse } from "axios";
+import { useQuery } from "react-query";
+import type { API } from "src/types";
+
+import { getMetaValue } from "src/utils";
+
+const healthUrl = getMetaValue("health_url");
+
+const useHealth = () =>
+  useQuery(
+    ["health"],
+    async () => axios.get<AxiosResponse, API.HealthInfo>(healthUrl),
+    {
+      refetchInterval: (autoRefreshInterval || 1) * 1000,
+    }
+  );
+
+export default useHealth;
diff --git a/airflow/www/static/js/api/useHistoricalMetricsData.ts 
b/airflow/www/static/js/api/useHistoricalMetricsData.ts
new file mode 100644
index 0000000000..d14ce13fb6
--- /dev/null
+++ b/airflow/www/static/js/api/useHistoricalMetricsData.ts
@@ -0,0 +1,40 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios, { AxiosResponse } from "axios";
+import { useQuery } from "react-query";
+import type { HistoricalMetricsData } from "src/types";
+
+import { getMetaValue } from "src/utils";
+
+const url = getMetaValue("historical_metrics_data_url");
+
+const useHistoricalMetricsData = (startDate: string, endDate: string) =>
+  useQuery(
+    ["historical_metrics_data", startDate, endDate],
+    async () =>
+      axios.get<AxiosResponse, HistoricalMetricsData>(url, {
+        params: { start_date: startDate, end_date: endDate },
+      }),
+    {
+      refetchInterval: (autoRefreshInterval || 1) * 1000,
+    }
+  );
+
+export default useHistoricalMetricsData;
diff --git a/airflow/www/static/js/api/usePools.ts 
b/airflow/www/static/js/api/usePools.ts
new file mode 100644
index 0000000000..664626a2ab
--- /dev/null
+++ b/airflow/www/static/js/api/usePools.ts
@@ -0,0 +1,41 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios, { AxiosResponse } from "axios";
+import { useQuery } from "react-query";
+import { useAutoRefresh } from "src/context/autorefresh";
+import type { API } from "src/types";
+
+import { getMetaValue } from "src/utils";
+
+const poolsUrl = getMetaValue("pools_url");
+
+const usePools = () => {
+  const { isRefreshOn } = useAutoRefresh();
+
+  return useQuery(
+    ["pools"],
+    async () => axios.get<AxiosResponse, API.PoolCollection>(poolsUrl),
+    {
+      refetchInterval: isRefreshOn && (autoRefreshInterval || 1) * 1000,
+    }
+  );
+};
+
+export default usePools;
diff --git 
a/airflow/www/static/js/cluster-activity/historical-metrics/PieChart.tsx 
b/airflow/www/static/js/cluster-activity/historical-metrics/PieChart.tsx
new file mode 100644
index 0000000000..a1aa86cc5a
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/historical-metrics/PieChart.tsx
@@ -0,0 +1,147 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import {
+  Box,
+  BoxProps,
+  Card,
+  CardBody,
+  CardHeader,
+  Heading,
+  useTheme,
+} from "@chakra-ui/react";
+import ReactECharts, { ReactEChartsProps } from "src/components/ReactECharts";
+import type { HistoricalMetricsData } from "src/types";
+import { camelCase, mapKeys } from "lodash";
+
+interface SeriesPoint {
+  name: string;
+  value: number;
+}
+
+type SeriesData = Array<SeriesPoint>;
+
+const camelCaseColorPalette = mapKeys(stateColors, (_, k) => camelCase(k));
+
+const formatData = (
+  data: HistoricalMetricsData[keyof HistoricalMetricsData] | undefined
+): [number, SeriesData] => {
+  if (data === undefined) return [0, []];
+
+  let sum = 0;
+  const formattedData: { name: string; value: number }[] = [];
+  Object.entries(data).forEach(([k, v]) => {
+    sum += v;
+    formattedData.push({
+      name: k,
+      value: v,
+    });
+  });
+  formattedData.sort((a: SeriesPoint, b: SeriesPoint) => b.value - a.value);
+  return [sum, formattedData];
+};
+
+interface Props extends BoxProps {
+  title: string;
+  data?: HistoricalMetricsData[keyof HistoricalMetricsData];
+  colorPalette?: {
+    [key: string]: string;
+  };
+}
+
+const PieChart = ({
+  title,
+  data,
+  colorPalette = camelCaseColorPalette,
+  ...rest
+}: Props) => {
+  const theme = useTheme();
+  const [sum, formattedData] = formatData(data);
+  const option: ReactEChartsProps["option"] = {
+    title: {
+      text: `on a total of ${sum}`,
+      left: "right",
+      top: "bottom",
+      textStyle: {
+        fontSize: "14px",
+        color: theme.colors.gray["500"],
+      },
+    },
+    tooltip: {
+      trigger: "item",
+    },
+    legend: {
+      left: "center",
+      type: "scroll",
+    },
+    color: formattedData?.map((d) => {
+      let color = colorPalette[d.name];
+      if (color === undefined) {
+        // eslint-disable-next-line no-console
+        console.warn(
+          `The color for ${d.name} is missing from the palette, defaulting to 
black`
+        );
+        color = "black";
+      }
+      return color;
+    }),
+    series: [
+      {
+        name: title,
+        type: "pie",
+        radius: ["35%", "60%"],
+        avoidLabelOverlap: false,
+        top: "0%",
+        itemStyle: {
+          borderRadius: 5,
+          borderColor: "#fff",
+          borderWidth: 2,
+        },
+        label: {
+          show: false,
+          position: "center",
+        },
+        emphasis: {
+          label: {
+            show: true,
+            fontSize: 16,
+            fontWeight: "bold",
+          },
+        },
+        data: formattedData,
+      },
+    ],
+  };
+
+  return (
+    <Box {...rest}>
+      <Card h="100%">
+        <CardHeader textAlign="center" p={3}>
+          <Heading size="md">{title}</Heading>
+        </CardHeader>
+        <CardBody>
+          <ReactECharts option={option} />
+        </CardBody>
+      </Card>
+    </Box>
+  );
+};
+
+export default PieChart;
diff --git 
a/airflow/www/static/js/cluster-activity/historical-metrics/index.tsx 
b/airflow/www/static/js/cluster-activity/historical-metrics/index.tsx
new file mode 100644
index 0000000000..5e319c9c3e
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/historical-metrics/index.tsx
@@ -0,0 +1,95 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import { Card, CardBody, CardHeader, Flex, Heading } from "@chakra-ui/react";
+import InfoTooltip from "src/components/InfoTooltip";
+import FilterBar from "src/cluster-activity/nav/FilterBar";
+import useFilters from "src/cluster-activity/useFilters";
+import { useHistoricalMetricsData } from "src/api";
+import PieChart from "src/cluster-activity/historical-metrics/PieChart";
+import LoadingWrapper from "src/components/LoadingWrapper";
+
+const HistoricalMetrics = () => {
+  const {
+    filters: { startDate, endDate },
+  } = useFilters();
+  const { data, isError } = useHistoricalMetricsData(startDate, endDate);
+  return (
+    <Flex w="100%">
+      <Card w="100%">
+        <CardHeader>
+          <Flex alignItems="center">
+            <Heading size="md">Historical metrics</Heading>
+            <InfoTooltip
+              label="Based on historical data. You can adjust the period by 
setting a different start and end date filter."
+              size={18}
+            />
+          </Flex>
+        </CardHeader>
+        <CardBody>
+          <FilterBar />
+          <Flex justifyContent="center" minH="200px" alignItems="center">
+            <LoadingWrapper hasData={!!data} isError={isError}>
+              <Flex flexWrap="wrap" width="100%">
+                <PieChart
+                  title="Dag Run States"
+                  data={data?.dagRunStates}
+                  width="33.33%"
+                  minW="300px"
+                  minH="350px"
+                  pr={4}
+                  colorPalette={{
+                    failed: stateColors.failed,
+                    queued: stateColors.queued,
+                    running: stateColors.running,
+                    success: stateColors.success,
+                  }}
+                />
+                <PieChart
+                  title="Dag Run Types"
+                  data={data?.dagRunTypes}
+                  width="33.33%"
+                  minW="300px"
+                  minH="350px"
+                  pr={4}
+                  colorPalette={{
+                    backfill: stateColors.deferred,
+                    datasetTriggered: stateColors.queued,
+                    manual: stateColors.success,
+                    scheduled: stateColors.scheduled,
+                  }}
+                />
+                <PieChart
+                  title="Task Instance States"
+                  data={data?.taskInstanceStates}
+                  width="33.33%"
+                  minW="300px"
+                  minH="350px"
+                />
+              </Flex>
+            </LoadingWrapper>
+          </Flex>
+        </CardBody>
+      </Card>
+    </Flex>
+  );
+};
+
+export default HistoricalMetrics;
diff --git a/airflow/www/static/js/cluster-activity/index.test.tsx 
b/airflow/www/static/js/cluster-activity/index.test.tsx
new file mode 100644
index 0000000000..f12c4c159a
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/index.test.tsx
@@ -0,0 +1,153 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* global describe  */
+
+import React from "react";
+import * as useHistoricalMetricsDataModule from 
"src/api/useHistoricalMetricsData";
+import * as useDagsModule from "src/api/useDags";
+import * as useDagRunsModule from "src/api/useDagRuns";
+import * as usePoolsModule from "src/api/usePools";
+import * as useHealthModule from "src/api/useHealth";
+
+import { render } from "@testing-library/react";
+
+import { Wrapper } from "src/utils/testUtils";
+import ClusterActivity from ".";
+
+const mockHistoricalMetricsData = {
+  dag_run_states: { failed: 0, queued: 0, running: 0, success: 306 },
+  dag_run_types: {
+    backfill: 0,
+    dataset_triggered: 0,
+    manual: 14,
+    scheduled: 292,
+  },
+  task_instance_states: {
+    deferred: 0,
+    failed: 0,
+    no_status: 0,
+    queued: 0,
+    removed: 0,
+    restarting: 0,
+    running: 0,
+    scheduled: 0,
+    shutdown: 0,
+    skipped: 0,
+    success: 1634,
+    up_for_reschedule: 0,
+    up_for_retry: 0,
+    upstream_failed: 0,
+  },
+};
+
+const mockHealthData = {
+  metadatabase: {
+    status: "healthy",
+  },
+  scheduler: {
+    latest_scheduler_heartbeat: "2023-05-19T12:00:36.109924+00:00",
+    status: "healthy",
+  },
+};
+
+const mockPoolsData = {
+  pools: [
+    {
+      description: "Default pool",
+      name: "default_pool",
+      occupied_slots: 0,
+      open_slots: 128,
+      queued_slots: 0,
+      running_slots: 0,
+      scheduled_slots: 0,
+      slots: 128,
+    },
+  ],
+  total_entries: 1,
+};
+
+const mockDagsData = {
+  dags: ["fake-dag-payload1", "fake-dag-payload2"],
+  total_entries: 2,
+};
+
+const mockDagRunsData = {
+  dags: [],
+  total_entries: 0,
+};
+
+describe("Test ToggleGroups", () => {
+  beforeEach(() => {
+    jest.spyOn(useHistoricalMetricsDataModule, "default").mockImplementation(
+      () =>
+        ({
+          data: mockHistoricalMetricsData,
+          isSuccess: true,
+        } as any)
+    );
+
+    jest.spyOn(useHealthModule, "default").mockImplementation(
+      () =>
+        ({
+          data: mockHealthData,
+          isSuccess: true,
+        } as any)
+    );
+
+    jest.spyOn(useDagsModule, "default").mockImplementation(
+      () =>
+        ({
+          data: mockDagsData,
+          isSuccess: true,
+        } as any)
+    );
+
+    jest.spyOn(useDagRunsModule, "default").mockImplementation(
+      () =>
+        ({
+          data: mockDagRunsData,
+          isSuccess: true,
+        } as any)
+    );
+
+    jest.spyOn(usePoolsModule, "default").mockImplementation(
+      () =>
+        ({
+          data: mockPoolsData,
+          isSuccess: true,
+        } as any)
+    );
+  });
+
+  test("Components renders properly", () => {
+    const { getByText, getAllByTestId, getAllByText } = render(
+      <ClusterActivity />,
+      {
+        wrapper: Wrapper,
+      }
+    );
+
+    expect(getAllByTestId("echart-container")).toHaveLength(4);
+
+    expect(getAllByText("healthy")).toHaveLength(2);
+    expect(getByText("Unpaused DAGs")).toBeInTheDocument();
+    expect(getByText("No dag running")).toBeInTheDocument();
+  });
+});
diff --git a/airflow/www/static/js/cluster-activity/index.tsx 
b/airflow/www/static/js/cluster-activity/index.tsx
new file mode 100644
index 0000000000..01b21b0dd8
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/index.tsx
@@ -0,0 +1,64 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* global document */
+
+import React from "react";
+import { createRoot } from "react-dom/client";
+import createCache from "@emotion/cache";
+import { Flex, Heading } from "@chakra-ui/react";
+
+import App from "src/App";
+import LiveMetrics from "./live-metrics";
+import HistoricalMetrics from "./historical-metrics";
+
+// create shadowRoot
+const root = document.querySelector("#root");
+const shadowRoot = root?.attachShadow({ mode: "open" });
+const cache = createCache({
+  container: shadowRoot,
+  key: "c",
+});
+const mainElement = document.getElementById("react-container");
+
+const ClusterActivity = () => (
+  <Flex
+    alignItems="flex-start"
+    flexDirection="column"
+    justifyContent="space-between"
+  >
+    <Heading mt={3} mb={2} fontWeight="normal" size="lg">
+      Cluster Activity
+    </Heading>
+    <LiveMetrics />
+    <HistoricalMetrics />
+  </Flex>
+);
+
+export default ClusterActivity;
+
+if (mainElement) {
+  shadowRoot?.appendChild(mainElement);
+  const reactRoot = createRoot(mainElement);
+  reactRoot.render(
+    <App cache={cache}>
+      <ClusterActivity />
+    </App>
+  );
+}
diff --git a/airflow/www/static/js/cluster-activity/live-metrics/DagRuns.tsx 
b/airflow/www/static/js/cluster-activity/live-metrics/DagRuns.tsx
new file mode 100644
index 0000000000..7f2b169359
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/live-metrics/DagRuns.tsx
@@ -0,0 +1,121 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import {
+  Box,
+  BoxProps,
+  Card,
+  CardBody,
+  CardHeader,
+  Center,
+  Flex,
+  Heading,
+  Link,
+  Table,
+  Tbody,
+  Td,
+  Text,
+  Th,
+  Thead,
+  Tr,
+} from "@chakra-ui/react";
+import { useDagRuns } from "src/api";
+import { formatDuration, getDuration } from "src/datetime_utils";
+import LoadingWrapper from "src/components/LoadingWrapper";
+
+const DagRuns = (props: BoxProps) => {
+  const { data, isError } = useDagRuns({
+    dagId: "~",
+    state: ["running"],
+    orderBy: "start_date",
+    limit: 5,
+  });
+
+  return (
+    <Center {...props}>
+      <LoadingWrapper hasData={!!data} isError={isError}>
+        <Card w="100%">
+          <CardHeader textAlign="center" p={3}>
+            <Heading size="md">Top 5 longest Dag Runs to finish</Heading>
+          </CardHeader>
+          <CardBody>
+            <Box mt={2} mb={5}>
+              {data?.totalEntries !== undefined && data.totalEntries > 0 ? (
+                <Table
+                  size="sm"
+                  style={{ tableLayout: "fixed", width: "100%" }}
+                >
+                  <Thead>
+                    <Tr>
+                      <Th>Dag Id</Th>
+                      <Th>Run Type</Th>
+                      <Th>Duration</Th>
+                    </Tr>
+                  </Thead>
+                  <Tbody>
+                    {data?.dagRuns?.map((dagRun) => (
+                      <Tr key={dagRun.dagRunId}>
+                        <Td
+                          textOverflow="ellipsis"
+                          overflow="hidden"
+                          whiteSpace="nowrap"
+                        >
+                          <Link
+                            href={`dags/${
+                              dagRun.dagId
+                            }/grid?dag_run_id=${encodeURIComponent(
+                              dagRun.dagRunId as string
+                            )}`}
+                          >
+                            {dagRun.dagId}
+                          </Link>
+                        </Td>
+                        <Td>{dagRun.runType}</Td>
+                        <Td>
+                          {formatDuration(
+                            getDuration(dagRun.startDate, dagRun.endDate)
+                          )}
+                        </Td>
+                      </Tr>
+                    ))}
+                  </Tbody>
+                </Table>
+              ) : (
+                <Flex justifyContent="center">
+                  <Heading as="b" size="sm">
+                    No dag running
+                  </Heading>
+                </Flex>
+              )}
+            </Box>
+            <Flex justifyContent="end" textAlign="right">
+              <Text size="md" color="gray.500">
+                out of <Text as="b">{data?.totalEntries}</Text> total running
+                Dag Runs
+              </Text>
+            </Flex>
+          </CardBody>
+        </Card>
+      </LoadingWrapper>
+    </Center>
+  );
+};
+
+export default DagRuns;
diff --git a/airflow/www/static/js/cluster-activity/live-metrics/Dags.tsx 
b/airflow/www/static/js/cluster-activity/live-metrics/Dags.tsx
new file mode 100644
index 0000000000..abe36b6e52
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/live-metrics/Dags.tsx
@@ -0,0 +1,69 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import {
+  BoxProps,
+  Card,
+  CardBody,
+  CardHeader,
+  Center,
+  Flex,
+  Heading,
+  Text,
+} from "@chakra-ui/react";
+import { useDags } from "src/api";
+import LoadingWrapper from "src/components/LoadingWrapper";
+
+const Dags = (props: BoxProps) => {
+  const { data: dataOnlyUnpaused, isError: isErrorUnpaused } = useDags({
+    paused: false,
+  });
+
+  const { data, isError } = useDags({});
+
+  return (
+    <Center {...props}>
+      <LoadingWrapper
+        hasData={!!data && !!dataOnlyUnpaused}
+        isError={isError || isErrorUnpaused}
+      >
+        <Card w="100%">
+          <CardHeader textAlign="center" p={3}>
+            <Heading size="md">Unpaused DAGs</Heading>
+          </CardHeader>
+          <CardBody>
+            <Flex justifyContent="center" mb={4}>
+              <Heading as="b" size="xl">
+                {dataOnlyUnpaused?.totalEntries}
+              </Heading>
+            </Flex>
+            <Flex justifyContent="end" textAlign="right">
+              <Text size="md" color="gray.500">
+                out of <Text as="b">{data?.totalEntries}</Text> total DAGs
+              </Text>
+            </Flex>
+          </CardBody>
+        </Card>
+      </LoadingWrapper>
+    </Center>
+  );
+};
+
+export default Dags;
diff --git a/airflow/www/static/js/cluster-activity/live-metrics/Health.tsx 
b/airflow/www/static/js/cluster-activity/live-metrics/Health.tsx
new file mode 100644
index 0000000000..fb59439c4b
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/live-metrics/Health.tsx
@@ -0,0 +1,116 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import {
+  Badge,
+  CenterProps,
+  Card,
+  CardBody,
+  CardHeader,
+  Center,
+  Flex,
+  Heading,
+  Stack,
+  Text,
+  FlexProps,
+} from "@chakra-ui/react";
+import { useHealth } from "src/api";
+import type { API } from "src/types";
+import Time from "src/components/Time";
+import LoadingWrapper from "src/components/LoadingWrapper";
+
+const HealthSection = ({
+  title,
+  status,
+  latestHeartbeat,
+  ...rest
+}: {
+  title: string;
+  status?: API.HealthStatus;
+  latestHeartbeat?: string | null;
+} & FlexProps) => (
+  <Flex flexDirection="column" {...rest}>
+    <Text as="b" color="blue.600">
+      {title}
+    </Text>
+    <Stack direction="row">
+      <Text textIndent="15px">status:</Text>
+      <div>
+        <Badge
+          colorScheme={status === "healthy" ? "green" : "red"}
+          fontSize="0.9rem"
+        >
+          {status || "unknown"}
+        </Badge>
+      </div>
+    </Stack>
+    {latestHeartbeat && (
+      <Stack direction="row">
+        <Text textIndent="15px" whiteSpace="nowrap">
+          last heartbeat:{" "}
+        </Text>
+        <div>
+          <Badge
+            colorScheme={status === "healthy" ? "green" : "red"}
+            fontSize="0.9rem"
+          >
+            <Time dateTime={latestHeartbeat} />
+          </Badge>
+        </div>
+      </Stack>
+    )}
+  </Flex>
+);
+
+const Health = (props: CenterProps) => {
+  const { data, isError } = useHealth();
+
+  return (
+    <Center {...props}>
+      <LoadingWrapper hasData={!!data} isError={isError}>
+        <Card w="100%">
+          <CardHeader textAlign="center" p={3}>
+            <Heading size="md">Health</Heading>
+          </CardHeader>
+          <CardBody>
+            <HealthSection
+              title="MetaDatabase"
+              status={data?.metadatabase?.status}
+              mb={3}
+            />
+            <HealthSection
+              title="Scheduler"
+              status={data?.scheduler?.status}
+              latestHeartbeat={data?.scheduler?.latestSchedulerHeartbeat}
+              mb={3}
+            />
+            <HealthSection
+              title="Triggerer"
+              status={data?.triggerer?.status}
+              latestHeartbeat={data?.triggerer?.latestTriggererHeartbeat}
+            />
+          </CardBody>
+        </Card>
+      </LoadingWrapper>
+    </Center>
+  );
+};
+
+export default Health;
diff --git a/airflow/www/static/js/cluster-activity/live-metrics/Pools.tsx 
b/airflow/www/static/js/cluster-activity/live-metrics/Pools.tsx
new file mode 100644
index 0000000000..36434eb079
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/live-metrics/Pools.tsx
@@ -0,0 +1,132 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import {
+  Box,
+  BoxProps,
+  Card,
+  CardBody,
+  CardHeader,
+  Center,
+  Heading,
+} from "@chakra-ui/react";
+import { usePools } from "src/api";
+import ReactECharts, { ReactEChartsProps } from "src/components/ReactECharts";
+import type { API } from "src/types";
+import LoadingWrapper from "src/components/LoadingWrapper";
+
+const formatData = (
+  data?: API.PoolCollection
+): Array<[string, number, number, number, number]> =>
+  data?.pools?.map((pool) => [
+    pool.name || "",
+    pool.openSlots || 0,
+    pool.queuedSlots || 0,
+    pool.runningSlots || 0,
+    pool.scheduledSlots || 0,
+  ]) || [];
+
+const Pools = (props: BoxProps) => {
+  const { data, isError } = usePools();
+
+  const option: ReactEChartsProps["option"] = {
+    dataset: {
+      source: [
+        ["pool", "open", "queued", "running", "scheduled"],
+        ...formatData(data),
+      ],
+    },
+    tooltip: {
+      trigger: "axis",
+      axisPointer: {
+        type: "shadow",
+      },
+    },
+    legend: {
+      data: ["open", "queued", "running", "scheduled"],
+    },
+    grid: {
+      left: "0%",
+      right: "5%",
+      top: "30%",
+      bottom: "0%",
+      containLabel: true,
+    },
+    xAxis: {
+      type: "value",
+    },
+    yAxis: {
+      type: "category",
+    },
+    series: [
+      {
+        type: "bar",
+        stack: "total",
+        barMaxWidth: 10,
+        itemStyle: {
+          color: stateColors.success,
+        },
+      },
+      {
+        type: "bar",
+        stack: "total",
+        barMaxWidth: 10,
+        itemStyle: {
+          color: stateColors.queued,
+        },
+      },
+      {
+        type: "bar",
+        stack: "total",
+        barMaxWidth: 10,
+        itemStyle: {
+          color: stateColors.running,
+        },
+      },
+      {
+        type: "bar",
+        stack: "total",
+        barMaxWidth: 10,
+        itemStyle: {
+          color: stateColors.scheduled,
+        },
+      },
+    ],
+  };
+
+  return (
+    <Center {...props}>
+      <LoadingWrapper hasData={!!data} isError={isError}>
+        <Card w="100%">
+          <CardHeader textAlign="center" p={3}>
+            <Heading size="md">Pools Slots</Heading>
+          </CardHeader>
+          <CardBody>
+            <Box height="250px">
+              <ReactECharts option={option} />
+            </Box>
+          </CardBody>
+        </Card>
+      </LoadingWrapper>
+    </Center>
+  );
+};
+
+export default Pools;
diff --git a/airflow/www/static/js/cluster-activity/live-metrics/index.tsx 
b/airflow/www/static/js/cluster-activity/live-metrics/index.tsx
new file mode 100644
index 0000000000..6b7f3c7668
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/live-metrics/index.tsx
@@ -0,0 +1,61 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+import { Card, CardBody, CardHeader, Flex, Heading } from "@chakra-ui/react";
+import InfoTooltip from "src/components/InfoTooltip";
+import Health from "./Health";
+import Pools from "./Pools";
+import Dags from "./Dags";
+import DagRuns from "./DagRuns";
+
+const LiveMetrics = () => (
+  <Flex w="100%">
+    <Card w="100%">
+      <CardHeader>
+        <Flex alignItems="center">
+          <Heading size="md">Live Metrics</Heading>
+          <InfoTooltip
+            label="Based on real time metrics and current resources state."
+            size={18}
+          />
+        </Flex>
+      </CardHeader>
+      <CardBody>
+        <Flex flexWrap="wrap" alignItems="center">
+          <Flex
+            direction="column"
+            w="25%"
+            minW="300px"
+            minH="200px"
+            pr={4}
+            justifyContent="space-around"
+          >
+            <Dags />
+            <DagRuns />
+          </Flex>
+          <Pools width="50%" minW="300px" pr={4} />
+          <Health width="25%" minW="300px" />
+        </Flex>
+      </CardBody>
+    </Card>
+  </Flex>
+);
+
+export default LiveMetrics;
diff --git a/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx 
b/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx
new file mode 100644
index 0000000000..29fa456df4
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/nav/FilterBar.tsx
@@ -0,0 +1,101 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* global moment */
+
+import { Box, Button, Flex, Input, Text } from "@chakra-ui/react";
+import React from "react";
+
+import { useTimezone } from "src/context/timezone";
+import {
+  isoFormatWithoutTZ,
+  formatDuration,
+  getDuration,
+} from "src/datetime_utils";
+import useFilters from "src/cluster-activity/useFilters";
+
+const FilterBar = () => {
+  const { filters, onStartDateChange, onEndDateChange, clearFilters } =
+    useFilters();
+
+  const { timezone } = useTimezone();
+  const startDate = moment(filters.startDate);
+  const endDate = moment(filters.endDate);
+  const formattedStartDate = startDate.tz(timezone).format(isoFormatWithoutTZ);
+  const formattedEndDate = endDate.tz(timezone).format(isoFormatWithoutTZ);
+
+  const inputStyles = { backgroundColor: "white", size: "lg" };
+
+  return (
+    <Flex
+      backgroundColor="blackAlpha.200"
+      mb={4}
+      px={4}
+      py={5}
+      justifyContent="space-between"
+      flexWrap="wrap"
+      gap={4}
+    >
+      <Flex justifyContent="space-between" flexWrap="wrap" gap={4}>
+        <Box px={2}>
+          <Text fontSize="sm" as="b" position="absolute" mt="-14px" ml={1}>
+            Start Date
+          </Text>
+          <Input
+            {...inputStyles}
+            type="datetime-local"
+            value={formattedStartDate || ""}
+            onChange={(e) => onStartDateChange(e.target.value)}
+          />
+        </Box>
+        <Box px={2}>
+          <Text fontSize="sm" as="b" position="absolute" mt="-14px" ml={1}>
+            End Date
+          </Text>
+          <Input
+            {...inputStyles}
+            type="datetime-local"
+            value={formattedEndDate || ""}
+            onChange={(e) => onEndDateChange(e.target.value)}
+          />
+        </Box>
+        <Flex alignItems="center">
+          <Text whiteSpace="nowrap">
+            over the last{" "}
+            {formatDuration(getDuration(formattedStartDate, formattedEndDate))}
+          </Text>
+        </Flex>
+      </Flex>
+      <Flex px={2}>
+        <Button
+          colorScheme="cyan"
+          aria-label="Reset filters"
+          background="white"
+          variant="outline"
+          onClick={clearFilters}
+          size="lg"
+        >
+          Clear Filters
+        </Button>
+      </Flex>
+    </Flex>
+  );
+};
+
+export default FilterBar;
diff --git a/airflow/www/static/js/cluster-activity/useFilters.tsx 
b/airflow/www/static/js/cluster-activity/useFilters.tsx
new file mode 100644
index 0000000000..414745d0de
--- /dev/null
+++ b/airflow/www/static/js/cluster-activity/useFilters.tsx
@@ -0,0 +1,95 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* global moment */
+
+import { useSearchParams } from "react-router-dom";
+import URLSearchParamsWrapper from "src/utils/URLSearchParamWrapper";
+
+export interface Filters {
+  startDate: string;
+  endDate: string;
+}
+
+export interface UtilFunctions {
+  onStartDateChange: (value: string) => void;
+  onEndDateChange: (value: string) => void;
+  clearFilters: () => void;
+}
+
+export interface FilterHookReturn extends UtilFunctions {
+  filters: Filters;
+}
+
+// Params names
+export const START_DATE_PARAM = "start_date";
+export const END_DATE_PARAM = "end_date";
+
+const date = new Date();
+date.setMilliseconds(0);
+
+export const now = date.toISOString();
+
+const useFilters = (): FilterHookReturn => {
+  const [searchParams, setSearchParams] = useSearchParams();
+
+  const endDate = searchParams.get(END_DATE_PARAM) || now;
+  const startDate =
+    searchParams.get(START_DATE_PARAM) ||
+    moment(endDate).subtract(1, "d").toISOString();
+
+  const makeOnChangeFn =
+    (paramName: string, formatFn?: (arg: string) => string) =>
+    (value: string) => {
+      const formattedValue = formatFn ? formatFn(value) : value;
+      const params = new URLSearchParamsWrapper(searchParams);
+
+      if (formattedValue) params.set(paramName, formattedValue);
+      else params.delete(paramName);
+
+      setSearchParams(params);
+    };
+
+  const onStartDateChange = makeOnChangeFn(
+    START_DATE_PARAM,
+    (localDate: string) => moment(localDate).utc().format()
+  );
+
+  const onEndDateChange = makeOnChangeFn(END_DATE_PARAM, (localDate: string) =>
+    moment(localDate).utc().format()
+  );
+
+  const clearFilters = () => {
+    searchParams.delete(START_DATE_PARAM);
+    searchParams.delete(END_DATE_PARAM);
+    setSearchParams(searchParams);
+  };
+
+  return {
+    filters: {
+      startDate,
+      endDate,
+    },
+    onStartDateChange,
+    onEndDateChange,
+    clearFilters,
+  };
+};
+
+export default useFilters;
diff --git a/airflow/www/static/js/components/LoadingWrapper.tsx 
b/airflow/www/static/js/components/LoadingWrapper.tsx
new file mode 100644
index 0000000000..b85febc402
--- /dev/null
+++ b/airflow/www/static/js/components/LoadingWrapper.tsx
@@ -0,0 +1,53 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Badge, Spinner } from "@chakra-ui/react";
+import React, { PropsWithChildren } from "react";
+
+interface Props extends PropsWithChildren {
+  hasData: boolean;
+  isError: boolean;
+}
+
+const LoadingWrapper = ({ children, hasData, isError }: Props) => {
+  if (isError) {
+    return (
+      <Badge colorScheme="red" fontSize="1rem">
+        Failed to fetch data
+      </Badge>
+    );
+  }
+
+  // using hasData and not isFetching to now show a spinner on
+  // every refresh (autoRefresh)
+  if (!hasData) {
+    return <Spinner color="blue.500" speed="1s" mr="4px" size="xl" />;
+  }
+
+  // Allows to not wrap children in an extra wrapper when it is already
+  // a valid component.
+  if (React.isValidElement(children)) {
+    return children;
+  }
+
+  // children is a str, int, etc.
+  return <span>{children}</span>;
+};
+
+export default LoadingWrapper;
diff --git a/airflow/www/static/js/components/ReactECharts.tsx 
b/airflow/www/static/js/components/ReactECharts.tsx
new file mode 100644
index 0000000000..b6a26b2047
--- /dev/null
+++ b/airflow/www/static/js/components/ReactECharts.tsx
@@ -0,0 +1,93 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React, { useRef, useEffect } from "react";
+import { init, getInstanceByDom } from "echarts";
+import type { CSSProperties } from "react";
+import type { EChartsOption, ECharts, SetOptionOpts } from "echarts";
+
+export interface ReactEChartsProps {
+  loading?: boolean;
+  option: EChartsOption;
+  settings?: SetOptionOpts;
+  style?: CSSProperties;
+  theme?: "light" | "dark";
+}
+
+const ReactECharts = ({
+  loading,
+  option,
+  settings,
+  style,
+  theme,
+}: ReactEChartsProps) => {
+  const ref = useRef<HTMLDivElement>(null);
+
+  useEffect(() => {
+    // Init Chart
+    let chart: ECharts | undefined;
+    if (ref.current !== null) {
+      chart = init(ref.current, theme, {
+        renderer: "svg",
+      });
+    }
+
+    const resizeChart = () => {
+      chart?.resize();
+    };
+
+    window.addEventListener("resize", resizeChart);
+
+    return () => {
+      chart?.dispose();
+      window.removeEventListener("resize", resizeChart);
+    };
+  }, [theme]);
+
+  useEffect(() => {
+    // Handle chart loading
+    if (ref.current !== null) {
+      const chart = getInstanceByDom(ref.current);
+      if (loading === true) {
+        chart?.showLoading();
+      } else {
+        chart?.hideLoading();
+      }
+    }
+  }, [loading]);
+
+  useEffect(() => {
+    // Handle option and theme updates
+    if (ref.current !== null) {
+      const chartInstance = getInstanceByDom(ref.current);
+      if (chartInstance) {
+        chartInstance.setOption(option, settings);
+      }
+    }
+  }, [option, settings, theme]);
+
+  return (
+    <div
+      data-testid="echart-container"
+      ref={ref}
+      style={{ width: "100%", height: "100%", ...style }}
+    />
+  );
+};
+export default ReactECharts;
diff --git a/airflow/www/static/js/dag/nav/FilterBar.tsx 
b/airflow/www/static/js/dag/nav/FilterBar.tsx
index 4b5e2f3be3..f76e20b270 100644
--- a/airflow/www/static/js/dag/nav/FilterBar.tsx
+++ b/airflow/www/static/js/dag/nav/FilterBar.tsx
@@ -52,7 +52,12 @@ const FilterBar = () => {
   const inputStyles = { backgroundColor: "white", size: "lg" };
 
   return (
-    <Flex backgroundColor="#f0f0f0" mt={4} p={4} 
justifyContent="space-between">
+    <Flex
+      backgroundColor="blackAlpha.200"
+      mt={4}
+      p={4}
+      justifyContent="space-between"
+    >
       <Flex>
         <Box px={2}>
           <Input
diff --git a/airflow/www/static/js/types/index.ts 
b/airflow/www/static/js/types/index.ts
index 42b2a4d857..3110879bfc 100644
--- a/airflow/www/static/js/types/index.ts
+++ b/airflow/www/static/js/types/index.ts
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+import type { CamelCase } from "type-fest";
 import type * as API from "./api-generated";
 
 type RunState = "success" | "running" | "queued" | "failed";
@@ -144,14 +145,27 @@ interface KeyboardShortcutIdentifier {
   [name: string]: KeyboardShortcutKeys;
 }
 
+interface HistoricalMetricsData {
+  dagRunStates: {
+    [K in CamelCase<RunState>]: number;
+  };
+  dagRunTypes: {
+    [K in CamelCase<DagRun["runType"]>]: number;
+  };
+  taskInstanceStates: {
+    [K in TaskState extends string ? CamelCase<K> : never]: number;
+  };
+}
+
 export type {
   API,
-  MinimalTaskInstance,
   Dag,
   DagRun,
   DatasetListItem,
   DepEdge,
   DepNode,
+  HistoricalMetricsData,
+  MinimalTaskInstance,
   RunOrdering,
   RunState,
   Task,
diff --git a/airflow/www/templates/airflow/datasets.html 
b/airflow/www/templates/airflow/cluster_activity.html
similarity index 56%
copy from airflow/www/templates/airflow/datasets.html
copy to airflow/www/templates/airflow/cluster_activity.html
index 6b3555c616..03ba1fe34f 100644
--- a/airflow/www/templates/airflow/datasets.html
+++ b/airflow/www/templates/airflow/cluster_activity.html
@@ -18,22 +18,23 @@
  #}
 
 {% extends base_template %}
-{% block page_title %}Datasets - {{ appbuilder.app_name }}{% endblock %}
+{% block page_title %}Cluster Activity - {{ appbuilder.app_name }}{% endblock 
%}
+{% from 'appbuilder/loading_dots.html' import loading_dots %}
 
 {% block head_meta %}
   {{ super() }}
-  <meta name="datasets_api" content="{{ url_for('Airflow.datasets_summary') 
}}">
-  <meta name="dataset_api" content="{{ 
url_for('/api/v1.airflow_api_connexion_endpoints_dataset_endpoint_get_dataset', 
uri='__URI__') }}">
-  <meta name="dataset_events_api" content="{{ 
url_for('/api/v1.airflow_api_connexion_endpoints_dataset_endpoint_get_dataset_events')
 }}">
-  <meta name="grid_url" content="{{ url_for('Airflow.grid', 
dag_id='__DAG_ID__') }}">
-  <meta name="datasets_docs" content="{{ 
get_docs_url('concepts/datasets.html') }}">
-  <meta name="dataset_dependencies_url" content="{{ 
url_for('Airflow.dataset_dependencies') }}">
+  <meta name="health_url" content="{{ url_for('Airflow.health')}}">
+  <meta name="pools_url" content="{{ 
url_for('/api/v1.airflow_api_connexion_endpoints_pool_endpoint_get_pools') }}">
+  <meta name="dags_url" content="{{ 
url_for('/api/v1.airflow_api_connexion_endpoints_dag_endpoint_get_dags') }}">
+  <meta name="dag_runs_url" content="{{ 
url_for('/api/v1.airflow_api_connexion_endpoints_dag_run_endpoint_get_dag_runs',
 dag_id='__DAG_ID__') }}">
+  <meta name="historical_metrics_data_url" content="{{ 
url_for('Airflow.historical_metrics_data') }}">
 {% endblock %}
 
 {% block content %}
   {{ super() }}
   <div id="root">
     <div id="react-container"></div>
+    {{ loading_dots(id='react-loading') }}
   </div>
 {% endblock %}
 
@@ -41,6 +42,7 @@
   {{ super()}}
   <script>
     const stateColors = {{ state_color_mapping|tojson }};
+    const autoRefreshInterval = {{ auto_refresh_interval }};
   </script>
-  <script src="{{ url_for_asset('datasets.js') }}"></script>
+  <script src="{{ url_for_asset('clusterActivity.js') }}"></script>
 {% endblock %}
diff --git a/airflow/www/templates/airflow/datasets.html 
b/airflow/www/templates/airflow/datasets.html
index 6b3555c616..0ffd11444a 100644
--- a/airflow/www/templates/airflow/datasets.html
+++ b/airflow/www/templates/airflow/datasets.html
@@ -19,6 +19,7 @@
 
 {% extends base_template %}
 {% block page_title %}Datasets - {{ appbuilder.app_name }}{% endblock %}
+{% from 'appbuilder/loading_dots.html' import loading_dots %}
 
 {% block head_meta %}
   {{ super() }}
@@ -34,6 +35,7 @@
   {{ super() }}
   <div id="root">
     <div id="react-container"></div>
+    {{ loading_dots(id='react-loading') }}
   </div>
 {% endblock %}
 
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 9b8a8ee72c..592812e841 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -70,7 +70,7 @@ from pendulum.datetime import DateTime
 from pendulum.parsing.exceptions import ParserError
 from pygments import highlight, lexers
 from pygments.formatters import HtmlFormatter
-from sqlalchemy import Date, and_, case, desc, func, inspect, union_all
+from sqlalchemy import Date, and_, case, desc, func, inspect, or_, union_all
 from sqlalchemy.exc import IntegrityError
 from sqlalchemy.orm import Session, joinedload
 from wtforms import SelectField, validators
@@ -974,6 +974,22 @@ class Airflow(AirflowBaseView):
             state_color_mapping=state_color_mapping,
         )
 
+    @expose("/cluster_activity")
+    @auth.has_access(
+        [
+            (permissions.ACTION_CAN_READ, 
permissions.RESOURCE_CLUSTER_ACTIVITY),
+        ]
+    )
+    def cluster_activity(self):
+        """Cluster Activity view."""
+        state_color_mapping = State.state_color.copy()
+        state_color_mapping["no_status"] = state_color_mapping.pop(None)
+        return self.render_template(
+            "airflow/cluster_activity.html",
+            auto_refresh_interval=conf.getint("webserver", 
"auto_refresh_interval"),
+            state_color_mapping=state_color_mapping,
+        )
+
     @expose("/next_run_datasets_summary", methods=["POST"])
     @auth.has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG)])
     @provide_session
@@ -3791,6 +3807,71 @@ class Airflow(AirflowBaseView):
             {"Content-Type": "application/json; charset=utf-8"},
         )
 
+    @expose("/object/historical_metrics_data")
+    @auth.has_access(
+        [
+            (permissions.ACTION_CAN_READ, 
permissions.RESOURCE_CLUSTER_ACTIVITY),
+        ]
+    )
+    def historical_metrics_data(self):
+        """Returns cluster activity historical metrics"""
+        start_date = _safe_parse_datetime(request.args.get("start_date"))
+        end_date = _safe_parse_datetime(request.args.get("end_date"))
+        with create_session() as session:
+            # DagRuns
+            dag_runs_type = (
+                session.query(DagRun.run_type, func.count(DagRun.run_id))
+                .filter(
+                    DagRun.start_date >= start_date,
+                    or_(DagRun.end_date.is_(None), DagRun.end_date <= 
end_date),
+                )
+                .group_by(DagRun.run_type)
+                .all()
+            )
+
+            dag_run_states = (
+                session.query(DagRun.state, func.count(DagRun.run_id))
+                .filter(
+                    DagRun.start_date >= start_date,
+                    or_(DagRun.end_date.is_(None), DagRun.end_date <= 
end_date),
+                )
+                .group_by(DagRun.state)
+                .all()
+            )
+
+            # TaskInstances
+            task_instance_states = (
+                session.query(TaskInstance.state, 
func.count(TaskInstance.run_id))
+                .join(TaskInstance.dag_run)
+                .filter(
+                    DagRun.start_date >= start_date,
+                    or_(DagRun.end_date.is_(None), DagRun.end_date <= 
end_date),
+                )
+                .group_by(TaskInstance.state)
+                .all()
+            )
+
+            data = {
+                "dag_run_types": {
+                    **{dag_run_type.value: 0 for dag_run_type in DagRunType},
+                    **{run_type: sum_value for run_type, sum_value in 
dag_runs_type},
+                },
+                "dag_run_states": {
+                    **{dag_run_state.value: 0 for dag_run_state in 
DagRunState},
+                    **{run_state: sum_value for run_state, sum_value in 
dag_run_states},
+                },
+                "task_instance_states": {
+                    "no_status": 0,
+                    **{ti_state.value: 0 for ti_state in TaskInstanceState},
+                    **{ti_state or "no_status": sum_value for ti_state, 
sum_value in task_instance_states},
+                },
+            }
+
+        return (
+            htmlsafe_json_dumps(data, separators=(",", ":"), 
dumps=flask.json.dumps),
+            {"Content-Type": "application/json; charset=utf-8"},
+        )
+
     @expose("/object/next_run_datasets/<string:dag_id>")
     @auth.has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG)])
     def next_run_datasets(self, dag_id):
diff --git a/airflow/www/webpack.config.js b/airflow/www/webpack.config.js
index 82344e3b03..e61947707d 100644
--- a/airflow/www/webpack.config.js
+++ b/airflow/www/webpack.config.js
@@ -76,6 +76,7 @@ const config = {
     taskInstances: `${JS_DIR}/task_instances.js`,
     tiLog: `${JS_DIR}/ti_log.js`,
     grid: `${JS_DIR}/dag/index.tsx`,
+    clusterActivity: `${JS_DIR}/cluster-activity/index.tsx`,
     datasets: `${JS_DIR}/datasets/index.tsx`,
     calendar: [`${CSS_DIR}/calendar.css`, `${JS_DIR}/calendar.js`],
     durationChart: `${JS_DIR}/duration_chart.js`,
diff --git a/airflow/www/yarn.lock b/airflow/www/yarn.lock
index 3f8de910cc..6e1fce5334 100644
--- a/airflow/www/yarn.lock
+++ b/airflow/www/yarn.lock
@@ -1493,562 +1493,753 @@
   resolved 
"https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39";
   integrity 
sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.0.3.tgz#4f9db1459698fd91d68f913fe7f6d1687cefabbd";
-  integrity 
sha512-3fu5q6I6QtYVfpBHK+xxIkZ3b/spHgDongXuKuLEJZswcSU8+X5B9YmNfv73ZMRKO3PboYtyHAmZZo4pYqzbbA==
-  dependencies:
-    "@chakra-ui/descendant" "3.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/transition" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.1.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.1.4.tgz#a3eca38f8e52d5a5f4b9528fb9d269dcdcb035ac";
+  integrity 
sha512-PQFW6kr+Bdru0DjKA8akC4BAz1VAJisLgo4TsJwjPO2gTS0zr99C+3bBs9uoDnjSJAf18/Q5zdXv11adA8n2XA==
+  dependencies:
+    "@chakra-ui/descendant" "3.0.11"
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/transition" "2.0.12"
+
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.0.13.tgz#11d48346e501988074affe12a448add1a6060296";
+  integrity 
sha512-7LqPv6EUBte4XM/Q2qBFIT5o4BC0dSlni9BHOH2BgAc5B1NF+pBAMDTUH7JNBiN7RHTV7EHAIWDziiX/NK28+Q==
+  dependencies:
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/spinner" "2.0.11"
+
+"@chakra-ui/[email protected]":
+  version "2.1.0"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.1.0.tgz#8aeb9b753f0412f262743adf68519dfa85120b3e";
+  integrity 
sha512-E3jMPGqKuGTbt7mKtc8g/MOOenw2c4wqRC1vOypyFgmC8wsewdY+DJJNENF3atXAK7p5VMBKQfZ7ipNlHnDAwA==
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.0.2.tgz#e8230e24b974f3dc31ecb7106038e16e3f392811";
-  integrity 
sha512-QqXFYeX74mHSVp5Peqc+0CkYGQlvKQzpvOKkn00M3ZczsgVxoDNrUv0PI2V3fuZDwo1ziLBGJsjgMFbJ+JrYgA==
+"@chakra-ui/[email protected]":
+  version "2.2.1"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.2.1.tgz#3946d8c3b1d49dc425aa80f22d2f53661395e394";
+  integrity 
sha512-sgiogfLM8vas8QJTt7AJI4XxNXYdViCWj+xYJwyOwUN93dWKImqqx3O2ihCXoXTIqQWg1rcEgoJ5CxCg6rQaQQ==
   dependencies:
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/spinner" "^2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/image" "2.0.12"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.1"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.0.1.tgz#3be152b6eaef93e0727cd12d3269b2e4374335d2";
-  integrity 
sha512-lbOUfPmCtgIe0G7Iu6C2MaFP3FKOHgKWxDrYc3498TQ7/z5N1r7AO6jB+gFRGDbxJNLjRGOLG7tV0bufagGTUw==
+"@chakra-ui/[email protected]":
+  version "2.1.1"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.1.tgz#e8a682a4909cf8ee5771f7b287524df2be383b8a";
+  integrity 
sha512-OSa+F9qJ1xmF0zVxC1GU46OWbbhGf0kurHioSB729d+tRw/OMzmqrrfCJ7KVUUN8NEnTZXT5FIgokMvHGEt+Hg==
   dependencies:
-    "@chakra-ui/theme-tools" "^2.0.2"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.0.3.tgz#952ce697edf65b48959f1eb6c08b0395ee628458";
-  integrity 
sha512-LbCQBJzDLkx2jqOjuEG5zOWA5njEAhUlQ3GnSkqOGaiDQWgM6eSLxWkgpI5fKhBlZ2OvMxjSSFaCCpf8wvU+YQ==
-  dependencies:
-    "@chakra-ui/image" "2.0.3"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.5.tgz#55b571038b66e9f6d41633c102ea904c679dac5c";
+  integrity 
sha512-8uhrckMwoR/powlAhxiFZPM0s8vn0B2yEyEaRcwpy5NmRAJSTEotC2WkSyQl/Cjysx9scredumB5g+fBX7IqGQ==
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.0.2.tgz#1c214a6971d65f4a355e0807eba07c0b84ae2daa";
-  integrity 
sha512-rJOkgaWqtxaPfISNXjhl9J4efD96FBnQnAKQJZtlG3WpWmIse/BPv1Pg4OCexPTBQQSwFkbTBgBD0lWD/i2UUw==
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.0.13.tgz#5db6aa3425a6bebc2102cd9f58e434d5508dd999";
+  integrity 
sha512-T9W/zHpHZVcbx/BMg0JIXCgRycut/eYoTYee/E+eBxyPCH45n308AsYU2bZ8TgZxUwbYNRgMp4qRL/KHUQDv5g==
   dependencies:
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/spinner" "2.0.11"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.0.2.tgz#a5ef09324e4dbf95e1814a1755b2a35c365470ea";
-  integrity 
sha512-l2RE1031HR+vVqNQhfrJCuC1OzKTTLmyA8+ScGZhjV6G4LWGzU5LfsyGAXq53l1lFcx6O9XJzfgnxAvnGGKJsw==
+"@chakra-ui/[email protected]":
+  version "2.1.1"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/card/-/card-2.1.1.tgz#b981a68d81d0f6447eb0d4d3fdcd7846bab2111f";
+  integrity 
sha512-vvmfuNn6gkfv6bGcXQe6kvWHspziPZgYnnffiEjPaZYtaf98WRszpjyPbFv0oQR/2H1RSE1oaTqa/J1rHrzw3A==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/spinner" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-context" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.1.0"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.1.0.tgz#5df4917b06d8e671a9822c46f5e2ec259ef40c85";
-  integrity 
sha512-LPKhJM/IMp8LKdr52PVfSGAnmqcgwTMPcjyWT8jXQ3OhEXRUKc5rSUORmPtJmffNLjLq1nPCcSMWQsVHhJ9MXw==
-  dependencies:
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.2.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.2.5.tgz#ce1c409647d11bf947ff0316bc397bc7cf25316c";
+  integrity 
sha512-7fNH+Q2nB2uMSnYAPtYxnuwZ1MOJqblZHa/ScfZ/fjiPDyEae1m068ZP/l9yJ5zlawYMTkp83m/JVcu5QFYurA==
+  dependencies:
+    "@chakra-ui/form-control" "2.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+    "@chakra-ui/visually-hidden" "2.0.13"
     "@zag-js/focus-visible" "0.1.0"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.0.2.tgz#21cb225df159b488ee4c407729ef5a3cfcb4a5a5";
-  integrity 
sha512-Zn0Hd9BCGVNMOXerUlfmOdCeVAyl6XYo5WC/Skm/REAQygk22/WjV42sLeT+1+bpOLpSvO4ZnheXfD5sIuDdfA==
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.0.11.tgz#d0afcdb40ed1b1ceeabb4ac3e9f2f51fd3cbdac7";
+  integrity 
sha512-5Y2dl5cxNgOxHbjxyxsL6Vdze4wUUvwsMCCW3kXwgz2OUI2y5UsBZNcvhNJx3RchJEd0fylMKiKoKmnZMHN2aw==
   dependencies:
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.0.2.tgz#5ac6bee78032d77017299650971624dd9498acca";
-  integrity 
sha512-aIpkIQdmbuKTiM1IuZRI4iUPzcaWla8mXysKIL+M6g0QbpaO/Xw3eucnAS0qO24djCzkcCZSLnHsEimBOBJdgA==
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.0.13.tgz#c549d682c66f3e08b1f37e98a83ebe0421846496";
+  integrity 
sha512-ZI/3p84FPlW0xoDCZYqsnIvR6bTc2d/TlhwyTHsDDxq9ZOWp9c2JicVn6WTdWGdshk8itnZZdG50IcnizGnimA==
   dependencies:
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/icon" "3.0.13"
 
-"@chakra-ui/[email protected]":
-  version "2.0.4"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.0.4.tgz#143c1c0baa5f8b21a491776fc58107675075c5f8";
-  integrity 
sha512-DIR6CSPlkmi92LDR3IhjIediLk7GFWttlTUvJQP06ZUvN+iCpd5TjgchxOYzqlP4T9W0L62eZXsluOxmRF/JSQ==
+"@chakra-ui/[email protected]":
+  version "2.1.10"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.1.10.tgz#8d446550af80cf01a2ccd7470861cb0180112049";
+  integrity 
sha512-aUPouOUPn7IPm1v00/9AIkRuNrkCwJlbjVL1kJzLzxijYjbHvEHPxntITt+JWjtXPT8xdOq6mexLYCOGA67JwQ==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.0.2.tgz#9c2ffb3d766737447b9fbb1f1af028ad9f9eed2d";
-  integrity 
sha512-D3vQoyCRjAwCmB39jFvTv+fAXmALLhScXe6s/S7rdgSYxuSEksuGlNjvBUYAVwDXeE2sjDoeWMvrHydRGv44Bw==
-  dependencies:
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.0.11.tgz#b2deec368fc83f6675964785f823e4c0c1f5d4ac";
+  integrity 
sha512-UJb4vqq+/FPuwTCuaPeHa2lwtk6u7eFvLuwDCST2e/sBWGJC1R+1/Il5pHccnWs09FWxyZ9v/Oxkg/CG3jZR4Q==
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.0.2.tgz#e27312d61bc6d8bcd1eb913383ca1db1af6b99bd";
-  integrity 
sha512-mRYrnu1924spsPU5GaHSbaoX28Gbzf8PDkO6Y1R6r6MQKTLjpdbkFmyG0QyEixD8aoaSaCO7iVbJRnUJ+dhlww==
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.0.11.tgz#b49aa76423e5f4a4a8e717750c190fa5050a3dca";
+  integrity 
sha512-1YRt/jom+m3iWw9J9trcM6rAHDvD4lwThiO9raxUK7BRsYUhnPZvsMpcXU1Moax218C4rRpbI9KfPLaig0m1xQ==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/number-utils" "2.0.5"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.1"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.0.1.tgz#53bbc2c48dd9fdfb59af8cb8e20390ad7ddb3688";
-  integrity 
sha512-8RhAC7l5RHp9hNDN2M2feZ2wPaoSrgxzqx6VqLTIul2lwucpp1LTlrDlPCBMJe8fp51Q83IOCW4882ktsXxktA==
+"@chakra-ui/[email protected]":
+  version "2.0.10"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.0.10.tgz#cb6cd97ee38f8069789f08c31a828bf3a7e339ea";
+  integrity 
sha512-FwHOfw2P4ckbpSahDZef2KoxcvHPUg09jlicWdp24/MjdsOO5PAB/apm2UBvQflY4WAJyOqYaOdnXFlR6nF4cQ==
 
-"@chakra-ui/[email protected]":
-  version "3.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.0.2.tgz#1cf2584989160d93d8983bca7e237dd9368cc0c5";
-  integrity 
sha512-BV4IpONYr52V7rJnEYj5Ej946HD2BTOgOQpSB/LMeITfkp51/O9pOayNoVghYW7cFts+Opy4YmvLcuxFhWrD3Q==
+"@chakra-ui/[email protected]":
+  version "3.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.0.11.tgz#cb8bca7b6e8915afc58cdb1444530a2d1b03efd3";
+  integrity 
sha512-sNLI6NS6uUgrvYS6Imhoc1YlI6bck6pfxMBJcnXVSfdIjD6XjCmeY2YgzrtDS+o+J8bB3YJeIAG/vsVy5USE5Q==
   dependencies:
-    "@chakra-ui/react-utils" "^2.0.1"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-2.0.2.tgz#473dfc05245debae7d1e336870a4e0b466d6373a";
-  integrity 
sha512-hZBD4K1i3a8+RnW5jaoVfHeEm0zDKcyZ7yZCNGmmM7sz2LAw/LdE6+IKBoEbXc5Gf8KnEs9eH/TBcPDhS9KUQg==
-  dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.0.4.tgz#367fffecbd287e16836e093d4030dc6e3785d402";
+  integrity 
sha512-P936+WKinz5fgHzfwiUQjE/t7NC8bU89Tceim4tbn8CIm/9b+CsHX64eNw4vyJqRwt78TXQK7aGBIbS18R0q5Q==
+
+"@chakra-ui/[email protected]":
+  version "2.0.16"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-2.0.16.tgz#8a45ff26d77f06841ea986484d71ede312b4c22e";
+  integrity 
sha512-kIFPufzIlViNv7qi2PxxWWBvjLb+3IP5hUGmqOA9qcYz5TAdqblQqDClm0iajlIDNUFWnS4h056o8jKsQ42a5A==
+  dependencies:
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-focus-on-pointer-down" "2.0.4"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+    "@chakra-ui/shared-utils" "2.0.3"
+
+"@chakra-ui/[email protected]":
+  version "2.0.6"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.6.tgz#5e04d68ea070ef52ce212c2a99be9afcc015cfaf";
+  integrity 
sha512-ZIoqUbgJ5TcCbZRchMv4n7rOl1JL04doMebED88LO5mux36iVP9er/nnOY4Oke1bANKKURMrQf5VTT9hoYeA7A==
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.0.3.tgz#8fa0fad83256d79b31ec7970751f74f519ecf123";
-  integrity 
sha512-QcKUy0n26T1qOEoqk9rDmr9tumZs/+VXh9gIhWYKlmScm8Dy87qCMfOJ2M8/sUCQcqypl8SwlONQdiCZ99FUFQ==
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.0.13.tgz#19d6ca35555965a9aaa241b991a67bbc875ee53d";
+  integrity 
sha512-AVSJt+3Ukia/m9TCZZgyWvTY7pw88jArivWVJ2gySGYYIs6z/FJMnlwbCVldV2afS0g3cYaii7aARb/WrlG34Q==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/dom-utils" "2.0.4"
     react-focus-lock "^2.9.1"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.0.2.tgz#14f32407a69559805c91d6ef6695d1056a5e4b59";
-  integrity 
sha512-uelLKIZgrcahvodEAd2WjdCJUus9q9Wq++KliN+8VIhPti89s8eewyDh3xWvurbgby+oGkHyjDMmxHrkfa3YYQ==
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.0.13.tgz#51831f981a2e937b0258b4fd2dd4ceacda03c01a";
+  integrity 
sha512-J964JlgrxP+LP3kYmLk1ttbl73u6ghT+JQDjEjkEUc8lSS9Iv4u9XkRDQHuz2t2y0KHjQdH12PUfUfBqcITbYw==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.0.2.tgz#6153f33957f23b8f156b7ce4ce1605f89e67c1b5";
-  integrity 
sha512-3B4zsl51tevmO6T6xUKcclwxf4FClKtScaNvb8jMmVczTGRL7WhZ6LxXeYUJMms11C8W9uZczE5yXSP0qweeAw==
+"@chakra-ui/[email protected]":
+  version "2.1.2"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.1.2.tgz#1e413f6624e97b854569e8a19846c9162a4ec153";
+  integrity 
sha512-/vDBOqqnho9q++lay0ZcvnH8VuE0wT2OkZj+qDwFwjiHAtGPVxHCSpu9KC8BIHME5TlWjyO6riVyUCb2e2ip6w==
   dependencies:
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-utils" "2.0.9"
+    "@chakra-ui/utils" "2.0.12"
     compute-scroll-into-view "1.0.14"
     copy-to-clipboard "3.3.1"
 
-"@chakra-ui/[email protected]":
-  version "3.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.0.2.tgz#e8b380981690a543382f56f9d184f6b28f4b3d83";
-  integrity 
sha512-sas37byldn5O/TTIKHzxHBujEYqVPXegisoMqutLtF60fpXnb62aG1JTyorXSG3zJxJWQW7+AvjbOGyWKHXc0Q==
-  dependencies:
-    "@chakra-ui/utils" "2.0.2"
-
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.0.3.tgz#49a73c39aacbec1c956503adf1b20cd945889593";
-  integrity 
sha512-GLMJXLdR0y7CCZ0hKHf6YZLb8dlPpx4vdXWTbtLnIU5EfGIOSiCU4N3+0KcjvMtDB69hBr5W4h1XMJNpetP1EA==
+"@chakra-ui/[email protected]":
+  version "3.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.0.13.tgz#1782f8bd81946eabb39d4dde9eccebba1e5571ba";
+  integrity 
sha512-RaDLC4psd8qyInY2RX4AlYRfpLBNw3VsMih17BFf8EESVhBXNJcYy7Q9eMV/K4NvZfZT42vuVqGVNFmkG89lBQ==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/shared-utils" "2.0.3"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.0.2.tgz#fd14044f31aad687387e40043438f5b96a9a2d70";
-  integrity 
sha512-ODwdlsLha+EBPFSnCEqWjlndeXaL4cXvCk4rrKuvs9vexhOBr+X9V6KNn5Rmn/bXah+Wsrn+5g6T9V7BvRES3Q==
+"@chakra-ui/[email protected]":
+  version "2.0.12"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.0.12.tgz#e90b1d2a5f87fff90b1ef86ca75bfe6b44ac545d";
+  integrity 
sha512-uclFhs0+wq2qujGu8Wk4eEWITA3iZZQTitGiFSEkO9Ws5VUH+Gqtn3mUilH0orubrI5srJsXAmjVTuVwge1KJQ==
   dependencies:
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.0.2.tgz#556ab483f01e33efd4bf4a7a2105ea7d272b4c05";
-  integrity 
sha512-iElUGxj8YmVGcaCQlQovJJC4APHMh5vwlZU37IC6W3FdJzv+orVhzbuB98tuzfWHxjKQZeGhcz7+npIkN87D5w==
-  dependencies:
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.0.14.tgz#eec3d04834ab1ac7dab344e9bf14d779c4f4da31";
+  integrity 
sha512-CkSrUJeKWogOSt2pUf2vVv5s0bUVcAi4/XGj1JVCCfyIX6a6h1m8R69MShTPxPiQ0Mdebq5ATrW/aZQQXZzRGQ==
+  dependencies:
+    "@chakra-ui/form-control" "2.0.13"
+    "@chakra-ui/object-utils" "2.0.5"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/shared-utils" "2.0.3"
+
+"@chakra-ui/[email protected]":
+  version "2.1.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.1.11.tgz#6b0005dd897a901f2fded99c19fe47f60db80cb3";
+  integrity 
sha512-UP19V8EeI/DEODbWrZlqC0sg248bpFaWpMiM/+g9Bsxs9aof3yexpMD/7gb0yrfbIrkdvSBrcQeqxXGzbfoopw==
+  dependencies:
+    "@chakra-ui/breakpoint-utils" "2.0.5"
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/object-utils" "2.0.5"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/shared-utils" "2.0.3"
+
+"@chakra-ui/[email protected]":
+  version "2.0.3"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.3.tgz#5ba459a2541ad0c98cd98b20a8054664c129e9b4";
+  integrity 
sha512-SQ5I5rJrcHpVUcEftHLOh8UyeY+06R8Gv3k2RjcpvM6mb2Gktlz/4xl2GcUh3LWydgGQDW/7Rse5rQhKWgzmcg==
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.0.2.tgz#811655e68347237ae7c75b280e3306d197f0c25a";
-  integrity 
sha512-aRJRaJInqNkFRRIjW57SPNhj7ngxh0xkdQZeOohvOcd7VbjvHNgXO1glKjIXRzSRHyteCdGUzb/jo68NizE3bQ==
-  dependencies:
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.0.11.tgz#1008c5b629aa4120e5158be53f13d8d34bc2d71a";
+  integrity 
sha512-ltObaKQekP75GCCbN+vt1/mGABSCaRdQELmotHTBc5AioA3iyCDHH69ev+frzEwLvKFqo+RomAdAAgqBIMJ02Q==
 
-"@chakra-ui/[email protected]":
-  version "3.1.0"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.1.0.tgz#421dc60a9c2226d65bb7eb8772de283227fc3724";
-  integrity 
sha512-E05PUom+izNILJff0Yje8OMWHVN5C2H2A/F0aaptIJ+600YNWn5CuGvdlSMb/VWHziHT7u5xyrtv0mdbxMlYBA==
+"@chakra-ui/[email protected]":
+  version "3.2.8"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.2.8.tgz#7d5feccb7ac52891426c060dd2ed1df37420956d";
+  integrity 
sha512-djmEg/eJ5Qrjn7SArTqjsvlwF6mNeMuiawrTwnU+0EKq9Pq/wVSb7VaIhxdQYJLA/DbRhE/KPMogw1LNVKa4Rw==
   dependencies:
-    "@chakra-ui/react-env" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/breakpoint-utils" "2.0.5"
+    "@chakra-ui/react-env" "2.0.11"
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.0.3.tgz#b1d02fc20856315eb50db54de40d5a07eaf68368";
-  integrity 
sha512-hW1XBK0ZOEvnrwurqZiQ7+CFW8Olfk82BilNOulQ7LxQ2hQAAg4JBQxs755jVEtqhSAP+oe/yuWEabWtCWLGQw==
-  dependencies:
-    "@chakra-ui/clickable" "2.0.2"
-    "@chakra-ui/descendant" "3.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/popper" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/transition" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
-
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.0.3.tgz#2291837bf0cb5b15b7baabde2632be2144224b1e";
-  integrity 
sha512-GS1Apvrsr8scM1d/awVgJdcheITja4fMKTKwWljstw7SfAMOPc4skKIg+MzriLvtIialm1WFxOWYfiQ5MKAAcQ==
-  dependencies:
-    "@chakra-ui/close-button" "2.0.2"
-    "@chakra-ui/focus-lock" "2.0.3"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/portal" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/transition" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.1.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.1.5.tgz#73b6db93d6dec9d04ab7c2630a7984e3180fd769";
+  integrity 
sha512-2UusrQtxHcqcO9n/0YobNN3RJC8yAZU6oJbRPuvsQ9IL89scEWCTIxXEYrnIjeh/5zikcSEDGo9zM9Udg/XcsA==
+  dependencies:
+    "@chakra-ui/clickable" "2.0.11"
+    "@chakra-ui/descendant" "3.0.11"
+    "@chakra-ui/lazy-utils" "2.0.3"
+    "@chakra-ui/popper" "3.0.10"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-animation-state" "2.0.6"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-disclosure" "2.0.6"
+    "@chakra-ui/react-use-focus-effect" "2.0.7"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-outside-click" "2.0.5"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+    "@chakra-ui/transition" "2.0.12"
+
+"@chakra-ui/[email protected]":
+  version "2.2.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.2.4.tgz#dbe884a9245ed840b6511a4f06b4a622fa86de4c";
+  integrity 
sha512-K2cafyNI0b4OSAB55qIXt5DLZqj7E1G0+Fza02ZOBZpgTCNQyDtc0KzdVMJZ9ryxKd16LUk5UmKHugY/VpHEWQ==
+  dependencies:
+    "@chakra-ui/close-button" "2.0.13"
+    "@chakra-ui/focus-lock" "2.0.13"
+    "@chakra-ui/portal" "2.0.11"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/transition" "2.0.12"
     aria-hidden "^1.1.1"
     react-remove-scroll "^2.5.4"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.0.2.tgz#9b3a8c054307d5e6d251851ab14f2d55307f83b3";
-  integrity 
sha512-7RT5TMCSPtghX7M2Uy2cruLwO0uYCzIa49tQFDzQ2YCGMuRimzma9i0nuOqQz2yGHxa3C8WJJoO91jPKzCjIbg==
-  dependencies:
-    "@chakra-ui/counter" "2.0.2"
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.0.14.tgz#e6336228b9210f9543fe440bfc6478537810d59c";
+  integrity 
sha512-IARUAbP4pn1gP5fY2dK4wtbR3ONjzHgTjH4Zj3ErZvdu/yTURLaZmlb6UGHwgqjWLyioactZ/+n4Njj5CRjs8w==
+  dependencies:
+    "@chakra-ui/counter" "2.0.11"
+    "@chakra-ui/form-control" "2.0.13"
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
+    "@chakra-ui/react-use-event-listener" "2.0.5"
+    "@chakra-ui/react-use-interval" "2.0.3"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.5.tgz#c7595fc919fca7c43fe172bfd6c5197c653ee572";
+  integrity 
sha512-Thhohnlqze0i5HBJO9xkfOPq1rv3ji/hNPf2xh1fh4hxrNzdm3HCkz0c6lyRQwGuVoeltEHysYZLH/uWLFTCSQ==
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.0.3.tgz#b647f825683b889b1cabc18dc49ccc17ea1a460d";
-  integrity 
sha512-tnISIFno2Nqmh5ZjXyRnUiyuw94xLpFWoVK9tTo/yoR5Llbh58BqRyybOZZpu3DIjuK9qy9M67KBhRdqkOLUFQ==
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.0.5.tgz#231602066ddb96ae91dcc7da243b97ad46972398";
+  integrity 
sha512-/rIMoYI3c2uLtFIrnTFOPRAI8StUuu335WszqKM0KAW1lwG9H6uSbxqlpZT1Pxi/VQqZKfheGiMQOx5lfTmM/A==
+
+"@chakra-ui/[email protected]":
+  version "2.0.16"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.0.16.tgz#d31a6e2bce85aa2d1351ccb4cd9bf7a5134d3fb9";
+  integrity 
sha512-51cioNYpBSgi9/jq6CrzoDvo8fpMwFXu3SaFRbKO47s9Dz/OAW0MpjyabTfSpwOv0xKZE+ayrYGJopCzZSWXPg==
+  dependencies:
+    "@chakra-ui/descendant" "3.0.11"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.1.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.1.4.tgz#c44df775875faabe09ef13ce32150a2631c768dd";
+  integrity 
sha512-NXVtyMxYzDKzzQph/+GFRSM3tEj3gNvlCX/xGRsCOt9I446zJ1InCd/boXQKAc813coEN9McSOjNWgo+NCBD+Q==
+  dependencies:
+    "@chakra-ui/close-button" "2.0.13"
+    "@chakra-ui/lazy-utils" "2.0.3"
+    "@chakra-ui/popper" "3.0.10"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-animation-state" "2.0.6"
+    "@chakra-ui/react-use-disclosure" "2.0.6"
+    "@chakra-ui/react-use-focus-effect" "2.0.7"
+    "@chakra-ui/react-use-focus-on-pointer-down" "2.0.4"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "3.0.10"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.0.10.tgz#5d382c36359615e349e679445eb58c139dbb4d4f";
+  integrity 
sha512-6LacbBGX0piHWY/DYxOGCTTFAoRGRHpGIRzTgfNy8jxw4f+rukaVudd4Pc2fwjCTdobJKM8nGNYIYNv9/Dmq9Q==
   dependencies:
-    "@chakra-ui/descendant" "3.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@popperjs/core" "^2.9.3"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.0.2.tgz#14265da8007352497b914e3d9338e9333bb8927c";
-  integrity 
sha512-i9Tsx+gpN470V7eLPng+lVK25DfUdQ44OAzWMUavIiutCtVJknZEPYbSr72JnT4NHBnr7b8rqUBEYq9+36LmlQ==
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.0.11.tgz#7a6b3ebc621bb28b46550fcfb36b94926d0111a5";
+  integrity 
sha512-Css61i4WKzKO8ou1aGjBzcsXMy9LnfnpkOFfvaNCpUUNEd6c47z6+FhZNq7Gc38PGNjSfMLAd4LmH+H0ZanYIA==
   dependencies:
-    "@chakra-ui/close-button" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/popper" "3.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
 
-"@chakra-ui/[email protected]":
-  version "3.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.0.2.tgz#63994c39c316b03f68597099113e0719ac70ac8f";
-  integrity 
sha512-oEUsaFR4EPY3CvhEVeZNoa+mA/w+TvLlG3xlicIwv/3Fcfl6LD2Jhr6utnqAvHFxE/qRcUcXLX20ovy0Zrgm/Q==
+"@chakra-ui/[email protected]":
+  version "2.1.1"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.1.1.tgz#b94399af12e9324737f9e690201f78546572ac59";
+  integrity 
sha512-ddAXaYGNObGqH1stRAYxkdospf6J4CDOhB0uyw9BeHRSsYkCUQWkUBd/melJuZeGHEH2ItF9T7FZ4JhcepP3GA==
   dependencies:
-    "@chakra-ui/react-utils" "2.0.1"
-    "@popperjs/core" "^2.9.3"
+    "@chakra-ui/react-context" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.0.2.tgz#403dc6bb2d13dfc8a89acc47dd79ba4da8f20658";
-  integrity 
sha512-bk8P/hxvGbKhEZSI2LAFwk98W7ivff3NwpFOHjsna0uuBPG772mEOXnxsHBsr2moGroMXdBOS++czHn1T3cHhw==
+"@chakra-ui/[email protected]":
+  version "2.0.24"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.0.24.tgz#733f0eacf779d39029cee164027af7bf5c6c66c3";
+  integrity 
sha512-32+DGfoXAOUOXwjLstdGQ+k/YoCwdFxWbwnEAp7WleislYsMcl0JeINDAbvksQH0piBty77swTuWfUU5cIox7g==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/css-reset" "2.0.10"
+    "@chakra-ui/portal" "2.0.11"
+    "@chakra-ui/react-env" "2.0.11"
+    "@chakra-ui/system" "2.3.4"
+    "@chakra-ui/utils" "2.0.12"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.0.2.tgz#b3f3912dae4cf9196c72f6d8bd234b710a0dbd72";
-  integrity 
sha512-nx/aDZGEAnRx6jC4RLbfoXTTEeHoHGVlwBTUx7OKPus+hopBVvXHpA/UH+H8OJ5nq0PJ6XaDPCHc1FTrK+j0aw==
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.0.14.tgz#f214f728235782a2ac49c0eb507f151612e31b2e";
+  integrity 
sha512-e/hY1g92Xdu5d5A27NFfa1+ccE2q/A5H7sc/M7p0fId6KO33Dst25Hy+HThtqnYN0Y3Om58fiXEKo5SsdtvSfA==
   dependencies:
-    "@chakra-ui/theme-tools" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/form-control" "2.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@zag-js/focus-visible" "0.1.0"
+
+"@chakra-ui/[email protected]":
+  version "2.0.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.4.tgz#6e4284297a8a9b4e6f5f955b099bb6c2c6bbf8b9";
+  integrity 
sha512-qsKUEfK/AhDbMexWo5JhmdlkxLg5WEw2dFh4XorvU1/dTYsRfP6cjFfO8zE+X3F0ZFNsgKz6rbN5oU349GLEFw==
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.0.5.tgz#c434013ecc46c780539791d756dafdfc7c64320e";
+  integrity 
sha512-WYS0VBl5Q3/kNShQ26BP+Q0OGMeTQWco3hSiJWvO2wYLY7N1BLq6dKs8vyKHZfpwKh2YL2bQeAObi+vSkXp6tQ==
+
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-2.0.11.tgz#d9d65fb695de7aff15e1d0e97d57bb7bedce5fa2";
+  integrity 
sha512-rPwUHReSWh7rbCw0HePa8Pvc+Q82fUFvVjHTIbXKnE6d+01cCE7j4f1NLeRD9pStKPI6sIZm9xTGvOCzl8F8iw==
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.5.tgz#1e4c99ef0e59b5fe9263d0e186cd66afdfb6c87b";
+  integrity 
sha512-GApp+R/VjS1UV5ms5irrij5LOIgUM0dqSVHagyEFEz88LRKkqMD9RuO577ZsVd4Gn0ULsacVJCUA0HtNUBJNzA==
 
-"@chakra-ui/[email protected]":
+"@chakra-ui/[email protected]":
   version "2.0.6"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.0.6.tgz#cf018e2c45797e68a1d262f5ff70c7bef5f103d7";
-  integrity 
sha512-EwwFF8ib9L5OYTRJq450Uvk7DqQJA/W6TyBo2f7mUE0j56GmV8ZRdsaXGqqag/aopCS/1n+ZfpQvQr/qNhAQBQ==
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.6.tgz#2a324d3c67015a542ed589f899672d681889e1e7";
+  integrity 
sha512-M2kUzZkSBgDpfvnffh3kTsMIM3Dvn+CTMqy9zfY97NL4P3LAWL1MuFtKdlKfQ8hs/QpwS/ew8CTmCtaywn4sKg==
   dependencies:
-    "@chakra-ui/css-reset" "2.0.1"
-    "@chakra-ui/portal" "2.0.2"
-    "@chakra-ui/react-env" "2.0.2"
-    "@chakra-ui/system" "2.1.3"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/dom-utils" "2.0.4"
+    "@chakra-ui/react-use-event-listener" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.0.2.tgz#810b30204d04cc6fb54079394484a654d56f39e1";
-  integrity 
sha512-f3YF7sL13qpbiqlFF8eGcL8lZeAmY3ZwqJk8m2v3Ofi0M7Et/CV00E1TxY5kK3tvDtmMXC5lILf5QlHHNgH6wQ==
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.5.tgz#862430dfbab8e1f0b8e04476e5e25469bd044ec9";
+  integrity 
sha512-vKnXleD2PzB0nGabY35fRtklMid4z7cecbMG0fkasNNsgWmrQcXJOuEKUUVCynL6FBU6gBnpKFi5Aqj6x+K4tw==
+
+"@chakra-ui/[email protected]":
+  version "2.0.6"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.6.tgz#ec62aff9b9c00324a0a4c9a4523824a9ad5ef9aa";
+  integrity 
sha512-7WuKrhQkpSRoiI5PKBvuIsO46IIP0wsRQgXtStSaIXv+FIvIJl9cxQXTbmZ5q1Ds641QdAUKx4+6v0K/zoZEHg==
   dependencies:
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-2.0.2.tgz#fada8d098c5de95562a8b723e24cbebc6e3018da";
-  integrity 
sha512-iQdc58d1HjfkPi+CEoZNqY77oX94bsWpMie30UYIaTonc9OOH6r1WCGQc8cyQa3jKiX2m9v9IbnxZa9Z0rYrHw==
+"@chakra-ui/[email protected]":
+  version "2.0.6"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.6.tgz#db707ee119db829e9b21ff1c05e867938f1e27ba";
+  integrity 
sha512-4UPePL+OcCY37KZ585iLjg8i6J0sjpLm7iZG3PUwmb97oKHVHq6DpmWIM0VfSjcT6AbSqyGcd5BXZQBgwt8HWQ==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]", "@chakra-ui/react-utils@^2.0.1":
-  version "2.0.1"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.1.tgz#aebf12ee9f71fb7a27183d556131177f9ce745c8";
-  integrity 
sha512-xLiTn7WeUo2e3zvo8zUGpICgIGsLCPpkVbjEKhr1jAV41urqEtwlLc6uGir595OYqAC8zFDqs4HXhHouqNEtiw==
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.5.tgz#949aa99878b25b23709452d3c80a1570c99747cc";
+  integrity 
sha512-etLBphMigxy/cm7Yg22y29gQ8u/K3PniR5ADZX7WVX61Cgsa8ciCqjTE9sTtlJQWAQySbWxt9+mjlT5zaf+6Zw==
   dependencies:
-    "@chakra-ui/utils" "^2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/react@^2.2.0":
-  version "2.2.1"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.2.1.tgz#606a112350145e1bbd722db970dac7114a973d88";
-  integrity 
sha512-m2vFICTUO3GivTkJROnTTJT+w8otcYMraKqOSdrAGmsjqtZAp8/FaGS+1bxzeZnZTszMn65LoLvlgBUDrTHhQA==
-  dependencies:
-    "@chakra-ui/accordion" "2.0.3"
-    "@chakra-ui/alert" "2.0.2"
-    "@chakra-ui/avatar" "2.0.3"
-    "@chakra-ui/breadcrumb" "2.0.2"
-    "@chakra-ui/button" "2.0.2"
-    "@chakra-ui/checkbox" "2.1.0"
-    "@chakra-ui/close-button" "2.0.2"
-    "@chakra-ui/control-box" "2.0.2"
-    "@chakra-ui/counter" "2.0.2"
-    "@chakra-ui/css-reset" "2.0.1"
-    "@chakra-ui/editable" "2.0.2"
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/image" "2.0.3"
-    "@chakra-ui/input" "2.0.2"
-    "@chakra-ui/layout" "2.0.2"
-    "@chakra-ui/live-region" "2.0.2"
-    "@chakra-ui/media-query" "3.1.0"
-    "@chakra-ui/menu" "2.0.3"
-    "@chakra-ui/modal" "2.0.3"
-    "@chakra-ui/number-input" "2.0.2"
-    "@chakra-ui/pin-input" "2.0.3"
-    "@chakra-ui/popover" "2.0.2"
-    "@chakra-ui/popper" "3.0.2"
-    "@chakra-ui/portal" "2.0.2"
-    "@chakra-ui/progress" "2.0.2"
-    "@chakra-ui/provider" "2.0.6"
-    "@chakra-ui/radio" "2.0.2"
-    "@chakra-ui/react-env" "2.0.2"
-    "@chakra-ui/select" "2.0.2"
-    "@chakra-ui/skeleton" "2.0.6"
-    "@chakra-ui/slider" "2.0.2"
-    "@chakra-ui/spinner" "2.0.2"
-    "@chakra-ui/stat" "2.0.2"
-    "@chakra-ui/switch" "2.0.3"
-    "@chakra-ui/system" "2.1.3"
-    "@chakra-ui/table" "2.0.2"
-    "@chakra-ui/tabs" "2.0.3"
-    "@chakra-ui/tag" "2.0.2"
-    "@chakra-ui/textarea" "2.0.3"
-    "@chakra-ui/theme" "2.1.0"
-    "@chakra-ui/toast" "2.1.0"
-    "@chakra-ui/tooltip" "2.0.2"
-    "@chakra-ui/transition" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
-
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.0.2.tgz#35f7fa0d4422f9a49b6577c2259b71e6d1ad9603";
-  integrity 
sha512-aXYRJFsi3xrcacPI+FDZ1fxRQc9PMFnYXvqTug4I7wIwZUE467vD4G90c6/b/tUzrerDkVcPhHbqFy8ENbrvdA==
+"@chakra-ui/[email protected]":
+  version "2.0.7"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.7.tgz#bd03290cac32e0de6a71ce987f939a5e697bca04";
+  integrity 
sha512-wI8OUNwfbkusajLac8QtjfSyNmsNu1D5pANmnSHIntHhui6Jwv75Pxx7RgmBEnfBEpleBndhR9E75iCjPLhZ/A==
   dependencies:
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/dom-utils" "2.0.4"
+    "@chakra-ui/react-use-event-listener" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.6"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.0.6.tgz#0700f118d31782b2a0f8764b3a22ed3d722f33c8";
-  integrity 
sha512-nbZEfA7vSxJ8qXM0sb+e/Dh8t2ZcAkjWUzScMvO8FWfblk3wkoeUT0ocTwJ4eDyTzEVBu+ym7Uc+ACZmBheabQ==
+"@chakra-ui/[email protected]":
+  version "2.0.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.4.tgz#aeba543c451ac1b0138093234e71d334044daf84";
+  integrity 
sha512-L3YKouIi77QbXH9mSLGEFzJbJDhyrPlcRcuu+TSC7mYaK9E+3Ap+RVSAVxj+CfQz7hCWpikPecKDuspIPWlyuA==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/media-query" "3.1.0"
-    "@chakra-ui/system" "2.1.3"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-event-listener" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.0.2.tgz#e772721d350523a2dbfba188383b2b66d7e67ac3";
-  integrity 
sha512-aWpjqFGN61fv3dKyBrP6c68MXmkYtZ6jeDWIKkgzc7ntb6Nnf6KDK8seZM0SmQR2F3GIejLt8AgnuIW/UBUa/Q==
+"@chakra-ui/[email protected]":
+  version "2.0.3"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.0.3.tgz#d5c7bce117fb25edb54e3e2c666e900618bb5bb2";
+  integrity 
sha512-Orbij5c5QkL4NuFyU4mfY/nyRckNBgoGe9ic8574VVNJIXfassevZk0WB+lvqBn5XZeLf2Tj+OGJrg4j4H9wzw==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]", "@chakra-ui/spinner@^2.0.2":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.0.2.tgz#4dc529bac5208e28a64e9fbde9d3f40b62cce629";
-  integrity 
sha512-jC6+pwkCQb5vfGsS/55EhH2UzsToeCvpfXLQ6TPWDPA2NHMTRskilHwKQT/i0nAgRcCq400FvcfIr5uAPs+Igg==
+"@chakra-ui/[email protected]":
+  version "2.0.3"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.0.3.tgz#27cf703858e65ecb5a0eef26215c794ad2a5353d";
+  integrity 
sha512-exNSQD4rPclDSmNwtcChUCJ4NuC2UJ4amyNGBqwSjyaK5jNHk2kkM7rZ6I0I8ul+26lvrXlSuhyv6c2PFwbFQQ==
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.5.tgz#13181e1a43219c6a04a01f84de0188df042ee92e";
+  integrity 
sha512-uc+MozBZ8asaUpO8SWcK6D4svRPACN63jv5uosUkXJR+05jQJkUofkfQbf2HeGVbrWCr0XZsftLIm4Mt/QMoVw==
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.5.tgz#6a9896d2c2d35f3c301c3bb62bed1bf5290d1e60";
+  integrity 
sha512-WmtXUeVaMtxP9aUGGG+GQaDeUn/Bvf8TI3EU5mE1+TtqLHxyA9wtvQurynrogvpilLaBADwn/JeBeqs2wHpvqA==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.0.2.tgz#8e211270d31bab8d64209f737cde23c50b5fe98b";
-  integrity 
sha512-GrQgiof8olOEVFAUtq5GA2cCUJqcSLMpS/6StBFR4fesrg5MAblfVYYY7uayqX/RnJU1BNElLOl/JAQ965LGXw==
+"@chakra-ui/[email protected]":
+  version "2.0.6"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.6.tgz#e489d61672e6f473b7fd362d816e2e27ed3b2af6";
+  integrity 
sha512-Vtgl3c+Mj4hdehFRFIgruQVXctwnG1590Ein1FiU8sVnlqO6bpug6Z+B14xBa+F+X0aK+DxnhkJFyWI93Pks2g==
   dependencies:
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
+    "@chakra-ui/event-utils" "2.0.6"
+    "@chakra-ui/react-use-latest-ref" "2.0.3"
+    framesync "5.3.0"
 
-"@chakra-ui/[email protected]":
-  version "2.2.0"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.2.0.tgz#d7fdca558db05100ea26ae8352b13c5840da9cc3";
-  integrity 
sha512-5THQlrMr6CsiulNtjzZV3DqYD85eQ+S8G6rsnjAKqFVJ1G29R392RKK/67R96WIRUJRtsHPq2REeTgAxGLDhOQ==
+"@chakra-ui/[email protected]":
+  version "2.0.3"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.0.3.tgz#9da3d53fd75f1c3da902bd6af71dcb1a7be37f31";
+  integrity 
sha512-A2ODOa0rm2HM4aqXfxxI0zPLcn5Q7iBEjRyfIQhb+EH+d2OFuj3L2slVoIpp6e/km3Xzv2d+u/WbjgTzdQ3d0w==
+
+"@chakra-ui/[email protected]":
+  version "2.0.3"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.3.tgz#bf63ac8c94460aa1b20b6b601a0ea873556ffb1b";
+  integrity 
sha512-dlTvQURzmdfyBbNdydgO4Wy2/HV8aJN8LszTtyb5vRZsyaslDM/ftcxo8E8QjHwRLD/V1Epb/A8731QfimfVaQ==
+
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.0.5.tgz#4bbffb64f97dcfe1d7edeb0f03bb1d5fbc48df64";
+  integrity 
sha512-4arAApdiXk5uv5ZeFKltEUCs5h3yD9dp6gTIaXbAdq+/ENK3jMWTwlqzNbJtCyhwoOFrblLSdBrssBMIsNQfZQ==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
-    csstype "^3.0.11"
+    "@zag-js/element-size" "0.1.0"
 
-"@chakra-ui/[email protected]":
+"@chakra-ui/[email protected]":
   version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.0.3.tgz#363e828af5ed9ad39458f7258a33d8af0e4cf7c0";
-  integrity 
sha512-k7HLnKBM9GsY/RdqUWqe233QNFa2JtE+G4UyX8BsYLquWOkBfgJvI+f2gSUye1zLS8e1bFwz5BBIljTQMb/Smw==
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.3.tgz#16ca397dbca55a64811575884cb81a348d86d4e2";
+  integrity 
sha512-rBBUkZSQq3nJQ8fuMkgZNY2Sgg4vKiKNp05GxAwlT7TitOfVZyoTriqQpqz296bWlmkICTZxlqCWfE5fWpsTsg==
   dependencies:
-    "@chakra-ui/checkbox" "2.1.0"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.1.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.1.3.tgz#a140335f56087f761d0a8cef6e4c77f971f054da";
-  integrity 
sha512-f9GfJr7HGxxhyAbXmka/k/mPsLl8wl+5fZUWglfRg4iddmsuYQcJEYg8+ewCyr7MA1Ddw9bPVgsC5uf/KYlo3w==
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.5.tgz#aede8f13f2b3de254b4ffa3b8cec1b70bd2876c5";
+  integrity 
sha512-y9tCMr1yuDl8ATYdh64Gv8kge5xE1DMykqPDZw++OoBsTaWr3rx40wblA8NIWuSyJe5ErtKP2OeglvJkYhryJQ==
+
+"@chakra-ui/[email protected]":
+  version "2.0.9"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.9.tgz#5cdf0bc8dee57c15f15ace04fbba574ec8aa6ecc";
+  integrity 
sha512-nlwPBVlQmcl1PiLzZWyrT3FSnt3vKSkBMzQ0EF4SJWA/nOIqTvmffb5DCzCqPzgQaE/Da1Xgus+JufFGM8GLCQ==
   dependencies:
-    "@chakra-ui/color-mode" "2.0.4"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/styled-system" "2.2.0"
-    "@chakra-ui/utils" "2.0.2"
-    react-fast-compare "3.2.0"
+    "@chakra-ui/utils" "2.0.12"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.0.2.tgz#328b61abe3209a8ed215031cfea8a92c885400a5";
-  integrity 
sha512-VkcXAmvNlhWXZ5qPUAVqW4DKARSNdCN4Ib8ViiX8lXqBUHK+IBAe2s6iB70FwzdaPqwrw2LndqRrLg/4w4FE3w==
+"@chakra-ui/[email protected]":
+  version "2.4.2"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.4.2.tgz#60d0cf80965d77ab6e280e28124b800a0d7a5f8c";
+  integrity 
sha512-lPDCCuY3S7XSeIK+P+ypGIL+lFqEZQt8H3Iyq4coblULMsj8skdSUqaoQ4I9fGgOi1koTPe4OlXb+rmqwQQ9MQ==
+  dependencies:
+    "@chakra-ui/accordion" "2.1.4"
+    "@chakra-ui/alert" "2.0.13"
+    "@chakra-ui/avatar" "2.2.1"
+    "@chakra-ui/breadcrumb" "2.1.1"
+    "@chakra-ui/button" "2.0.13"
+    "@chakra-ui/card" "2.1.1"
+    "@chakra-ui/checkbox" "2.2.5"
+    "@chakra-ui/close-button" "2.0.13"
+    "@chakra-ui/control-box" "2.0.11"
+    "@chakra-ui/counter" "2.0.11"
+    "@chakra-ui/css-reset" "2.0.10"
+    "@chakra-ui/editable" "2.0.16"
+    "@chakra-ui/form-control" "2.0.13"
+    "@chakra-ui/hooks" "2.1.2"
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/image" "2.0.12"
+    "@chakra-ui/input" "2.0.14"
+    "@chakra-ui/layout" "2.1.11"
+    "@chakra-ui/live-region" "2.0.11"
+    "@chakra-ui/media-query" "3.2.8"
+    "@chakra-ui/menu" "2.1.5"
+    "@chakra-ui/modal" "2.2.4"
+    "@chakra-ui/number-input" "2.0.14"
+    "@chakra-ui/pin-input" "2.0.16"
+    "@chakra-ui/popover" "2.1.4"
+    "@chakra-ui/popper" "3.0.10"
+    "@chakra-ui/portal" "2.0.11"
+    "@chakra-ui/progress" "2.1.1"
+    "@chakra-ui/provider" "2.0.24"
+    "@chakra-ui/radio" "2.0.14"
+    "@chakra-ui/react-env" "2.0.11"
+    "@chakra-ui/select" "2.0.14"
+    "@chakra-ui/skeleton" "2.0.18"
+    "@chakra-ui/slider" "2.0.14"
+    "@chakra-ui/spinner" "2.0.11"
+    "@chakra-ui/stat" "2.0.13"
+    "@chakra-ui/styled-system" "2.4.0"
+    "@chakra-ui/switch" "2.0.17"
+    "@chakra-ui/system" "2.3.4"
+    "@chakra-ui/table" "2.0.12"
+    "@chakra-ui/tabs" "2.1.5"
+    "@chakra-ui/tag" "2.0.13"
+    "@chakra-ui/textarea" "2.0.14"
+    "@chakra-ui/theme" "2.2.2"
+    "@chakra-ui/theme-utils" "2.0.5"
+    "@chakra-ui/toast" "4.0.4"
+    "@chakra-ui/tooltip" "2.2.2"
+    "@chakra-ui/transition" "2.0.12"
+    "@chakra-ui/utils" "2.0.12"
+    "@chakra-ui/visually-hidden" "2.0.13"
+
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.0.14.tgz#b2230702e31d2b9b4cc7848b18ba7ae8e4c89bdb";
+  integrity 
sha512-fvVGxAtLaIXGOMicrzSa6imMw5h26S1ar3xyNmXgR40dbpTPHmtQJkbHBf9FwwQXgSgKWgBzsztw5iDHCpPVzA==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/form-control" "2.0.13"
 
-"@chakra-ui/[email protected]":
+"@chakra-ui/[email protected]":
   version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-2.0.3.tgz#678a1814384c949a1b8bf725c21f2e840060f9e5";
-  integrity 
sha512-iBi7hSiNv7y9Zu0eR0b4SCBdKoY/5aOKhToZIm0iv5qJPunN3ap3zVAHL36ucPAIv19rC0GaOwqLsNQErMkMYQ==
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.3.tgz#97cbc11282e381ebd9f581c603088f9d60ead451";
+  integrity 
sha512-pCU+SUGdXzjAuUiUT8mriekL3tJVfNdwSTIaNeip7k/SWDzivrKGMwAFBxd3XVTDevtVusndkO4GJuQ3yILzDg==
+
+"@chakra-ui/[email protected]":
+  version "2.0.18"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.0.18.tgz#a2af241f0b1b692db4d10b90a887107a5e401c7d";
+  integrity 
sha512-qjcD8BgVx4kL8Lmb8EvmmDGM2ICl6CqhVE2LShJrgG7PDM6Rt6rYM617kqLurLYZjbJUiwgf9VXWifS0IpT31Q==
   dependencies:
-    "@chakra-ui/clickable" "2.0.2"
-    "@chakra-ui/descendant" "3.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/media-query" "3.2.8"
+    "@chakra-ui/react-use-previous" "2.0.3"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-2.0.2.tgz#d989d1e64ed89f92447ca4f2316506282d16518f";
-  integrity 
sha512-/TqjwPNTUjDofvTEulrNELS6/ls1n54YMFXMwGNwrEbNlJPgoE555t1N3jpdoNKH4kLhvkFcC6lfkDdWwnZ1BA==
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.0.14.tgz#8fa8fb5df292525d8b97ea3c3c666e400fb365f2";
+  integrity 
sha512-z4Q5rWtYVTdFgBVvR6aUhSMg3CQuAgjJGHvLHEGDCUjYCuBXrb3SmWyvv03uKyjSbwRyKqSsvAnSCxtmHODt/w==
+  dependencies:
+    "@chakra-ui/number-utils" "2.0.5"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-callback-ref" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-latest-ref" "2.0.3"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-pan-event" "2.0.6"
+    "@chakra-ui/react-use-size" "2.0.5"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.0.11"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.0.11.tgz#a5dd76b6cb0f3524d9b90b73fa4acfb6adc69f33";
+  integrity 
sha512-piO2ghWdJzQy/+89mDza7xLhPnW7pA+ADNbgCb1vmriInWedS41IBKe+pSPz4IidjCbFu7xwKE0AerFIbrocCA==
+
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.0.13.tgz#1805817ab54f9d9b663b465fcb255285d22d0152";
+  integrity 
sha512-6XeuE/7w0BjyCHSxMbsf6/rNOOs8BSit1NS7g7+Jd/40Pc/SKlNWLd3kxXPid4eT3RwyNIdMPtm30OActr9nqQ==
+  dependencies:
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.4.0"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.4.0.tgz#4b50079606331e4e8fda7ea59da9db51b446d40c";
+  integrity 
sha512-G4HpbFERq4C1cBwKNDNkpCiliOICLXjYwKI/e/6hxNY+GlPxt8BCzz3uhd3vmEoG2vRM4qjidlVjphhWsf6vRQ==
   dependencies:
-    "@chakra-ui/icon" "3.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    csstype "^3.0.11"
+    lodash.mergewith "4.6.2"
 
-"@chakra-ui/[email protected]":
-  version "2.0.3"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.0.3.tgz#0629fbdb1f9af6721edae07b5098e3fc4d1af44c";
-  integrity 
sha512-esOJa0vSrSsgDJGjPAbnPNPvemN1QUKYFYLFTOM/LR6BzI21EL8PX4Bh3AJM6aJK0GjeR0+SeKMuuuLL4oFnmw==
+"@chakra-ui/[email protected]":
+  version "2.0.17"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.0.17.tgz#1d6904b6cde2469212bbd8311b749b96c653a9a3";
+  integrity 
sha512-BQabfC6qYi5xBJvEFPzKq0yl6fTtTNNEHTid5r7h0PWcCnAiHwQJTpQRpxp+AjK569LMLtTXReTZvNBrzEwOrA==
   dependencies:
-    "@chakra-ui/form-control" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/checkbox" "2.2.5"
 
-"@chakra-ui/[email protected]", "@chakra-ui/theme-tools@^2.0.2":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.0.2.tgz#2f59f14f553dcb5ccc8e8492cb9524954fe1bf89";
-  integrity 
sha512-E01ZJZB4XVqkvn2hOXKQ/uVkvaPLQN1SyxAYXjFZGyZ1ppBLl362EWfY9IgWNzDITgq9MCJyQFfm2mXwQDUNzA==
+"@chakra-ui/[email protected]":
+  version "2.3.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.3.4.tgz#425bf7eebf61bd92aa68f60a6b62c380274fbe4e";
+  integrity 
sha512-/2m8hFfFzOMO2OlwHxTWqINOBJMjxWwU5V/AcB7C0qS51Dcj9c7kupilM6QdqiOLLdMS7mIVRSYr8jn8gMw9fA==
+  dependencies:
+    "@chakra-ui/color-mode" "2.1.10"
+    "@chakra-ui/react-utils" "2.0.9"
+    "@chakra-ui/styled-system" "2.4.0"
+    "@chakra-ui/theme-utils" "2.0.5"
+    "@chakra-ui/utils" "2.0.12"
+    react-fast-compare "3.2.0"
+
+"@chakra-ui/[email protected]":
+  version "2.0.12"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.0.12.tgz#387653cf660318b13086b6497aca2b671deb055a";
+  integrity 
sha512-TSxzpfrOoB+9LTdNTMnaQC6OTsp36TlCRxJ1+1nAiCmlk+m+FiNzTQsmBalDDhc29rm+6AdRsxSPsjGWB8YVwg==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
-    "@ctrl/tinycolor" "^3.4.0"
+    "@chakra-ui/react-context" "2.0.5"
 
-"@chakra-ui/[email protected]":
-  version "2.1.0"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-2.1.0.tgz#2a71da8c7f4c191e3711ef6139cec398a4fd7ad4";
-  integrity 
sha512-OHvKCQ/QUHc3ZVgKKshYkvholiDhPf7vEPZcNOi5rnaFSP4PzWd00d1i7HOXYSyv/TGDOBRzs1IcodKfG6FzgA==
+"@chakra-ui/[email protected]":
+  version "2.1.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-2.1.5.tgz#827b0e71eb173c09c31dcbbe05fc1146f4267229";
+  integrity 
sha512-XmnKDclAJe0FoW4tdC8AlnZpPN5fcj92l4r2sqiL9WyYVEM71hDxZueETIph/GTtfMelG7Z8e5vBHP4rh1RT5g==
+  dependencies:
+    "@chakra-ui/clickable" "2.0.11"
+    "@chakra-ui/descendant" "3.0.11"
+    "@chakra-ui/lazy-utils" "2.0.3"
+    "@chakra-ui/react-children-utils" "2.0.4"
+    "@chakra-ui/react-context" "2.0.5"
+    "@chakra-ui/react-use-controllable-state" "2.0.6"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+    "@chakra-ui/react-use-safe-layout-effect" "2.0.3"
+
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-2.0.13.tgz#ad7349bfcdd5642d3894fadb43728acc0f061101";
+  integrity 
sha512-W1urf+tvGMt6J3cc31HudybYSl+B5jYUP5DJxzXM9p+n3JrvXWAo4D6LmpLBHY5zT2mNne14JF1rVeRcG4Rtdg==
+  dependencies:
+    "@chakra-ui/icon" "3.0.13"
+    "@chakra-ui/react-context" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.0.14.tgz#a79a3fdd850a3303e6ebb68d64b7c334de03da4d";
+  integrity 
sha512-r8hF1rCi+GseLtY/IGeVWXFN0Uve2b820UQumRj4qxj7PsPqw1hFg7Cecbbb9zwF38K/m+D3IdwFeJzI1MtgRA==
   dependencies:
-    "@chakra-ui/anatomy" "2.0.1"
-    "@chakra-ui/theme-tools" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/form-control" "2.0.13"
 
-"@chakra-ui/[email protected]":
-  version "2.1.0"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-2.1.0.tgz#8e0c8ea20493f17b541bf964b2c64e114acce4ec";
-  integrity 
sha512-xXgwzff/gtNrq2HGGG3fuqcfRQEIObluHzHhqgS3gesf8KYut/5ZJoLdgV4RKE+NYgJIi77BFUcQDiLJttxxPA==
-  dependencies:
-    "@chakra-ui/alert" "2.0.2"
-    "@chakra-ui/close-button" "2.0.2"
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/portal" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/system" "2.1.3"
-    "@chakra-ui/theme" "2.1.0"
-    "@chakra-ui/transition" "2.0.2"
-    "@chakra-ui/utils" "2.0.2"
-
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.0.2.tgz#ac3993aea85abce94b882bebc20e23af57498c80";
-  integrity 
sha512-oK6gXybFe/MmHBXbd9w3XgNChVHQ9BeLW0IAtFeDyeHn5gJg0iKul/SNmJkD73Iyv/j+BsmBMn98mbNYQkeMQA==
+"@chakra-ui/[email protected]":
+  version "2.0.14"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.0.14.tgz#6c523284ab384ca57a3aef1fcfa7c32ed357fbde";
+  integrity 
sha512-lVcDmq5pyU0QbsIFKjt/iVUFDap7di2QHvPvGChA1YSjtg1PtuUi+BxEXWzp3Nfgw/N4rMvlBs+S0ynJypdwbg==
   dependencies:
-    "@chakra-ui/hooks" "2.0.2"
-    "@chakra-ui/popper" "3.0.2"
-    "@chakra-ui/portal" "2.0.2"
-    "@chakra-ui/react-utils" "2.0.1"
-    "@chakra-ui/utils" "2.0.2"
-    "@chakra-ui/visually-hidden" "2.0.2"
+    "@chakra-ui/anatomy" "2.1.0"
+    color2k "^2.0.0"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.0.2.tgz#f2713814990d31cbe2a647d3baa09f32646c9810";
-  integrity 
sha512-s98gDFIGbv60WMyniVjy381NXxgS1Y/6RACR1Z1pReC5XZLY5GyMqeRYyFCAeE78qKkqon77Y8EDPQXl6X78dw==
+"@chakra-ui/[email protected]":
+  version "2.0.5"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.5.tgz#ad1e53fc7f71326d15b9b01a157c7e2a029f3dda";
+  integrity 
sha512-QQowSM8fvQlTmT0w9wtqUlWOB4i+9eA7P4XRm4bfhBMZ7XpK4ctV95sPeGqaXVccsz5m0q1AuGWa+j6eMCbrrg==
   dependencies:
-    "@chakra-ui/utils" "2.0.2"
+    "@chakra-ui/styled-system" "2.4.0"
+    "@chakra-ui/theme" "2.2.2"
+    lodash.mergewith "4.6.2"
 
-"@chakra-ui/[email protected]", "@chakra-ui/utils@^2.0.2":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.2.tgz#130ba1647ea2b94ad956ae4cbcf685838d350593";
-  integrity 
sha512-9AC/ir9zm0shgFG7kdzOKUH2Wx5VB71M3uRMEsMZf75YlhhiU7AvBNtWXnJu+CBiTi41rKa5A+2ImMOsuPfGbA==
+"@chakra-ui/[email protected]":
+  version "2.2.2"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-2.2.2.tgz#5ea69adde78ee6ea59f9dce674947ed8be2ebc62";
+  integrity 
sha512-7DlOQiXmnaqYyqXwqmfFSCWGkUonuqmNC5mmUCwxI435KgHNCaE2bIm6DI7N2NcIcuVcfc8Vn0UqrDoGU3zJBg==
+  dependencies:
+    "@chakra-ui/anatomy" "2.1.0"
+    "@chakra-ui/theme-tools" "2.0.14"
+
+"@chakra-ui/[email protected]":
+  version "4.0.4"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-4.0.4.tgz#254fb5c4c5bde0a373aab574927c654442fb0411";
+  integrity 
sha512-Gv52UQ4fJtziL9Qg0Yterb76C1GgzViryPDf2dxSzTlnCcKIbY4ktEhehyFBjDXYoGkFb47NZUEyhy+u8p3GUA==
+  dependencies:
+    "@chakra-ui/alert" "2.0.13"
+    "@chakra-ui/close-button" "2.0.13"
+    "@chakra-ui/portal" "2.0.11"
+    "@chakra-ui/react-use-timeout" "2.0.3"
+    "@chakra-ui/react-use-update-effect" "2.0.5"
+    "@chakra-ui/styled-system" "2.4.0"
+    "@chakra-ui/theme" "2.2.2"
+
+"@chakra-ui/[email protected]":
+  version "2.2.2"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.2.2.tgz#8ac0759fbc5adacec6e0ac7419c8055a67a95b5c";
+  integrity 
sha512-WDgQVEMHdsyUpKG9Nogy2FKLBgfdJG7hTSrSbH1WLvHsPkpPLknL4i5Z/pCvpa4A7SzTa6ps350mxtJ054MeMg==
+  dependencies:
+    "@chakra-ui/popper" "3.0.10"
+    "@chakra-ui/portal" "2.0.11"
+    "@chakra-ui/react-types" "2.0.5"
+    "@chakra-ui/react-use-disclosure" "2.0.6"
+    "@chakra-ui/react-use-event-listener" "2.0.5"
+    "@chakra-ui/react-use-merge-refs" "2.0.5"
+
+"@chakra-ui/[email protected]":
+  version "2.0.12"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.0.12.tgz#876c6ed24e442a720a8570490a93cb1f87008700";
+  integrity 
sha512-ff6eU+m08ccYfCkk0hKfY/XlmGxCrfbBgsKgV4mirZ4SKUL1GVye8CYuHwWQlBJo+8s0yIpsTNxAuX4n/cW9/w==
+
+"@chakra-ui/[email protected]":
+  version "2.0.12"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.12.tgz#5ab8a4529fca68d9f8c6722004f6a5129b0b75e9";
+  integrity 
sha512-1Z1MgsrfMQhNejSdrPJk8v5J4gCefHo+1wBmPPHTz5bGEbAAbZ13aXAfXy8w0eFy0Nvnawn0EHW7Oynp/MdH+Q==
   dependencies:
     "@types/lodash.mergewith" "4.6.6"
     css-box-model "1.2.1"
     framesync "5.3.0"
     lodash.mergewith "4.6.2"
 
-"@chakra-ui/[email protected]":
-  version "2.0.2"
-  resolved 
"https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.0.2.tgz#741f0c25d0574d9903617c9e7ea901cf00b699f2";
-  integrity 
sha512-zYeLzaeouPbBBPDBAdRwj+jyxLJbtU6vW6r4kSQKfHoQPxJ+1A1HxRmDrj4FZJXk0CnBc4m7HF6Zuy7A5eCokg==
-  dependencies:
-    "@chakra-ui/utils" "2.0.2"
-
-"@ctrl/tinycolor@^3.4.0":
-  version "3.4.0"
-  resolved 
"https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz#c3c5ae543c897caa9c2a68630bed355be5f9990f";
-  integrity 
sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==
+"@chakra-ui/[email protected]":
+  version "2.0.13"
+  resolved 
"https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.0.13.tgz#6553467d93f206d17716bcbe6e895a84eef87472";
+  integrity 
sha512-sDEeeEjLfID333EC46NdCbhK2HyMXlpl5HzcJjuwWIpyVz4E1gKQ9hlwpq6grijvmzeSywQ5D3tTwUrvZck4KQ==
 
 "@discoveryjs/json-ext@^0.5.0":
   version "0.5.7"
@@ -3625,6 +3816,11 @@
   resolved 
"https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d";
   integrity 
sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
 
+"@zag-js/[email protected]":
+  version "0.1.0"
+  resolved 
"https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.1.0.tgz#dfdb3f66a70328d0c3149aae29b8f99c10590c22";
+  integrity 
sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ==
+
 "@zag-js/[email protected]":
   version "0.1.0"
   resolved 
"https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz#9777bbaff8316d0b3a14a9095631e1494f69dbc7";
@@ -3784,11 +3980,11 @@ argparse@^2.0.1:
   integrity 
sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
 
 aria-hidden@^1.1.1:
-  version "1.1.3"
-  resolved 
"https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254";
-  integrity 
sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
+  version "1.2.3"
+  resolved 
"https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954";
+  integrity 
sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==
   dependencies:
-    tslib "^1.0.0"
+    tslib "^2.0.0"
 
 aria-query@^4.2.2:
   version "4.2.2"
@@ -4493,7 +4689,7 @@ [email protected]:
   resolved 
"https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25";
   integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
 
-color-name@^1.0.0, color-name@~1.1.4:
+color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
   version "1.1.4"
   resolved 
"https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2";
   integrity 
sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
@@ -4506,6 +4702,11 @@ color-string@^1.9.0:
     color-name "^1.0.0"
     simple-swizzle "^0.2.2"
 
+color2k@^2.0.0:
+  version "2.0.2"
+  resolved 
"https://registry.yarnpkg.com/color2k/-/color2k-2.0.2.tgz#ac2b4aea11c822a6bcb70c768b5a289f4fffcebb";
+  integrity 
sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==
+
 color@^4.2.3:
   version "4.2.3"
   resolved 
"https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a";
@@ -4760,6 +4961,11 @@ cssesc@^3.0.0:
   resolved 
"https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee";
   integrity 
sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
 
+cssfontparser@^1.2.1:
+  version "1.2.1"
+  resolved 
"https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3";
+  integrity 
sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==
+
 cssnano-preset-default@^5.2.11:
   version "5.2.11"
   resolved 
"https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.11.tgz#28350471bc1af9df14052472b61340347f453a53";
@@ -5550,6 +5756,14 @@ domutils@^2.8.0:
     domelementtype "^2.2.0"
     domhandler "^4.2.0"
 
+echarts@^5.4.2:
+  version "5.4.2"
+  resolved 
"https://registry.yarnpkg.com/echarts/-/echarts-5.4.2.tgz#9f38781c9c6ae323e896956178f6956952c77a48";
+  integrity 
sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA==
+  dependencies:
+    tslib "2.3.0"
+    zrender "5.4.3"
+
 electron-to-chromium@^1.4.147:
   version "1.4.156"
   resolved 
"https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.156.tgz#fc398e1bfbe586135351ebfaf198473a82923af5";
@@ -6278,10 +6492,10 @@ flux@^4.0.1:
     fbemitter "^3.0.0"
     fbjs "^3.0.1"
 
-focus-lock@^0.11.2:
-  version "0.11.2"
-  resolved 
"https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.2.tgz#aeef3caf1cea757797ac8afdebaec8fd9ab243ed";
-  integrity 
sha512-pZ2bO++NWLHhiKkgP1bEXHhR1/OjVcSvlCJ98aNJDFeb7H5OOQaO+SKOZle6041O9rv2tmbrO4JzClAvDUHf0g==
+focus-lock@^0.11.6:
+  version "0.11.6"
+  resolved 
"https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.6.tgz#e8821e21d218f03e100f7dc27b733f9c4f61e683";
+  integrity 
sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==
   dependencies:
     tslib "^2.0.3"
 
@@ -7243,6 +7457,14 @@ istanbul-reports@^3.1.3:
     html-escaper "^2.0.0"
     istanbul-lib-report "^3.0.0"
 
+jest-canvas-mock@^2.5.1:
+  version "2.5.1"
+  resolved 
"https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.5.1.tgz#81509af658ef485e9a1bf39c64e06761517bdbcb";
+  integrity 
sha512-IVnRiz+v4EYn3ydM/pBo8GW/J+nU/Hg5gHBQQOUQhdRyNfvHnabB8ReqARLO0p+kvQghqr4V0tA92CF3JcUSRg==
+  dependencies:
+    cssfontparser "^1.2.1"
+    moo-color "^1.0.2"
+
 jest-changed-files@^27.5.1:
   version "27.5.1"
   resolved 
"https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5";
@@ -8767,6 +8989,13 @@ moment-timezone@^0.5.43:
   resolved 
"https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108";
   integrity 
sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
 
+moo-color@^1.0.2:
+  version "1.0.3"
+  resolved 
"https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.3.tgz#d56435f8359c8284d83ac58016df7427febece74";
+  integrity 
sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==
+  dependencies:
+    color-name "^1.1.4"
+
 mri@^1.1.0:
   version "1.2.0"
   resolved 
"https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b";
@@ -9834,12 +10063,12 @@ [email protected]:
   integrity 
sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
 
 react-focus-lock@^2.9.1:
-  version "2.9.1"
-  resolved 
"https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.1.tgz#094cfc19b4f334122c73bb0bff65d77a0c92dd16";
-  integrity 
sha512-pSWOQrUmiKLkffPO6BpMXN7SNKXMsuOakl652IBuALAu1esk+IcpJyM+ALcYzPTTFz1rD0R54aB9A4HuP5t1Wg==
+  version "2.9.4"
+  resolved 
"https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.4.tgz#4753f6dcd167c39050c9d84f9c63c71b3ff8462e";
+  integrity 
sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg==
   dependencies:
     "@babel/runtime" "^7.0.0"
-    focus-lock "^0.11.2"
+    focus-lock "^0.11.6"
     prop-types "^15.6.2"
     react-clientside-effect "^1.2.6"
     use-callback-ref "^1.3.0"
@@ -9919,9 +10148,9 @@ react-remove-scroll-bar@^2.3.3:
     tslib "^2.0.0"
 
 react-remove-scroll@^2.5.4:
-  version "2.5.4"
-  resolved 
"https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz#afe6491acabde26f628f844b67647645488d2ea0";
-  integrity 
sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==
+  version "2.5.5"
+  resolved 
"https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77";
+  integrity 
sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==
   dependencies:
     react-remove-scroll-bar "^2.3.3"
     react-style-singleton "^2.2.1"
@@ -11266,7 +11495,12 @@ tsconfig-paths@^3.14.1, tsconfig-paths@^3.14.2:
     minimist "^1.2.6"
     strip-bom "^3.0.0"
 
-tslib@^1.0.0, tslib@^1.8.1:
[email protected]:
+  version "2.3.0"
+  resolved 
"https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e";
+  integrity 
sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
+
+tslib@^1.8.1:
   version "1.14.1"
   resolved 
"https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00";
   integrity 
sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@@ -12005,6 +12239,13 @@ yocto-queue@^0.1.0:
   resolved 
"https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b";
   integrity 
sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
[email protected]:
+  version "5.4.3"
+  resolved 
"https://registry.yarnpkg.com/zrender/-/zrender-5.4.3.tgz#41ffaf835f3a3210224abd9d6964b48ff01e79f5";
+  integrity 
sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ==
+  dependencies:
+    tslib "2.3.0"
+
 zustand@^4.1.1:
   version "4.1.5"
   resolved 
"https://registry.yarnpkg.com/zustand/-/zustand-4.1.5.tgz#7402b511f5b23ccb0f9ba6d20ae01ec817e16eb6";
diff --git a/tests/api_connexion/endpoints/test_dag_run_endpoint.py 
b/tests/api_connexion/endpoints/test_dag_run_endpoint.py
index 7510b41e0a..434511b9e9 100644
--- a/tests/api_connexion/endpoints/test_dag_run_endpoint.py
+++ b/tests/api_connexion/endpoints/test_dag_run_endpoint.py
@@ -50,6 +50,7 @@ def configured_app(minimal_app_for_api):
         permissions=[
             (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG),
             (permissions.ACTION_CAN_READ, permissions.RESOURCE_DATASET),
+            (permissions.ACTION_CAN_READ, 
permissions.RESOURCE_CLUSTER_ACTIVITY),
             (permissions.ACTION_CAN_EDIT, permissions.RESOURCE_DAG),
             (permissions.ACTION_CAN_CREATE, permissions.RESOURCE_DAG_RUN),
             (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_RUN),
diff --git a/tests/www/test_security.py b/tests/www/test_security.py
index 31e6ca3b46..48e02a3cbb 100644
--- a/tests/www/test_security.py
+++ b/tests/www/test_security.py
@@ -388,6 +388,7 @@ def test_get_user_roles_for_anonymous_user(app, 
security_manager):
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_CODE),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_RUN),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DATASET),
+        (permissions.ACTION_CAN_READ, permissions.RESOURCE_CLUSTER_ACTIVITY),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_IMPORT_ERROR),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_WARNING),
         (permissions.ACTION_CAN_READ, permissions.RESOURCE_JOB),
@@ -406,6 +407,7 @@ def test_get_user_roles_for_anonymous_user(app, 
security_manager):
         (permissions.ACTION_CAN_ACCESS_MENU, 
permissions.RESOURCE_DAG_DEPENDENCIES),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DAG_RUN),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DATASET),
+        (permissions.ACTION_CAN_ACCESS_MENU, 
permissions.RESOURCE_CLUSTER_ACTIVITY),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_JOB),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_AUDIT_LOG),
         (permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_PLUGIN),
@@ -463,7 +465,6 @@ def test_get_accessible_dag_ids(app, security_manager, 
session):
                 (permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG),
             ],
         ) as user:
-
             dag_model = DagModel(dag_id=dag_id, fileloc="/tmp/dag_.py", 
schedule_interval="2 2 * * *")
             session.add(dag_model)
             session.commit()
@@ -491,7 +492,6 @@ def 
test_dont_get_inaccessible_dag_ids_for_dag_resource_permission(app, security
                 (permissions.ACTION_CAN_EDIT, permissions.RESOURCE_DAG),
             ],
         ) as user:
-
             dag_model = DagModel(dag_id=dag_id, fileloc="/tmp/dag_.py", 
schedule_interval="2 2 * * *")
             session.add(dag_model)
             session.commit()
@@ -711,7 +711,6 @@ def 
test_correct_roles_have_perms_to_read_config(security_manager):
 
 
 def test_create_dag_specific_permissions(session, security_manager, 
monkeypatch, sample_dags):
-
     access_control = {"Public": {permissions.ACTION_CAN_READ}}
 
     collect_dags_from_db_mock = mock.Mock()
diff --git a/tests/www/views/test_views_cluster_activity.py 
b/tests/www/views/test_views_cluster_activity.py
new file mode 100644
index 0000000000..13105eb28a
--- /dev/null
+++ b/tests/www/views/test_views_cluster_activity.py
@@ -0,0 +1,143 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import pendulum
+import pytest
+
+from airflow.models import DagBag
+from airflow.operators.empty import EmptyOperator
+from airflow.utils.state import DagRunState, TaskInstanceState
+from airflow.utils.types import DagRunType
+from tests.test_utils.db import clear_db_runs
+
+
[email protected](autouse=True, scope="module")
+def examples_dag_bag():
+    # Speed up: We don't want example dags for this module
+
+    return DagBag(include_examples=False, read_dags_from_db=True)
+
+
[email protected](autouse=True)
+def clean():
+    clear_db_runs()
+    yield
+    clear_db_runs()
+
+
+# freeze time fixture so that it is applied before `make_dag_runs` is!
[email protected]
+def freeze_time_for_dagruns(time_machine):
+    time_machine.move_to("2023-05-02T00:00:00+00:00", tick=False)
+    yield
+
+
[email protected]
+def make_dag_runs(dag_maker, session):
+    with dag_maker(
+        dag_id="test_dag_id",
+        serialized=True,
+        session=session,
+        start_date=pendulum.DateTime(2023, 2, 1, 0, 0, 0, tzinfo=pendulum.UTC),
+    ):
+        EmptyOperator(task_id="task_1") >> EmptyOperator(task_id="task_2")
+
+    date = dag_maker.dag.start_date
+
+    run1 = dag_maker.create_dagrun(
+        run_id="run_1",
+        state=DagRunState.SUCCESS,
+        run_type=DagRunType.SCHEDULED,
+        execution_date=date,
+        start_date=date,
+    )
+
+    run2 = dag_maker.create_dagrun(
+        run_id="run_2",
+        state=DagRunState.FAILED,
+        run_type=DagRunType.DATASET_TRIGGERED,
+        execution_date=dag_maker.dag.next_dagrun_info(date).logical_date,
+        start_date=dag_maker.dag.next_dagrun_info(date).logical_date,
+    )
+
+    for ti in run1.task_instances:
+        ti.state = TaskInstanceState.SUCCESS
+
+    for ti in run2.task_instances:
+        ti.state = TaskInstanceState.FAILED
+
+    session.flush()
+
+
[email protected]("freeze_time_for_dagruns", "make_dag_runs")
+def test_historical_metrics_data(admin_client, session):
+    resp = admin_client.get(
+        
"/object/historical_metrics_data?start_date=2023-01-01T00:00&end_date=2023-05-02T00:00",
+        follow_redirects=True,
+    )
+    assert resp.status_code == 200
+    assert resp.json == {
+        "dag_run_states": {"failed": 1, "queued": 0, "running": 0, "success": 
1},
+        "dag_run_types": {"backfill": 0, "dataset_triggered": 1, "manual": 0, 
"scheduled": 1},
+        "task_instance_states": {
+            "deferred": 0,
+            "failed": 2,
+            "no_status": 0,
+            "queued": 0,
+            "removed": 0,
+            "restarting": 0,
+            "running": 0,
+            "scheduled": 0,
+            "shutdown": 0,
+            "skipped": 0,
+            "success": 2,
+            "up_for_reschedule": 0,
+            "up_for_retry": 0,
+            "upstream_failed": 0,
+        },
+    }
+
+
[email protected]("freeze_time_for_dagruns", "make_dag_runs")
+def test_historical_metrics_data_date_filters(admin_client, session):
+    resp = admin_client.get(
+        
"/object/historical_metrics_data?start_date=2023-02-02T00:00&end_date=2023-05-02T00:00",
+        follow_redirects=True,
+    )
+    assert resp.status_code == 200
+    assert resp.json == {
+        "dag_run_states": {"failed": 1, "queued": 0, "running": 0, "success": 
0},
+        "dag_run_types": {"backfill": 0, "dataset_triggered": 1, "manual": 0, 
"scheduled": 0},
+        "task_instance_states": {
+            "deferred": 0,
+            "failed": 2,
+            "no_status": 0,
+            "queued": 0,
+            "removed": 0,
+            "restarting": 0,
+            "running": 0,
+            "scheduled": 0,
+            "shutdown": 0,
+            "skipped": 0,
+            "success": 0,
+            "up_for_reschedule": 0,
+            "up_for_retry": 0,
+            "upstream_failed": 0,
+        },
+    }

Reply via email to