Repository: apache/airflow
File: airflow-core/src/airflow/ui/src/components/PoolBar.tsx (TypeScript)

Code before:
 * specific language governing permissions and limitations
 * under the License.
 */
import { Box, Flex, Text, VStack, Link } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink } from "react-router-dom";

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";

export const PoolBar = ({
  pool,
  poolsWithSlotType,
  totalSlots,
}: {
  readonly pool: PoolResponse | Slots;
  readonly poolsWithSlotType?: Slots;
  readonly totalSlots: number;
}) => {
  const { t: translate } = useTranslation("common");
  const activeSlots = ["running", "queued", "open"];

  if ("include_deferred" in pool && pool.include_deferred) {
    activeSlots.push("deferred");
  }

  return (
    <Tooltip
      content={
        <VStack align="start" gap={1} p={1}>
          {slotConfigs.map(({ key }) => {
            const slotValue = pool[key];
            const slotType = key.replace("_slots", "");

            if (slotValue === 0) {
              return undefined;
            }

            return (
              <Flex align="center" gap={2} key={key}>
                <StateIcon size={12} state={slotType as TaskInstanceState} />
                <Text fontSize="xs">
                  {translate(`common:state.${slotType}`)}: {slotValue}
                </Text>
              </Flex>
            );
          })}
          {"include_deferred" in pool && (

Review comment (suggestion):
The computation for PoolBar summary won't be accurate I think. Because `influce_deferred` is not in `pool` and it won't be counted for pools with 'include_deferred=True'

Code after:
 * specific language governing permissions and limitations
 * under the License.
 */
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, 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";

export const PoolBar = ({
  pool,
  poolsWithSlotType,
  totalSlots,
}: {
  readonly pool: PoolResponse | Slots;
  readonly poolsWithSlotType?: Slots;
  readonly totalSlots: number;
}) => {
  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 (
    <VStack align="stretch" gap={1} w="100%">
      <Flex bg="bg.muted" borderRadius="md" h="20px" overflow="hidden" w="100%">