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 b6bf6a83b51 UI: Fix misleading Calendar Total Runs coloring behavior 
(#67595)
b6bf6a83b51 is described below

commit b6bf6a83b519881d7805e269cac0895409132232
Author: YeoooonShin <[email protected]>
AuthorDate: Wed Jun 17 23:46:26 2026 +0900

    UI: Fix misleading Calendar Total Runs coloring behavior (#67595)
    
    * fix: add missing queued state color to CalendarToolTip (May 15)
    
    * fix: calendar cell coloring to prioritize severity in Total Runs view
    
    * refactor: clarify calendar cell color keys and extract priority 
resolution logic
    
    * test: add missing test cases for calendar scale total runs
    
    * fix: expand calendar legend to clarify running and failed states
---
 .../ui/src/pages/Dag/Calendar/CalendarCell.tsx     |  10 +-
 .../ui/src/pages/Dag/Calendar/CalendarLegend.tsx   | 109 ++++++++++----
 .../ui/src/pages/Dag/Calendar/CalendarTooltip.tsx  |   1 +
 .../src/pages/Dag/Calendar/calendarUtils.test.ts   | 134 ++++++++++++++++-
 .../ui/src/pages/Dag/Calendar/calendarUtils.ts     | 164 ++++++++++++++-------
 .../src/airflow/ui/src/pages/Dag/Calendar/types.ts |   4 +-
 6 files changed, 326 insertions(+), 96 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
index ea91e34309b..6660194329e 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
@@ -28,8 +28,8 @@ type Props = {
     | Record<string, string>
     | string
     | {
-        actual: string | { _dark: string; _light: string };
-        planned: string | { _dark: string; _light: string };
+        primary: string | { _dark: string; _light: string };
+        secondary: string | { _dark: string; _light: string };
       };
   readonly cellData: CalendarCellData | undefined;
   readonly index?: number;
@@ -64,7 +64,7 @@ export const CalendarCell = ({
     : [];
 
   const isMixedState =
-    typeof backgroundColor === "object" && "planned" in backgroundColor && 
"actual" in backgroundColor;
+    typeof backgroundColor === "object" && "secondary" in backgroundColor && 
"primary" in backgroundColor;
 
   const cellBox = isMixedState ? (
     <Box
@@ -82,14 +82,14 @@ export const CalendarCell = ({
       width="14px"
     >
       <Box
-        bg={backgroundColor.planned}
+        bg={backgroundColor.secondary}
         clipPath="polygon(0 100%, 100% 100%, 0 0)"
         height="100%"
         position="absolute"
         width="100%"
       />
       <Box
-        bg={backgroundColor.actual}
+        bg={backgroundColor.primary}
         clipPath="polygon(100% 0, 100% 100%, 0 0)"
         height="100%"
         position="absolute"
diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarLegend.tsx 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarLegend.tsx
index 480c1a8e077..7f12162bb5b 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarLegend.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarLegend.tsx
@@ -30,8 +30,48 @@ type Props = {
   readonly viewMode: CalendarColorMode;
 };
 
+type LegendColorType =
+  | Record<string, string>
+  | string
+  | { primary: Record<string, string> | string; secondary: Record<string, 
string> | string };
+
+const LegendIcon = ({ color, cursor }: { readonly color: LegendColorType; 
readonly cursor?: string }) => {
+  const isMixedState = typeof color === "object" && "primary" in color && 
"secondary" in color;
+
+  if (isMixedState) {
+    return (
+      <Box
+        borderRadius="2px"
+        boxShadow="sm"
+        cursor={cursor}
+        height="14px"
+        overflow="hidden"
+        position="relative"
+        width="14px"
+      >
+        <Box
+          bg={color.secondary}
+          clipPath="polygon(0 100%, 100% 100%, 0 0)"
+          height="100%"
+          position="absolute"
+          width="100%"
+        />
+        <Box
+          bg={color.primary}
+          clipPath="polygon(100% 0, 100% 100%, 0 0)"
+          height="100%"
+          position="absolute"
+          width="100%"
+        />
+      </Box>
+    );
+  }
+
+  return <Box bg={color} borderRadius="2px" boxShadow="sm" cursor={cursor} 
height="14px" width="14px" />;
+};
+
 export const CalendarLegend = ({ scale, vertical = false, viewMode }: Props) 
=> {
-  const { t: translate } = useTranslation("dag");
+  const { t: translate } = useTranslation(["dag", "common"]);
 
   const legendTitle =
     viewMode === "failed" ? translate("overview.buttons.failedRun_other") : 
translate("calendar.totalRuns");
@@ -54,7 +94,9 @@ export const CalendarLegend = ({ scale, vertical = false, 
viewMode }: Props) =>
             <VStack gap={0.5}>
               {[...scale.legendItems].reverse().map(({ color, label }) => (
                 <Tooltip content={`${label} ${viewMode === "failed" ? "failed" 
: "runs"}`} key={label}>
-                  <Box bg={color} borderRadius="2px" cursor="pointer" 
height="14px" width="14px" />
+                  <Box>
+                    <LegendIcon color={color} cursor="pointer" />
+                  </Box>
                 </Tooltip>
               ))}
             </VStack>
@@ -70,7 +112,9 @@ export const CalendarLegend = ({ scale, vertical = false, 
viewMode }: Props) =>
             <HStack gap={0.5}>
               {scale.legendItems.map(({ color, label }) => (
                 <Tooltip content={`${label} ${viewMode === "failed" ? "failed" 
: "runs"}`} key={label}>
-                  <Box bg={color} borderRadius="2px" cursor="pointer" 
height="14px" width="14px" />
+                  <Box>
+                    <LegendIcon color={color} cursor="pointer" />
+                  </Box>
                 </Tooltip>
               ))}
             </HStack>
@@ -83,42 +127,49 @@ export const CalendarLegend = ({ scale, vertical = false, 
viewMode }: Props) =>
 
       <Box>
         <HStack gap={4} justify="center" wrap="wrap">
+          {viewMode === "total" && (
+            <>
+              <HStack gap={2}>
+                <LegendIcon color={{ _dark: "green.700", _light: "green.400" 
}} />
+                <Text color="fg.muted" fontSize="xs">
+                  {translate("common:states.success")}
+                </Text>
+              </HStack>
+              <HStack gap={2}>
+                <LegendIcon color={{ _dark: "cyan.700", _light: "cyan.400" }} 
/>
+                <Text color="fg.muted" fontSize="xs">
+                  {translate("common:states.running")}
+                </Text>
+              </HStack>
+            </>
+          )}
+
+          <HStack gap={2}>
+            <LegendIcon color={{ _dark: "red.700", _light: "red.400" }} />
+            <Text color="fg.muted" fontSize="xs">
+              {translate("common:states.failed")}
+            </Text>
+          </HStack>
+
           <HStack gap={2}>
             <Box bg={PLANNED_COLOR} borderRadius="2px" boxShadow="sm" 
height="14px" width="14px" />
             <Text color="fg.muted" fontSize="xs">
               {translate("common:states.planned")}
             </Text>
           </HStack>
+
           <HStack gap={2}>
-            <Box
-              borderRadius="2px"
-              boxShadow="sm"
-              height="14px"
-              overflow="hidden"
-              position="relative"
-              width="14px"
-            >
-              <Box
-                bg={PLANNED_COLOR}
-                clipPath="polygon(0 100%, 100% 100%, 0 0)"
-                height="100%"
-                position="absolute"
-                width="100%"
-              />
-              <Box
-                bg={
+            <LegendIcon
+              color={{
+                primary:
                   viewMode === "failed"
                     ? { _dark: "red.700", _light: "red.400" }
-                    : { _dark: "green.700", _light: "green.400" }
-                }
-                clipPath="polygon(100% 0, 100% 100%, 0 0)"
-                height="100%"
-                position="absolute"
-                width="100%"
-              />
-            </Box>
+                    : { _dark: "green.700", _light: "green.400" },
+                secondary: PLANNED_COLOR,
+              }}
+            />
             <Text color="fg.muted" fontSize="xs">
-              {translate("calendar.legend.mixed")}
+              {translate("dag:calendar.legend.mixed")}
             </Text>
           </HStack>
         </HStack>
diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
index f5a3a50ecf9..90ae1d8ab36 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
@@ -32,6 +32,7 @@ type Props = {
 const stateColorMap = {
   failed: "failed.solid",
   planned: "stone.solid",
+  queued: "queued.solid",
   running: "running.solid",
   success: "success.solid",
 };
diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.test.ts 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.test.ts
index 4cb86deec29..c35225cebdc 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.test.ts
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.test.ts
@@ -27,6 +27,7 @@ const EMPTY_COLOR = { _dark: "gray.700", _light: "gray.100" };
 const PLANNED_COLOR = { _dark: "stone.600", _light: "stone.500" };
 const DEFAULT_TOTAL_COLOR = { _dark: "green.700", _light: "green.400" };
 const DEFAULT_FAILED_COLOR = { _dark: "red.700", _light: "red.400" };
+const DEFAULT_RUNNING_COLOR = { _dark: "cyan.700", _light: "cyan.400" };
 
 const EMPTY_COUNTS: RunCounts = {
   failed: 0,
@@ -158,8 +159,8 @@ describe("createCalendarScale", () => {
     });
 
     expect(scale.getColor({ ...EMPTY_COUNTS, planned: 1, success: 1, total: 2 
})).toEqual({
-      actual: DEFAULT_TOTAL_COLOR,
-      planned: PLANNED_COLOR,
+      primary: DEFAULT_TOTAL_COLOR,
+      secondary: PLANNED_COLOR,
     });
   });
 
@@ -171,8 +172,57 @@ describe("createCalendarScale", () => {
     });
 
     expect(scale.getColor({ ...EMPTY_COUNTS, queued: 1, success: 1, total: 2 
})).toEqual({
-      actual: DEFAULT_TOTAL_COLOR,
-      planned: PLANNED_COLOR,
+      primary: DEFAULT_TOTAL_COLOR,
+      secondary: PLANNED_COLOR,
+    });
+  });
+
+  it("returns the failed color for a failed-only cell in total mode", () => {
+    const scale = createCalendarScale([run("failed", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, total: 1 
})).toEqual(DEFAULT_FAILED_COLOR);
+  });
+
+  it("returns a mixed red and green color for failed and success runs in total 
mode", () => {
+    const scale = createCalendarScale([run("failed", 1), run("success", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, success: 1, total: 2 
})).toEqual({
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: DEFAULT_TOTAL_COLOR,
+    });
+  });
+
+  it("returns a mixed cyan and green color for running and success runs in 
total mode", () => {
+    const scale = createCalendarScale([run("running", 1), run("success", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, running: 1, success: 1, total: 2 
})).toEqual({
+      primary: DEFAULT_RUNNING_COLOR,
+      secondary: DEFAULT_TOTAL_COLOR,
+    });
+  });
+
+  it("returns a mixed cyan and red color for running and failed runs in total 
mode", () => {
+    const scale = createCalendarScale([run("running", 1), run("failed", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, running: 1, total: 2 
})).toEqual({
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: DEFAULT_RUNNING_COLOR,
     });
   });
 
@@ -195,8 +245,8 @@ describe("createCalendarScale", () => {
     });
 
     expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, planned: 1, total: 2 
})).toEqual({
-      actual: DEFAULT_FAILED_COLOR,
-      planned: PLANNED_COLOR,
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: PLANNED_COLOR,
     });
   });
 
@@ -218,8 +268,76 @@ describe("createCalendarScale", () => {
     });
 
     expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, queued: 1, total: 2 
})).toEqual({
-      actual: DEFAULT_FAILED_COLOR,
-      planned: PLANNED_COLOR,
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: PLANNED_COLOR,
+    });
+  });
+
+  it("returns the correct gradient color when runs span across different 
dates", () => {
+    const scale = createCalendarScale(
+      [run("failed", 1, "2026-04-08T10:00:00Z"), run("failed", 5, 
"2026-04-09T10:00:00Z")],
+      {
+        granularity: "hourly",
+        timezone: "UTC",
+        viewMode: "total",
+      },
+    );
+
+    const lowIntensityColor = { _dark: "red.900", _light: "red.200" };
+    const highIntensityColor = { _dark: "red.300", _light: "red.800" };
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, total: 1 
})).toEqual(lowIntensityColor);
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 5, total: 5 
})).toEqual(highIntensityColor);
+  });
+
+  it("prioritizes failed over running over success when multiple actual states 
coexist with pending", () => {
+    const scale = createCalendarScale([run("planned", 1), run("failed", 1), 
run("success", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, planned: 1, success: 
1, total: 3 })).toEqual({
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: PLANNED_COLOR,
     });
   });
+
+  it("returns an empty scale when no data is provided", () => {
+    const scale = createCalendarScale([], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.type).toBe("empty");
+    expect(scale.getColor(EMPTY_COUNTS)).toEqual(EMPTY_COLOR);
+    expect(scale.legendItems).toEqual([{ color: EMPTY_COLOR, label: "0" }]);
+  });
+
+  it("prioritizes running and failed colors when failed, running, and success 
coexist without pending states", () => {
+    const scale = createCalendarScale([run("failed", 1), run("running", 1), 
run("success", 1)], {
+      granularity: "hourly",
+      timezone: "UTC",
+      viewMode: "total",
+    });
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, running: 1, success: 
1, total: 3 })).toEqual({
+      primary: DEFAULT_FAILED_COLOR,
+      secondary: DEFAULT_RUNNING_COLOR,
+    });
+  });
+
+  it("returns the correct gradient color for failed mode when failed runs span 
across different dates", () => {
+    const scale = createCalendarScale(
+      [run("failed", 1, "2026-04-08T10:00:00Z"), run("failed", 10, 
"2026-04-09T10:00:00Z")],
+      { granularity: "hourly", timezone: "UTC", viewMode: "failed" },
+    );
+
+    const lowIntensityFailedColor = { _dark: "red.900", _light: "red.200" };
+    const highIntensityFailedColor = { _dark: "red.300", _light: "red.800" };
+
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 1, total: 1 
})).toEqual(lowIntensityFailedColor);
+    expect(scale.getColor({ ...EMPTY_COUNTS, failed: 10, total: 10 
})).toEqual(highIntensityFailedColor);
+  });
 });
diff --git 
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.ts 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.ts
index 3f57eb35030..527ebc6389c 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.ts
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/calendarUtils.ts
@@ -40,6 +40,7 @@ dayjs.extend(tz);
 // Calendar color constants
 export const PLANNED_COLOR = { _dark: "stone.600", _light: "stone.500" };
 const EMPTY_COLOR = { _dark: "gray.700", _light: "gray.100" };
+const RUNNING_COLOR = { _dark: "cyan.700", _light: "cyan.400" };
 
 const TOTAL_COLOR_INTENSITIES = [
   EMPTY_COLOR, // 0
@@ -244,6 +245,75 @@ type ScaleOptions = {
   viewMode: CalendarColorMode;
 };
 
+type ColorValue = string | { _dark: string; _light: string };
+
+type ResolveColorParams = {
+  failedColor: ColorValue;
+  failedCount: number;
+  hasPending: boolean;
+  runningCount: number;
+  successColor: ColorValue;
+  successCount: number;
+};
+
+const resolveCellColor = ({
+  failedColor,
+  failedCount,
+  hasPending,
+  runningCount,
+  successColor,
+  successCount,
+}: ResolveColorParams): ColorValue | { primary: ColorValue; secondary: 
ColorValue } => {
+  const hasActual = failedCount > 0 || runningCount > 0 || successCount > 0;
+
+  if (hasPending && hasActual) {
+    let primaryColor: ColorValue = EMPTY_COLOR;
+
+    if (failedCount > 0) {
+      primaryColor = failedColor;
+    } else if (runningCount > 0) {
+      primaryColor = RUNNING_COLOR;
+    } else if (successCount > 0) {
+      primaryColor = successColor;
+    }
+
+    return {
+      primary: primaryColor,
+      secondary: PLANNED_COLOR,
+    };
+  }
+
+  if (hasPending && !hasActual) {
+    return PLANNED_COLOR;
+  }
+
+  if (hasActual) {
+    if (failedCount > 0 && runningCount > 0) {
+      return { primary: failedColor, secondary: RUNNING_COLOR };
+    }
+
+    if (failedCount > 0 && successCount > 0) {
+      return { primary: failedColor, secondary: successColor };
+    }
+
+    if (runningCount > 0 && successCount > 0) {
+      return { primary: RUNNING_COLOR, secondary: successColor };
+    }
+
+    if (failedCount > 0) {
+      return failedColor;
+    }
+    if (runningCount > 0) {
+      return RUNNING_COLOR;
+    }
+    if (successCount > 0) {
+      return successColor;
+    }
+  }
+
+  return EMPTY_COLOR;
+};
+
 export const createCalendarScale = (
   data: Array<CalendarTimeRangeResponse>,
   options: ScaleOptions,
@@ -267,22 +337,23 @@ export const createCalendarScale = (
 
     return {
       getColor: (counts: RunCounts) => {
-        const actualCount = getActualRunCount(counts, viewMode);
-        const hasPending = getPendingRunCount(counts) > 0;
-        const hasActual = actualCount > 0;
-
-        if (hasPending && hasActual) {
-          return {
-            actual: singleColor,
-            planned: PLANNED_COLOR,
-          };
-        }
+        const failedCount = counts.failed;
+        const runningCount = viewMode === "total" ? counts.running : 0;
+        const successCount = viewMode === "total" ? counts.success : 0;
 
-        if (hasPending && !hasActual) {
-          return PLANNED_COLOR;
-        }
+        const hasPending = getPendingRunCount(counts) > 0;
 
-        return actualCount === 0 ? EMPTY_COLOR : singleColor;
+        const failedColor = FAILURE_COLOR_INTENSITIES[2] ?? EMPTY_COLOR;
+        const successColor = TOTAL_COLOR_INTENSITIES[2] ?? EMPTY_COLOR;
+
+        return resolveCellColor({
+          failedColor,
+          failedCount,
+          hasPending,
+          runningCount,
+          successColor,
+          successCount,
+        });
       },
       legendItems: [
         { color: EMPTY_COLOR, label: "0" },
@@ -312,54 +383,43 @@ export const createCalendarScale = (
     | string
     | { _dark: string; _light: string }
     | {
-        actual: string | { _dark: string; _light: string };
-        planned: string | { _dark: string; _light: string };
+        primary: string | { _dark: string; _light: string };
+        secondary: string | { _dark: string; _light: string };
       } => {
-    const actualCount = getActualRunCount(counts, viewMode);
-    const hasPending = getPendingRunCount(counts) > 0;
-    const hasActual = actualCount > 0;
+    const failedCount = counts.failed;
+    const runningCount = viewMode === "total" ? counts.running : 0;
+    const successCount = viewMode === "total" ? counts.success : 0;
 
-    if (hasPending && hasActual) {
-      let actualColor = colorScheme[0] ?? EMPTY_COLOR;
+    const hasPending = getPendingRunCount(counts) > 0;
 
+    const getIntensityColor = (count: number, scheme: Array<ColorValue>) => {
+      if (count === 0) {
+        return scheme[0] ?? EMPTY_COLOR;
+      }
       for (let index = uniqueThresholds.length - 1; index >= 1; index -= 1) {
         const threshold = uniqueThresholds[index];
 
-        if (threshold !== undefined && actualCount >= threshold) {
-          actualColor = colorScheme[Math.min(index, colorScheme.length - 1)] 
?? EMPTY_COLOR;
-          break;
+        if (threshold !== undefined && count >= threshold) {
+          return scheme[Math.min(index, scheme.length - 1)] ?? EMPTY_COLOR;
         }
       }
 
-      if (actualCount > 0 && actualColor === colorScheme[0]) {
-        actualColor = colorScheme[1] ?? EMPTY_COLOR;
-      }
-
-      return {
-        actual: actualColor,
-        planned: PLANNED_COLOR,
-      };
-    }
-
-    if (hasPending && !hasActual) {
-      return PLANNED_COLOR;
-    }
-
-    const targetCount = actualCount;
-
-    if (targetCount === 0) {
-      return colorScheme[0] ?? EMPTY_COLOR;
-    }
-
-    for (let index = uniqueThresholds.length - 1; index >= 1; index -= 1) {
-      const threshold = uniqueThresholds[index];
-
-      if (threshold !== undefined && targetCount >= threshold) {
-        return colorScheme[Math.min(index, colorScheme.length - 1)] ?? 
EMPTY_COLOR;
-      }
-    }
+      return scheme[1] ?? EMPTY_COLOR;
+    };
 
-    return colorScheme[1] ?? EMPTY_COLOR;
+    const failedColor =
+      failedCount > 0 ? getIntensityColor(failedCount, 
FAILURE_COLOR_INTENSITIES) : EMPTY_COLOR;
+    const successColor =
+      successCount > 0 ? getIntensityColor(successCount, 
TOTAL_COLOR_INTENSITIES) : EMPTY_COLOR;
+
+    return resolveCellColor({
+      failedColor,
+      failedCount,
+      hasPending,
+      runningCount,
+      successColor,
+      successCount,
+    });
   };
 
   const legendItems: Array<LegendItem> = [];
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/types.ts 
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/types.ts
index 8ef78a66af4..7e93c637734 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/types.ts
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/types.ts
@@ -69,8 +69,8 @@ export type CalendarScale = {
     | string
     | { _dark: string; _light: string }
     | {
-        actual: string | { _dark: string; _light: string };
-        planned: string | { _dark: string; _light: string };
+        primary: string | { _dark: string; _light: string };
+        secondary: string | { _dark: string; _light: string };
       };
   readonly legendItems: Array<LegendItem>;
   readonly type: CalendarScaleType;

Reply via email to