Skip to content

Commit

Permalink
Upgrade more javascript files to typescript (#24715)
Browse files Browse the repository at this point in the history
* upgrade more js files to ts

* upgrade more component files

* fix linting issues
  • Loading branch information
bbovenzi authored Jun 29, 2022
1 parent cef97fc commit 41aa9ab
Show file tree
Hide file tree
Showing 18 changed files with 123 additions and 42 deletions.
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
File renamed without changes.
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

0 comments on commit 41aa9ab

Please sign in to comment.