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

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 620aa0c432429f3f67b37d33aa058d96f138e223
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jan 14 14:45:54 2026 -0500

    [v3-1-test] UI: Update PoolBar to separate Scheduled and Deferred slots 
(#59270) (#60538)
    
    * UI: Update PoolBar to separate Scheduled and Deferred slots
    
    * UI: Use standard tooltips and cleanup i18n keys
    (cherry picked from commit 41f3dfec4937f9096c482fbc5d2a463d15050dd6)
    
    Co-authored-by: Anshu Singh <[email protected]>
---
 .../airflow/ui/public/i18n/locales/en/common.json  |  10 +-
 .../src/airflow/ui/src/components/PoolBar.tsx      | 126 +++++++++++++--------
 .../pages/Dashboard/PoolSummary/PoolSummary.tsx    |   4 +-
 .../src/airflow/ui/src/pages/Pools/PoolBarCard.tsx |   5 +-
 4 files changed, 84 insertions(+), 61 deletions(-)

diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json 
b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
index 3b9b1c71c33..0a59f203473 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
@@ -145,15 +145,6 @@
     "placeholder": "Add a note...",
     "taskInstance": "Task Instance Note"
   },
-  "pools": {
-    "deferred": "Deferred",
-    "open": "Open",
-    "pools_one": "pool",
-    "pools_other": "pools",
-    "queued": "Queued",
-    "running": "Running",
-    "scheduled": "Scheduled"
-  },
   "reset": "Reset",
   "runId": "Run ID",
   "runTypes": {
@@ -192,6 +183,7 @@
     "failed": "Failed",
     "no_status": "No Status",
     "none": "No Status",
+    "open": "Open",
     "planned": "Planned",
     "queued": "Queued",
     "removed": "Removed",
diff --git a/airflow-core/src/airflow/ui/src/components/PoolBar.tsx 
b/airflow-core/src/airflow/ui/src/components/PoolBar.tsx
index d7b68b6b560..e19cce8ecdd 100644
--- a/airflow-core/src/airflow/ui/src/components/PoolBar.tsx
+++ b/airflow-core/src/airflow/ui/src/components/PoolBar.tsx
@@ -16,11 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Flex, Link, Box } from "@chakra-ui/react";
+import { Box, Flex, Text, VStack, Link, HStack } from "@chakra-ui/react";
 import { useTranslation } from "react-i18next";
 import { Link as RouterLink } from "react-router-dom";
 
-import type { PoolResponse } from "openapi/requests/types.gen";
+import type { PoolResponse, TaskInstanceState } from 
"openapi/requests/types.gen";
+import { StateIcon } from "src/components/StateIcon";
 import { Tooltip } from "src/components/ui";
 import { SearchParamsKeys } from "src/constants/searchParams";
 import { type Slots, slotConfigs } from "src/utils/slots";
@@ -36,52 +37,87 @@ export const PoolBar = ({
 }) => {
   const { t: translate } = useTranslation("common");
 
+  const isDashboard = Boolean(poolsWithSlotType);
+  const includeDeferredInBar = "include_deferred" in pool && 
pool.include_deferred;
+  const barSlots = ["running", "queued", "open"];
+
+  if (isDashboard || includeDeferredInBar) {
+    barSlots.push("deferred");
+  }
+  const infoSlots = ["scheduled"];
+
+  if (!isDashboard && !includeDeferredInBar) {
+    infoSlots.push("deferred");
+  }
+
+  const preparedSlots = slotConfigs.map((config) => {
+    const slotType = config.key.replace("_slots", "") as TaskInstanceState;
+
+    return {
+      ...config,
+      label: translate(`common:states.${slotType}`),
+      slotType,
+      slotValue: (pool[config.key] as number | undefined) ?? 0,
+    };
+  });
+
   return (
-    <>
-      {slotConfigs.map(({ color, icon, key }) => {
-        const slotValue = pool[key];
-        const flexValue = slotValue / totalSlots || 0;
+    <VStack align="stretch" gap={1} w="100%">
+      <Flex bg="bg.muted" borderRadius="md" h="20px" overflow="hidden" 
w="100%">
+        {preparedSlots
+          .filter((slot) => barSlots.includes(slot.slotType) && slot.slotValue 
> 0)
+          .map((slot) => {
+            const flexValue = slot.slotValue / totalSlots || 0;
 
-        if (flexValue === 0) {
-          return undefined;
-        }
+            const poolContent = (
+              <Tooltip content={slot.label} key={slot.key} showArrow={true}>
+                <Flex
+                  alignItems="center"
+                  bg={`${slot.color}.solid`}
+                  color={`${slot.color}.contrast`}
+                  gap={1}
+                  h="100%"
+                  justifyContent="center"
+                  overflow="hidden"
+                  px={1}
+                  w="100%"
+                >
+                  {slot.icon}
+                  <Text fontSize="xs" fontWeight="bold" truncate>
+                    {slot.slotValue}
+                  </Text>
+                </Flex>
+              </Tooltip>
+            );
 
-        const slotType = key.replace("_slots", "");
-        const poolCount = poolsWithSlotType ? poolsWithSlotType[key] : 0;
-        const tooltipContent = `${translate(`pools.${slotType}`)}: 
${slotValue} (${poolCount} ${translate("pools.pools", { count: poolCount })})`;
-        const poolContent = (
-          <Tooltip content={tooltipContent} key={key}>
-            <Flex
-              alignItems="center"
-              bg={`${color}.solid`}
-              color={`${color}.contrast`}
-              gap={1}
-              h="100%"
-              justifyContent="center"
-              px={1}
-              textAlign="center"
-              w="100%"
-            >
-              {icon}
-              {slotValue}
-            </Flex>
-          </Tooltip>
-        );
+            return slot.color !== "success" && "name" in pool ? (
+              <Link asChild flex={flexValue} key={slot.key}>
+                <RouterLink
+                  
to={`/task_instances?${SearchParamsKeys.STATE}=${slot.color}&${SearchParamsKeys.POOL}=${pool.name}`}
+                >
+                  {poolContent}
+                </RouterLink>
+              </Link>
+            ) : (
+              <Box flex={flexValue} key={slot.key}>
+                {poolContent}
+              </Box>
+            );
+          })}
+      </Flex>
 
-        return color !== "success" && "name" in pool ? (
-          <Link asChild display="flex" flex={flexValue} key={key}>
-            <RouterLink
-              
to={`/task_instances?${SearchParamsKeys.STATE}=${color}&${SearchParamsKeys.POOL}=${pool.name}`}
-            >
-              {poolContent}
-            </RouterLink>
-          </Link>
-        ) : (
-          <Box display="flex" flex={flexValue} key={key}>
-            {poolContent}
-          </Box>
-        );
-      })}
-    </>
+      <HStack gap={4} wrap="wrap">
+        {preparedSlots
+          .filter((slot) => infoSlots.includes(slot.slotType) && 
slot.slotValue > 0)
+          .map((slot) => (
+            <HStack gap={1} key={slot.key}>
+              <StateIcon size={12} state={slot.slotType} />
+              <Text color="fg.muted" fontSize="xs" fontWeight="medium">
+                {slot.label}: {slot.slotValue}
+              </Text>
+            </HStack>
+          ))}
+      </HStack>
+    </VStack>
   );
 };
diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dashboard/PoolSummary/PoolSummary.tsx 
b/airflow-core/src/airflow/ui/src/pages/Dashboard/PoolSummary/PoolSummary.tsx
index be08ecb15c4..9fadd5bab2b 100644
--- 
a/airflow-core/src/airflow/ui/src/pages/Dashboard/PoolSummary/PoolSummary.tsx
+++ 
b/airflow-core/src/airflow/ui/src/pages/Dashboard/PoolSummary/PoolSummary.tsx
@@ -98,9 +98,7 @@ export const PoolSummary = () => {
       {isLoading ? (
         <Skeleton borderRadius="full" h={8} w="100%" />
       ) : (
-        <Flex bg="bg" borderRadius="full" display="flex" overflow="hidden" 
w="100%">
-          <PoolBar pool={aggregatePool} poolsWithSlotType={poolsWithSlotType} 
totalSlots={totalSlots} />
-        </Flex>
+        <PoolBar pool={aggregatePool} poolsWithSlotType={poolsWithSlotType} 
totalSlots={totalSlots} />
       )}
     </Box>
   );
diff --git a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx 
b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx
index d1d416e9c7e..218eb24a6b3 100644
--- a/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Pools/PoolBarCard.tsx
@@ -61,11 +61,8 @@ const PoolBarCard = ({ pool }: PoolBarCardProps) => {
           )}
         </VStack>
       </Flex>
-
       <Box margin={4}>
-        <Flex bg="bg.muted" borderRadius="md" h="20px" overflow="hidden" 
w="100%">
-          <PoolBar pool={pool} totalSlots={pool.slots} />
-        </Flex>
+        <PoolBar pool={pool} totalSlots={pool.slots} />
       </Box>
     </Box>
   );

Reply via email to