You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bb...@apache.org on 2022/08/02 16:07:12 UTC
[airflow] branch main updated: Show upstream/downstreams from a dataset (#25403)
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 <br...@gmail.com>
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 <15...@users.noreply.github.com>
* remove created/updated at, separate links
* update copy
Co-authored-by: Daniel Standish <15...@users.noreply.github.com>
---
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"