Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade more javascript files to typescript #24715

Merged
merged 3 commits into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const AutoRefresh = () => {
</FormLabel>
<Switch
id="auto-refresh"
onChange={() => toggleRefresh(true)}
onChange={toggleRefresh}
isDisabled={isPaused}
isChecked={isRefreshOn}
size="lg"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,32 @@
import React from 'react';
import { Flex, IconButton } from '@chakra-ui/react';
import { MdExpand, MdCompress } from 'react-icons/md';
import type { Task } from './types';

const getGroupIds = (groups) => {
const groupIds = [];
const checkTasks = (tasks) => tasks.forEach((task) => {
const getGroupIds = (groups: Task[]) => {
const groupIds: string[] = [];
const checkTasks = (tasks: Task[]) => tasks.forEach((task) => {
if (task.children) {
groupIds.push(task.label);
groupIds.push(task.label!);
checkTasks(task.children);
}
});
checkTasks(groups);
return groupIds;
};

const ToggleGroups = ({ groups, openGroupIds, onToggleGroups }) => {
interface Props {
groups: Task;
openGroupIds: string[];
onToggleGroups: (groupIds: string[]) => void;
}

const ToggleGroups = ({ groups, openGroupIds, onToggleGroups }: Props) => {
// Don't show button if the DAG has no task groups
const hasGroups = groups.children && groups.children.find((c) => !!c.children);
if (!hasGroups) return null;

const allGroupIds = getGroupIds(groups.children);
const allGroupIds = getGroupIds(groups.children || []);

const isExpandDisabled = allGroupIds.length === openGroupIds.length;
const isCollapseDisabled = !openGroupIds.length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ export const ClipboardButton = forwardRef(
},
);

export const ClipboardText = ({ value }) => (
interface Props {
value: string
}

export const ClipboardText = ({ value }: Props) => (
<>
{value}
<ClipboardButton value={value} iconOnly variant="ghost" size="xs" fontSize="xl" ml={1} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@
import React from 'react';
import {
Button,
ButtonProps,
Link,
} from '@chakra-ui/react';

const LinkButton = ({ children, ...rest }) => (<Button as={Link} variant="ghost" colorScheme="blue" {...rest}>{children}</Button>);
interface Props extends ButtonProps {
href?: string;
}

const LinkButton = ({ children, ...rest }: Props) => (<Button as={Link} variant="ghost" colorScheme="blue" {...rest}>{children}</Button>);

export default LinkButton;
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ import { ChakraWrapper } from '../utils/testUtils';

describe('Test TaskName', () => {
test('Displays a normal task name', () => {
const { getByText } = render(<TaskName label="test" />, { wrapper: ChakraWrapper });
const { getByText } = render(<TaskName label="test" onToggle={() => {}} />, { wrapper: ChakraWrapper });

expect(getByText('test')).toBeDefined();
});

test('Displays a mapped task name', () => {
const { getByText } = render(<TaskName level={0} label="test" isMapped />, { wrapper: ChakraWrapper });
const { getByText } = render(<TaskName level={0} label="test" isMapped onToggle={() => {}} />, { wrapper: ChakraWrapper });

expect(getByText('test [ ]')).toBeDefined();
});

test('Displays a group task name', () => {
const { getByText, getByTestId } = render(<TaskName level={0} label="test" isGroup />, { wrapper: ChakraWrapper });
const { getByText, getByTestId } = render(<TaskName level={0} label="test" isGroup onToggle={() => {}} />, { wrapper: ChakraWrapper });

expect(getByText('test')).toBeDefined();
expect(getByTestId('closed-group')).toBeDefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@ import {
} from '@chakra-ui/react';
import { FiChevronUp, FiChevronDown } from 'react-icons/fi';

interface Props {
isGroup?: boolean;
isMapped?: boolean;
onToggle: () => void;
isOpen?: boolean;
level?: number;
label: string;
}

const TaskName = ({
isGroup = false, isMapped = false, onToggle, isOpen = false, level = 0, label,
}) => (
}: Props) => (
<Flex
as={isGroup ? 'button' : 'div'}
onClick={onToggle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { getMetaValue } from '../../utils';
const autoRefreshKey = 'disabledAutoRefresh';

const initialIsPaused = getMetaValue('is_paused') === 'True';
const isRefreshDisabled = JSON.parse(localStorage.getItem(autoRefreshKey));
const isRefreshDisabled = JSON.parse(localStorage.getItem(autoRefreshKey) || 'false');

const AutoRefreshContext = React.createContext({
isRefreshOn: false,
Expand All @@ -37,7 +37,11 @@ const AutoRefreshContext = React.createContext({
startRefresh: () => {},
});

export const AutoRefreshProvider = ({ children }) => {
interface Props {
children: React.ReactNode;
}

export const AutoRefreshProvider = ({ children }: Props) => {
const [isPaused, setIsPaused] = useState(initialIsPaused);
const isRefreshAllowed = !(isPaused || isRefreshDisabled);
const initialState = isRefreshAllowed;
Expand Down Expand Up @@ -72,10 +76,16 @@ export const AutoRefreshProvider = ({ children }) => {
);

useEffect(() => {
const handleChange = (e) => {
setIsPaused(!e.detail);
if (!e.detail) {
stopRefresh();
function isCustomEvent(event: Event): event is CustomEvent {
return 'detail' in event;
}

const handleChange = (e: Event) => {
if (isCustomEvent(e)) {
setIsPaused(!e.detail);
if (!e.detail) {
stopRefresh();
}
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ import { Box, Text } from '@chakra-ui/react';

import { formatDuration } from '../../datetime_utils';
import Time from '../components/Time';
import type { RunWithDuration } from './index';

interface Props {
dagRun: RunWithDuration;
}

const DagRunTooltip = ({
dagRun: {
state, duration, dataIntervalStart, executionDate, runType,
},
}) => (
}: Props) => (
<Box py="2px">
<Text>
Status:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,20 @@ import {

import { useContainerRef } from '../../context/containerRef';

interface Props {
isOpen: boolean;
onClose: () => void;
title?: string;
description: string;
body?: string[];
onConfirm: () => void;
isLoading?: boolean;
}

const ConfirmDialog = ({
isOpen, onClose, title = 'Wait a minute', description, body = [], onConfirm, isLoading = false,
}) => {
const initialFocusRef = useRef();
}: Props) => {
const initialFocusRef = useRef<HTMLButtonElement>(null);
const containerRef = useContainerRef();
return (
<AlertDialog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ import QueueRun from './QueueRun';
import ClearRun from './ClearRun';
import { useGridData } from '../../../api';
import { appendSearchParams, getMetaValue } from '../../../../utils';
import type { DagRun as DagRunType } from '../../../types';

const dagId = getMetaValue('dag_id');
const graphUrl = getMetaValue('graph_url');
const dagRunDetailsUrl = getMetaValue('dagrun_details_url');

const DagRun = ({ runId }) => {
interface Props {
runId: DagRunType['runId'];
}

const DagRun = ({ runId }: Props) => {
const { data: { dagRuns } } = useGridData();
const run = dagRuns.find((dr) => dr.runId === runId);
if (!run) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,17 @@ import { getDuration, formatDuration } from '../../../../datetime_utils';
import { SimpleStatus } from '../../../components/StatusBox';
import Time from '../../../components/Time';
import { ClipboardText } from '../../../components/Clipboard';
import type { Task, TaskInstance, TaskState } from '../../../types';

const Details = ({ instance, group, operator }) => {
interface Props {
instance: TaskInstance;
group: Task;
operator: string;
}

const Details = ({ instance, group, operator }: Props) => {
const isGroup = !!group.children;
const summary = [];
const summary: React.ReactNode[] = [];

const {
taskId,
Expand All @@ -45,18 +52,17 @@ const Details = ({ instance, group, operator }) => {

const {
isMapped,
children,
tooltip,
} = group;

const numMap = finalStatesMap();
let numMapped = 0;
if (isGroup) {
children.forEach((child) => {
group.children?.forEach((child) => {
const taskInstance = child.instances.find((ti) => ti.runId === runId);
if (taskInstance) {
const stateKey = taskInstance.state == null ? 'no_status' : taskInstance.state;
if (numMap.has(stateKey)) numMap.set(stateKey, numMap.get(stateKey) + 1);
if (numMap.has(stateKey)) numMap.set(stateKey, (numMap.get(stateKey) || 0) + 1);
}
});
} else if (isMapped && mappedStates) {
Expand All @@ -72,7 +78,7 @@ const Details = ({ instance, group, operator }) => {
summary.push(
// eslint-disable-next-line react/no-array-index-key
<Flex key={val} ml="10px" alignItems="center">
<SimpleStatus state={val} mx={2} />
<SimpleStatus state={val as TaskState} mx={2} />
{val}
{': '}
{key}
Expand All @@ -82,7 +88,7 @@ const Details = ({ instance, group, operator }) => {
});

const taskIdTitle = isGroup ? 'Task Group Id: ' : 'Task Id: ';
const isStateFinal = ['success', 'failed', 'upstream_failed', 'skipped'].includes(state);
const isStateFinal = state && ['success', 'failed', 'upstream_failed', 'skipped'].includes(state);
const isOverall = (isMapped || isGroup) && 'Overall ';

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,27 @@ import {
} from '@chakra-ui/react';

import { useExtraLinks } from '../../../api';
import type { Task } from '../../../types';

interface Props {
dagId: string;
taskId: Task['id'];
executionDate: string;
extraLinks: string[];
}

const ExtraLinks = ({
dagId,
taskId,
executionDate,
extraLinks = [],
}) => {
}: Props) => {
const { data: links = [] } = useExtraLinks({
dagId, taskId, executionDate, extraLinks,
});

if (!links.length) return null;
const isExternal = (url) => /^(?:[a-z]+:)?\/\//.test(url);
const isExternal = (url: string) => /^(?:[a-z]+:)?\/\//.test(url);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import {

import { getMetaValue, appendSearchParams } from '../../../../utils';
import LinkButton from '../../../components/LinkButton';
import type { Task, DagRun } from '../../../types';

const dagId = getMetaValue('dag_id');
const dagId = getMetaValue('dag_id') || '';
const isK8sExecutor = getMetaValue('k8s_or_k8scelery_executor') === 'True';
const numRuns = getMetaValue('num_runs');
const baseDate = getMetaValue('base_date');
Expand All @@ -36,12 +37,21 @@ const renderedTemplatesUrl = getMetaValue('rendered_templates_url');
const xcomUrl = getMetaValue('xcom_url');
const logUrl = getMetaValue('log_url');
const taskUrl = getMetaValue('task_url');
const gridUrl = getMetaValue('grid_url');
const gridUrl = getMetaValue('grid_url') || '';
const gridUrlNoRoot = getMetaValue('grid_url_no_root');

interface Props {
runId: DagRun['runId'];
taskId: Task['id'];
executionDate: string;
operator: string;
isMapped?: boolean;
}

const Nav = ({
runId, taskId, executionDate, operator, isMapped,
}) => {
runId, taskId, executionDate, operator, isMapped = false,
}: Props) => {
if (!taskId) return null;
const params = new URLSearchParams({
task_id: taskId,
execution_date: executionDate,
Expand All @@ -63,14 +73,15 @@ const Nav = ({
const filterParams = new URLSearchParams({
task_id: taskId,
dag_run_id: runId,
base_date: baseDate,
num_runs: numRuns,
root: taskId,
}).toString();
});

if (baseDate) filterParams.append('base_date', baseDate);
if (numRuns) filterParams.append('num_runs', numRuns);

const allInstancesLink = `${taskInstancesUrl}?${listParams.toString()}`;

const filterUpstreamLink = appendSearchParams(gridUrlNoRoot, filterParams);
const filterUpstreamLink = appendSearchParams(gridUrlNoRoot, filterParams.toString());
const subDagLink = appendSearchParams(gridUrl.replace(dagId, `${dagId}.${taskId}`), subDagParams);

// TODO: base subdag zooming as its own attribute instead of via operator name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const TaskInstance = ({ taskId, runId }: Props) => {
const operator = (task?.classRef && task?.classRef?.className) ?? '';

const instance = group.instances.find((ti) => ti.runId === runId);
if (!instance) return null;

let taskActionsTitle = 'Task Actions';
if (isMapped) {
Expand Down Expand Up @@ -185,7 +186,7 @@ const TaskInstance = ({ taskId, runId }: Props) => {
<Details instance={instance} group={group} operator={operator} />
<ExtraLinks
taskId={taskId}
dagId={dagId}
dagId={dagId || ''}
executionDate={executionDate}
extraLinks={group?.extraLinks || []}
/>
Expand Down
2 changes: 1 addition & 1 deletion airflow/www/static/js/grid/renderTaskRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ const Row = (props: RowProps) => {
onToggle={memoizedToggle}
isGroup={isGroup}
isMapped={task.isMapped}
label={task.label}
label={task.label || task.id || ''}
isOpen={isOpen}
level={level}
/>
Expand Down