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

bbovenzi 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 b7f2206621 Show upstream/downstreams from a dataset (#25403)
b7f2206621 is described below

commit b7f2206621365bd957c61567be49fe8447c71d3a
Author: Brent Bovenzi <[email protected]>
AuthorDate: Tue Aug 2 17:07:02 2022 +0100

    Show upstream/downstreams from a dataset (#25403)
    
    * add links to upstream/downstream dags, fix typing
    
    * tooltip descriptions
    
    * Update airflow/www/static/js/datasets/Details.tsx
    
    Co-authored-by: Daniel Standish 
<[email protected]>
    
    * remove created/updated at, separate links
    
    * update copy
    
    Co-authored-by: Daniel Standish 
<[email protected]>
---
 airflow/www/alias-rest-types.js                  |   4 +-
 airflow/www/package.json                         |   1 +
 airflow/www/static/js/components/InfoTooltip.tsx |  48 +++++++
 airflow/www/static/js/components/Table/index.tsx |   4 +-
 airflow/www/static/js/datasets/Details.tsx       |  96 ++++++++++----
 airflow/www/static/js/datasets/List.tsx          |  30 ++++-
 airflow/www/static/js/types/api-generated.ts     | 160 +++++++++++------------
 airflow/www/static/js/types/index.ts             |  11 --
 airflow/www/yarn.lock                            |   5 +
 9 files changed, 229 insertions(+), 130 deletions(-)

diff --git a/airflow/www/alias-rest-types.js b/airflow/www/alias-rest-types.js
index 97ed7b4cca..bc89630b16 100644
--- a/airflow/www/alias-rest-types.js
+++ b/airflow/www/alias-rest-types.js
@@ -81,7 +81,7 @@ const generateAliases = (rootNode, writeText, prefix = '') => 
{
 
       const types = schemaMemberNames.map((n) => [
         `${n}`,
-        `export type ${n} = SnakeToCamelCaseNested<${prefixPath(prefix, 
'components')}['schemas']['${n}']>;`,
+        `export type ${n} = CamelCasedPropertiesDeep<${prefixPath(prefix, 
'components')}['schemas']['${n}']>;`,
       ]);
       if (types.length) {
         writeText.push(['comment', `Types for returned data ${prefix}`]);
@@ -172,7 +172,7 @@ function generate(file) {
   writeText.push(['block', license]);
   writeText.push(['comment', 'eslint-disable']);
   // eslint-disable-next-line quotes
-  writeText.push(['block', `import type { SnakeToCamelCaseNested } from 
'.';`]);
+  writeText.push(['block', `import type { CamelCasedPropertiesDeep } from 
'type-fest';`]);
   writeText.push(['block', sourceFile.text]);
   generateAliases(sourceFile, writeText);
 
diff --git a/airflow/www/package.json b/airflow/www/package.json
index a85bf0ca7d..f9091602f0 100644
--- a/airflow/www/package.json
+++ b/airflow/www/package.json
@@ -108,6 +108,7 @@
     "react-router-dom": "^6.3.0",
     "react-table": "^7.8.0",
     "redoc": "^2.0.0-rc.72",
+    "type-fest": "^2.17.0",
     "url-search-params-polyfill": "^8.1.0"
   }
 }
diff --git a/airflow/www/static/js/components/InfoTooltip.tsx 
b/airflow/www/static/js/components/InfoTooltip.tsx
new file mode 100644
index 0000000000..0cf593d466
--- /dev/null
+++ b/airflow/www/static/js/components/InfoTooltip.tsx
@@ -0,0 +1,48 @@
+/*!
+ * 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, { ReactNode } from 'react';
+import {
+  Box, Tooltip,
+} from '@chakra-ui/react';
+import { MdInfo } from 'react-icons/md';
+import { useContainerRef } from 'src/context/containerRef';
+import type { IconBaseProps } from 'react-icons';
+
+interface InfoTooltipProps extends IconBaseProps {
+  label: ReactNode;
+}
+
+const InfoTooltip = ({ label, ...rest }: InfoTooltipProps) => {
+  const containerRef = useContainerRef();
+  return (
+    <Tooltip
+      label={label}
+      hasArrow
+      placement="top"
+      portalProps={{ containerRef }}
+    >
+      <Box display="inline" ml={1} color="gray.500">
+        <MdInfo {...rest} />
+      </Box>
+    </Tooltip>
+  );
+};
+
+export default InfoTooltip;
diff --git a/airflow/www/static/js/components/Table/index.tsx 
b/airflow/www/static/js/components/Table/index.tsx
index 534cc50f61..11087bdb26 100644
--- a/airflow/www/static/js/components/Table/index.tsx
+++ b/airflow/www/static/js/components/Table/index.tsx
@@ -198,7 +198,7 @@ export const Table = ({
               <Th
                 {...column.getHeaderProps(column.getSortByToggleProps())}
               >
-                <>
+                <Flex>
                   {column.render('Header')}
                   {column.isSorted && (
                     column.isSortedDesc ? (
@@ -208,7 +208,7 @@ export const Table = ({
                     )
                   )}
                   {(!column.isSorted && column.canSort) && (<TiArrowUnsorted 
aria-label="unsorted" style={{ display: 'inline' }} size="1em" />)}
-                </>
+                </Flex>
               </Th>
             ))}
           </Tr>
diff --git a/airflow/www/static/js/datasets/Details.tsx 
b/airflow/www/static/js/datasets/Details.tsx
index 7cc16c101c..753f1dc333 100644
--- a/airflow/www/static/js/datasets/Details.tsx
+++ b/airflow/www/static/js/datasets/Details.tsx
@@ -19,23 +19,84 @@
 
 import React, { useMemo, useState } from 'react';
 import {
-  Box, Heading, Text, Code, Flex, Spinner, Button,
+  Box, Heading, Text, Code, Flex, Spinner, Button, Link,
 } from '@chakra-ui/react';
 import { snakeCase } from 'lodash';
 import type { SortingRule } from 'react-table';
 
-import Time from 'src/components/Time';
 import { useDatasetEvents, useDataset } from 'src/api';
 import {
   Table, TimeCell, CodeCell, TaskInstanceLink,
 } from 'src/components/Table';
 import { ClipboardButton } from 'src/components/Clipboard';
+import type { API } from 'src/types';
+import InfoTooltip from 'src/components/InfoTooltip';
 
 interface Props {
   datasetId: string;
   onBack: () => void;
 }
 
+const Details = ({
+  dataset: {
+    uri,
+    extra,
+    upstreamTaskReferences,
+    downstreamDagReferences,
+  },
+}: { dataset: API.Dataset }) => (
+  <Box>
+    <Heading my={2} fontWeight="normal">
+      Dataset:
+      {' '}
+      {uri}
+      <ClipboardButton value={uri} iconOnly ml={2} />
+    </Heading>
+    {!!extra && (
+      <Flex>
+        <Text mr={1}>Extra:</Text>
+        <Code>{JSON.stringify(extra)}</Code>
+      </Flex>
+    )}
+    {upstreamTaskReferences && !!upstreamTaskReferences.length && (
+    <Box mb={2}>
+      <Flex alignItems="center">
+        <Heading size="md" fontWeight="normal">Producing Tasks</Heading>
+        <InfoTooltip label="Tasks that will update this dataset." size={14} />
+      </Flex>
+      {upstreamTaskReferences.map(({ dagId, taskId }) => (
+        <Link
+          key={`${dagId}.${taskId}`}
+          color="blue.600"
+          href={`/dags/${dagId}/grid`}
+          display="block"
+        >
+          {`${dagId}.${taskId}`}
+        </Link>
+      ))}
+    </Box>
+    )}
+    {downstreamDagReferences && !!downstreamDagReferences.length && (
+    <Box>
+      <Flex alignItems="center">
+        <Heading size="md" fontWeight="normal">Consuming DAGs</Heading>
+        <InfoTooltip label="DAGs that depend on this dataset updating to 
trigger a run." size={14} />
+      </Flex>
+      {downstreamDagReferences.map(({ dagId }) => (
+        <Link
+          key={dagId}
+          color="blue.600"
+          href={`/dags/${dagId}/grid`}
+          display="block"
+        >
+          {dagId}
+        </Link>
+      ))}
+    </Box>
+    )}
+  </Box>
+);
+
 const DatasetDetails = ({ datasetId, onBack }: Props) => {
   const limit = 25;
   const [offset, setOffset] = useState(0);
@@ -85,32 +146,11 @@ const DatasetDetails = ({ datasetId, onBack }: Props) => {
     <Box mt={[6, 3]} maxWidth="1500px">
       <Button onClick={onBack}>See all datasets</Button>
       {isLoading && <Spinner display="block" />}
-      {!!dataset && (
-        <Box>
-          <Heading my={2} fontWeight="normal">
-            Dataset:
-            {' '}
-            {dataset.uri}
-            <ClipboardButton value={dataset.uri} iconOnly ml={2} />
-          </Heading>
-          {!!dataset.extra && (
-            <Flex>
-              <Text mr={1}>Extra:</Text>
-              <Code>{JSON.stringify(dataset.extra)}</Code>
-            </Flex>
-          )}
-          <Flex my={2}>
-            <Text mr={1}>Updated At:</Text>
-            <Time dateTime={dataset.updatedAt} />
-          </Flex>
-          <Flex my={2}>
-            <Text mr={1}>Created At:</Text>
-            <Time dateTime={dataset.createdAt} />
-          </Flex>
-        </Box>
-      )}
-      <Heading size="lg" mt={3} mb={2} fontWeight="normal">Upstream 
Events</Heading>
-      <Text>Whenever a DAG has updated this dataset.</Text>
+      {!!dataset && (<Details dataset={dataset} />)}
+      <Flex alignItems="center">
+        <Heading size="lg" mt={3} mb={2} fontWeight="normal">Events</Heading>
+        <InfoTooltip label="Whenever a DAG has updated this dataset." 
size={18} />
+      </Flex>
       <Table
         data={data}
         columns={columns}
diff --git a/airflow/www/static/js/datasets/List.tsx 
b/airflow/www/static/js/datasets/List.tsx
index a4c08fc2c7..674834c36b 100644
--- a/airflow/www/static/js/datasets/List.tsx
+++ b/airflow/www/static/js/datasets/List.tsx
@@ -24,19 +24,35 @@ import {
   Flex,
   Button,
   Link,
+  Text,
 } from '@chakra-ui/react';
 import { snakeCase } from 'lodash';
 import type { Row, SortingRule } from 'react-table';
 
 import { useDatasets } from 'src/api';
-import { Table, TimeCell, CodeCell } from 'src/components/Table';
+import { Table, CodeCell } from 'src/components/Table';
 import type { API } from 'src/types';
 import { MdOutlineAccountTree } from 'react-icons/md';
+import InfoTooltip from 'src/components/InfoTooltip';
 
 interface Props {
   onSelect: (datasetId: string) => void;
 }
 
+const UpstreamHeader = () => (
+  <Flex>
+    <Text>Producing Tasks</Text>
+    <InfoTooltip size={12} label="Number of tasks that will update this 
dataset." />
+  </Flex>
+);
+
+const DownstreamHeader = () => (
+  <Flex>
+    <Text>Consuming DAGs</Text>
+    <InfoTooltip size={12} label="Number of DAGs that will run based on 
updates to this dataset." />
+  </Flex>
+);
+
 const DatasetsList = ({ onSelect }: Props) => {
   const limit = 25;
   const [offset, setOffset] = useState(0);
@@ -60,14 +76,14 @@ const DatasetsList = ({ onSelect }: Props) => {
         Cell: CodeCell,
       },
       {
-        Header: 'Created At',
-        accessor: 'createdAt',
-        Cell: TimeCell,
+        Header: UpstreamHeader,
+        accessor: 'upstreamTaskReferences',
+        Cell: ({ cell: { value } }: any) => value.length,
       },
       {
-        Header: 'Updated At',
-        accessor: 'updatedAt',
-        Cell: TimeCell,
+        Header: DownstreamHeader,
+        accessor: 'downstreamDagReferences',
+        Cell: ({ cell: { value } }: any) => value.length,
       },
     ],
     [],
diff --git a/airflow/www/static/js/types/api-generated.ts 
b/airflow/www/static/js/types/api-generated.ts
index b0d7110d64..509cf41c3f 100644
--- a/airflow/www/static/js/types/api-generated.ts
+++ b/airflow/www/static/js/types/api-generated.ts
@@ -18,7 +18,7 @@
 */
 
 /* eslint-disable */
-import type { SnakeToCamelCaseNested } from '.';
+import type { CamelCasedPropertiesDeep } from 'type-fest';
 /**
  * This file was auto-generated by openapi-typescript.
  * Do not make direct changes to the file.
@@ -4027,85 +4027,85 @@ export interface external {}
 export type Paths = paths;
 
 /* Types for returned data  */
-export type UserCollectionItem = 
SnakeToCamelCaseNested<components['schemas']['UserCollectionItem']>;
-export type User = SnakeToCamelCaseNested<components['schemas']['User']>;
-export type UserCollection = 
SnakeToCamelCaseNested<components['schemas']['UserCollection']>;
-export type ConnectionCollectionItem = 
SnakeToCamelCaseNested<components['schemas']['ConnectionCollectionItem']>;
-export type ConnectionCollection = 
SnakeToCamelCaseNested<components['schemas']['ConnectionCollection']>;
-export type Connection = 
SnakeToCamelCaseNested<components['schemas']['Connection']>;
-export type ConnectionTest = 
SnakeToCamelCaseNested<components['schemas']['ConnectionTest']>;
-export type DAG = SnakeToCamelCaseNested<components['schemas']['DAG']>;
-export type DAGCollection = 
SnakeToCamelCaseNested<components['schemas']['DAGCollection']>;
-export type DAGRun = SnakeToCamelCaseNested<components['schemas']['DAGRun']>;
-export type UpdateDagRunState = 
SnakeToCamelCaseNested<components['schemas']['UpdateDagRunState']>;
-export type DAGRunCollection = 
SnakeToCamelCaseNested<components['schemas']['DAGRunCollection']>;
-export type DagWarning = 
SnakeToCamelCaseNested<components['schemas']['DagWarning']>;
-export type DagWarningCollection = 
SnakeToCamelCaseNested<components['schemas']['DagWarningCollection']>;
-export type EventLog = 
SnakeToCamelCaseNested<components['schemas']['EventLog']>;
-export type EventLogCollection = 
SnakeToCamelCaseNested<components['schemas']['EventLogCollection']>;
-export type ImportError = 
SnakeToCamelCaseNested<components['schemas']['ImportError']>;
-export type ImportErrorCollection = 
SnakeToCamelCaseNested<components['schemas']['ImportErrorCollection']>;
-export type HealthInfo = 
SnakeToCamelCaseNested<components['schemas']['HealthInfo']>;
-export type MetadatabaseStatus = 
SnakeToCamelCaseNested<components['schemas']['MetadatabaseStatus']>;
-export type SchedulerStatus = 
SnakeToCamelCaseNested<components['schemas']['SchedulerStatus']>;
-export type Pool = SnakeToCamelCaseNested<components['schemas']['Pool']>;
-export type PoolCollection = 
SnakeToCamelCaseNested<components['schemas']['PoolCollection']>;
-export type Provider = 
SnakeToCamelCaseNested<components['schemas']['Provider']>;
-export type ProviderCollection = 
SnakeToCamelCaseNested<components['schemas']['ProviderCollection']>;
-export type SLAMiss = SnakeToCamelCaseNested<components['schemas']['SLAMiss']>;
-export type TaskInstance = 
SnakeToCamelCaseNested<components['schemas']['TaskInstance']>;
-export type TaskInstanceCollection = 
SnakeToCamelCaseNested<components['schemas']['TaskInstanceCollection']>;
-export type TaskInstanceReference = 
SnakeToCamelCaseNested<components['schemas']['TaskInstanceReference']>;
-export type TaskInstanceReferenceCollection = 
SnakeToCamelCaseNested<components['schemas']['TaskInstanceReferenceCollection']>;
-export type VariableCollectionItem = 
SnakeToCamelCaseNested<components['schemas']['VariableCollectionItem']>;
-export type VariableCollection = 
SnakeToCamelCaseNested<components['schemas']['VariableCollection']>;
-export type Variable = 
SnakeToCamelCaseNested<components['schemas']['Variable']>;
-export type XComCollectionItem = 
SnakeToCamelCaseNested<components['schemas']['XComCollectionItem']>;
-export type XComCollection = 
SnakeToCamelCaseNested<components['schemas']['XComCollection']>;
-export type XCom = SnakeToCamelCaseNested<components['schemas']['XCom']>;
-export type DAGDetail = 
SnakeToCamelCaseNested<components['schemas']['DAGDetail']>;
-export type ExtraLink = 
SnakeToCamelCaseNested<components['schemas']['ExtraLink']>;
-export type ExtraLinkCollection = 
SnakeToCamelCaseNested<components['schemas']['ExtraLinkCollection']>;
-export type Task = SnakeToCamelCaseNested<components['schemas']['Task']>;
-export type TaskCollection = 
SnakeToCamelCaseNested<components['schemas']['TaskCollection']>;
-export type PluginCollectionItem = 
SnakeToCamelCaseNested<components['schemas']['PluginCollectionItem']>;
-export type PluginCollection = 
SnakeToCamelCaseNested<components['schemas']['PluginCollection']>;
-export type Role = SnakeToCamelCaseNested<components['schemas']['Role']>;
-export type RoleCollection = 
SnakeToCamelCaseNested<components['schemas']['RoleCollection']>;
-export type Action = SnakeToCamelCaseNested<components['schemas']['Action']>;
-export type ActionCollection = 
SnakeToCamelCaseNested<components['schemas']['ActionCollection']>;
-export type Resource = 
SnakeToCamelCaseNested<components['schemas']['Resource']>;
-export type ActionResource = 
SnakeToCamelCaseNested<components['schemas']['ActionResource']>;
-export type Dataset = SnakeToCamelCaseNested<components['schemas']['Dataset']>;
-export type DatasetTaskRef = 
SnakeToCamelCaseNested<components['schemas']['DatasetTaskRef']>;
-export type DatasetDagRef = 
SnakeToCamelCaseNested<components['schemas']['DatasetDagRef']>;
-export type DatasetCollection = 
SnakeToCamelCaseNested<components['schemas']['DatasetCollection']>;
-export type DatasetEvent = 
SnakeToCamelCaseNested<components['schemas']['DatasetEvent']>;
-export type DatasetEventCollection = 
SnakeToCamelCaseNested<components['schemas']['DatasetEventCollection']>;
-export type ConfigOption = 
SnakeToCamelCaseNested<components['schemas']['ConfigOption']>;
-export type ConfigSection = 
SnakeToCamelCaseNested<components['schemas']['ConfigSection']>;
-export type Config = SnakeToCamelCaseNested<components['schemas']['Config']>;
-export type VersionInfo = 
SnakeToCamelCaseNested<components['schemas']['VersionInfo']>;
-export type ClearDagRun = 
SnakeToCamelCaseNested<components['schemas']['ClearDagRun']>;
-export type ClearTaskInstance = 
SnakeToCamelCaseNested<components['schemas']['ClearTaskInstance']>;
-export type UpdateTaskInstancesState = 
SnakeToCamelCaseNested<components['schemas']['UpdateTaskInstancesState']>;
-export type ListDagRunsForm = 
SnakeToCamelCaseNested<components['schemas']['ListDagRunsForm']>;
-export type ListTaskInstanceForm = 
SnakeToCamelCaseNested<components['schemas']['ListTaskInstanceForm']>;
-export type ScheduleInterval = 
SnakeToCamelCaseNested<components['schemas']['ScheduleInterval']>;
-export type TimeDelta = 
SnakeToCamelCaseNested<components['schemas']['TimeDelta']>;
-export type RelativeDelta = 
SnakeToCamelCaseNested<components['schemas']['RelativeDelta']>;
-export type CronExpression = 
SnakeToCamelCaseNested<components['schemas']['CronExpression']>;
-export type Timezone = 
SnakeToCamelCaseNested<components['schemas']['Timezone']>;
-export type Tag = SnakeToCamelCaseNested<components['schemas']['Tag']>;
-export type Color = SnakeToCamelCaseNested<components['schemas']['Color']>;
-export type ClassReference = 
SnakeToCamelCaseNested<components['schemas']['ClassReference']>;
-export type Error = SnakeToCamelCaseNested<components['schemas']['Error']>;
-export type CollectionInfo = 
SnakeToCamelCaseNested<components['schemas']['CollectionInfo']>;
-export type TaskState = 
SnakeToCamelCaseNested<components['schemas']['TaskState']>;
-export type DagState = 
SnakeToCamelCaseNested<components['schemas']['DagState']>;
-export type TriggerRule = 
SnakeToCamelCaseNested<components['schemas']['TriggerRule']>;
-export type WeightRule = 
SnakeToCamelCaseNested<components['schemas']['WeightRule']>;
-export type HealthStatus = 
SnakeToCamelCaseNested<components['schemas']['HealthStatus']>;
+export type UserCollectionItem = 
CamelCasedPropertiesDeep<components['schemas']['UserCollectionItem']>;
+export type User = CamelCasedPropertiesDeep<components['schemas']['User']>;
+export type UserCollection = 
CamelCasedPropertiesDeep<components['schemas']['UserCollection']>;
+export type ConnectionCollectionItem = 
CamelCasedPropertiesDeep<components['schemas']['ConnectionCollectionItem']>;
+export type ConnectionCollection = 
CamelCasedPropertiesDeep<components['schemas']['ConnectionCollection']>;
+export type Connection = 
CamelCasedPropertiesDeep<components['schemas']['Connection']>;
+export type ConnectionTest = 
CamelCasedPropertiesDeep<components['schemas']['ConnectionTest']>;
+export type DAG = CamelCasedPropertiesDeep<components['schemas']['DAG']>;
+export type DAGCollection = 
CamelCasedPropertiesDeep<components['schemas']['DAGCollection']>;
+export type DAGRun = CamelCasedPropertiesDeep<components['schemas']['DAGRun']>;
+export type UpdateDagRunState = 
CamelCasedPropertiesDeep<components['schemas']['UpdateDagRunState']>;
+export type DAGRunCollection = 
CamelCasedPropertiesDeep<components['schemas']['DAGRunCollection']>;
+export type DagWarning = 
CamelCasedPropertiesDeep<components['schemas']['DagWarning']>;
+export type DagWarningCollection = 
CamelCasedPropertiesDeep<components['schemas']['DagWarningCollection']>;
+export type EventLog = 
CamelCasedPropertiesDeep<components['schemas']['EventLog']>;
+export type EventLogCollection = 
CamelCasedPropertiesDeep<components['schemas']['EventLogCollection']>;
+export type ImportError = 
CamelCasedPropertiesDeep<components['schemas']['ImportError']>;
+export type ImportErrorCollection = 
CamelCasedPropertiesDeep<components['schemas']['ImportErrorCollection']>;
+export type HealthInfo = 
CamelCasedPropertiesDeep<components['schemas']['HealthInfo']>;
+export type MetadatabaseStatus = 
CamelCasedPropertiesDeep<components['schemas']['MetadatabaseStatus']>;
+export type SchedulerStatus = 
CamelCasedPropertiesDeep<components['schemas']['SchedulerStatus']>;
+export type Pool = CamelCasedPropertiesDeep<components['schemas']['Pool']>;
+export type PoolCollection = 
CamelCasedPropertiesDeep<components['schemas']['PoolCollection']>;
+export type Provider = 
CamelCasedPropertiesDeep<components['schemas']['Provider']>;
+export type ProviderCollection = 
CamelCasedPropertiesDeep<components['schemas']['ProviderCollection']>;
+export type SLAMiss = 
CamelCasedPropertiesDeep<components['schemas']['SLAMiss']>;
+export type TaskInstance = 
CamelCasedPropertiesDeep<components['schemas']['TaskInstance']>;
+export type TaskInstanceCollection = 
CamelCasedPropertiesDeep<components['schemas']['TaskInstanceCollection']>;
+export type TaskInstanceReference = 
CamelCasedPropertiesDeep<components['schemas']['TaskInstanceReference']>;
+export type TaskInstanceReferenceCollection = 
CamelCasedPropertiesDeep<components['schemas']['TaskInstanceReferenceCollection']>;
+export type VariableCollectionItem = 
CamelCasedPropertiesDeep<components['schemas']['VariableCollectionItem']>;
+export type VariableCollection = 
CamelCasedPropertiesDeep<components['schemas']['VariableCollection']>;
+export type Variable = 
CamelCasedPropertiesDeep<components['schemas']['Variable']>;
+export type XComCollectionItem = 
CamelCasedPropertiesDeep<components['schemas']['XComCollectionItem']>;
+export type XComCollection = 
CamelCasedPropertiesDeep<components['schemas']['XComCollection']>;
+export type XCom = CamelCasedPropertiesDeep<components['schemas']['XCom']>;
+export type DAGDetail = 
CamelCasedPropertiesDeep<components['schemas']['DAGDetail']>;
+export type ExtraLink = 
CamelCasedPropertiesDeep<components['schemas']['ExtraLink']>;
+export type ExtraLinkCollection = 
CamelCasedPropertiesDeep<components['schemas']['ExtraLinkCollection']>;
+export type Task = CamelCasedPropertiesDeep<components['schemas']['Task']>;
+export type TaskCollection = 
CamelCasedPropertiesDeep<components['schemas']['TaskCollection']>;
+export type PluginCollectionItem = 
CamelCasedPropertiesDeep<components['schemas']['PluginCollectionItem']>;
+export type PluginCollection = 
CamelCasedPropertiesDeep<components['schemas']['PluginCollection']>;
+export type Role = CamelCasedPropertiesDeep<components['schemas']['Role']>;
+export type RoleCollection = 
CamelCasedPropertiesDeep<components['schemas']['RoleCollection']>;
+export type Action = CamelCasedPropertiesDeep<components['schemas']['Action']>;
+export type ActionCollection = 
CamelCasedPropertiesDeep<components['schemas']['ActionCollection']>;
+export type Resource = 
CamelCasedPropertiesDeep<components['schemas']['Resource']>;
+export type ActionResource = 
CamelCasedPropertiesDeep<components['schemas']['ActionResource']>;
+export type Dataset = 
CamelCasedPropertiesDeep<components['schemas']['Dataset']>;
+export type DatasetTaskRef = 
CamelCasedPropertiesDeep<components['schemas']['DatasetTaskRef']>;
+export type DatasetDagRef = 
CamelCasedPropertiesDeep<components['schemas']['DatasetDagRef']>;
+export type DatasetCollection = 
CamelCasedPropertiesDeep<components['schemas']['DatasetCollection']>;
+export type DatasetEvent = 
CamelCasedPropertiesDeep<components['schemas']['DatasetEvent']>;
+export type DatasetEventCollection = 
CamelCasedPropertiesDeep<components['schemas']['DatasetEventCollection']>;
+export type ConfigOption = 
CamelCasedPropertiesDeep<components['schemas']['ConfigOption']>;
+export type ConfigSection = 
CamelCasedPropertiesDeep<components['schemas']['ConfigSection']>;
+export type Config = CamelCasedPropertiesDeep<components['schemas']['Config']>;
+export type VersionInfo = 
CamelCasedPropertiesDeep<components['schemas']['VersionInfo']>;
+export type ClearDagRun = 
CamelCasedPropertiesDeep<components['schemas']['ClearDagRun']>;
+export type ClearTaskInstance = 
CamelCasedPropertiesDeep<components['schemas']['ClearTaskInstance']>;
+export type UpdateTaskInstancesState = 
CamelCasedPropertiesDeep<components['schemas']['UpdateTaskInstancesState']>;
+export type ListDagRunsForm = 
CamelCasedPropertiesDeep<components['schemas']['ListDagRunsForm']>;
+export type ListTaskInstanceForm = 
CamelCasedPropertiesDeep<components['schemas']['ListTaskInstanceForm']>;
+export type ScheduleInterval = 
CamelCasedPropertiesDeep<components['schemas']['ScheduleInterval']>;
+export type TimeDelta = 
CamelCasedPropertiesDeep<components['schemas']['TimeDelta']>;
+export type RelativeDelta = 
CamelCasedPropertiesDeep<components['schemas']['RelativeDelta']>;
+export type CronExpression = 
CamelCasedPropertiesDeep<components['schemas']['CronExpression']>;
+export type Timezone = 
CamelCasedPropertiesDeep<components['schemas']['Timezone']>;
+export type Tag = CamelCasedPropertiesDeep<components['schemas']['Tag']>;
+export type Color = CamelCasedPropertiesDeep<components['schemas']['Color']>;
+export type ClassReference = 
CamelCasedPropertiesDeep<components['schemas']['ClassReference']>;
+export type Error = CamelCasedPropertiesDeep<components['schemas']['Error']>;
+export type CollectionInfo = 
CamelCasedPropertiesDeep<components['schemas']['CollectionInfo']>;
+export type TaskState = 
CamelCasedPropertiesDeep<components['schemas']['TaskState']>;
+export type DagState = 
CamelCasedPropertiesDeep<components['schemas']['DagState']>;
+export type TriggerRule = 
CamelCasedPropertiesDeep<components['schemas']['TriggerRule']>;
+export type WeightRule = 
CamelCasedPropertiesDeep<components['schemas']['WeightRule']>;
+export type HealthStatus = 
CamelCasedPropertiesDeep<components['schemas']['HealthStatus']>;
 
 /* Alias operations to PascalCase. */
 export type Operations = operations;
diff --git a/airflow/www/static/js/types/index.ts 
b/airflow/www/static/js/types/index.ts
index c8eb5d9ac8..d65e68115d 100644
--- a/airflow/www/static/js/types/index.ts
+++ b/airflow/www/static/js/types/index.ts
@@ -79,15 +79,6 @@ interface Task {
   hasOutletDatasets?: boolean;
 }
 
-type SnakeToCamelCase<S extends string> =
-  S extends `${infer T}_${infer U}`
-    ? `${T}${Capitalize<SnakeToCamelCase<U>>}`
-    : S;
-
-type SnakeToCamelCaseNested<T> = T extends object ? {
-  [K in keyof T as SnakeToCamelCase<K & string>]: SnakeToCamelCaseNested<T[K]>
-} : T;
-
 export type {
   Dag,
   DagRun,
@@ -96,6 +87,4 @@ export type {
   TaskInstance,
   Task,
   API,
-  SnakeToCamelCase,
-  SnakeToCamelCaseNested,
 };
diff --git a/airflow/www/yarn.lock b/airflow/www/yarn.lock
index 4295236051..c4c02ca5d7 100644
--- a/airflow/www/yarn.lock
+++ b/airflow/www/yarn.lock
@@ -9811,6 +9811,11 @@ type-fest@^1.2.1:
   resolved 
"https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1";
   integrity 
sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
 
+type-fest@^2.17.0:
+  version "2.17.0"
+  resolved 
"https://registry.yarnpkg.com/type-fest/-/type-fest-2.17.0.tgz#c677030ce61e5be0c90c077d52571eb73c506ea9";
+  integrity 
sha512-U+g3/JVXnOki1kLSc+xZGPRll3Ah9u2VIG6Sn9iH9YX6UkPERmt6O/0fIyTgsd2/whV0+gAaHAg8fz6sG1QzMA==
+
 typedarray-to-buffer@^3.1.5:
   version "3.1.5"
   resolved 
"https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080";

Reply via email to