src/components/TaskListingHeader/TaskListingHeader.tsx (162 lines of code) (raw):

import React from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { SetQuery } from 'use-query-params'; import { Run } from '@/types'; import Button from '@components/Button'; import ButtonGroup from '@components/ButtonGroup'; import Icon from '@components/Icon'; import SearchField from '@components/SearchField'; import { ItemRow } from '@components/Structure'; import CollapseButton from '@components/TaskListingHeader/components/CollapseButton'; import CustomSettings from '@components/TaskListingHeader/components/CustomSettings'; import { RowCounts } from '@components/Timeline/taskdataUtils'; import { TaskListMode, TaskSettingsQueryParameters, TaskSettingsState } from '@components/Timeline/useTaskListSettings'; import { SearchFieldReturnType } from '@hooks/useSearchField'; import FEATURE_FLAGS from '@utils/FEATURE'; import { getRunId } from '@utils/run'; // // Typedef // export type TaskListingProps = { run: Run; onToggleCollapse: (type: 'expand' | 'collapse') => void; onModeSelect: (mode: TaskListMode) => void; onSetFullscreen?: () => void; onZoom?: (type: 'in' | 'out' | 'reset') => void; isFullscreen?: boolean; userZoomed?: boolean; settings: TaskSettingsState; setQueryParam: SetQuery<TaskSettingsQueryParameters>; searchField: SearchFieldReturnType; counts: RowCounts; isAnyGroupOpen: boolean; }; // // Horizontal row with controls for task list (Timeline and task page) // const TaskListingHeader: React.FC<TaskListingProps> = ({ run, onModeSelect, onToggleCollapse, onSetFullscreen, onZoom, settings, setQueryParam, isFullscreen, searchField, counts, userZoomed = false, isAnyGroupOpen, }) => { const { t } = useTranslation(); const activeMode = getMode(settings); const autoCompleteSettings = { url: `/flows/${run.flow_id}/runs/${getRunId(run)}/artifacts/autocomplete`, params: (input: string) => ({ 'name:co': input, }), }; const autoCompleteEnabled = (str: string) => str.indexOf(':') === -1; return ( <TaskListingContainer> <SettingsRow> <SettingsRowLeft> <CollapseButton disabled={!settings.group} expand={() => onToggleCollapse('expand')} collapse={() => onToggleCollapse('collapse')} isAnyGroupOpen={isAnyGroupOpen} /> {(FEATURE_FLAGS.ARTIFACT_SEARCH || FEATURE_FLAGS.FOREACH_VAR_SEARCH) && ( <SearchField initialValue={searchField.fieldProps.text} onUpdate={searchField.fieldProps.setText} results={searchField.results} autoCompleteSettings={autoCompleteSettings} autoCompleteEnabled={autoCompleteEnabled} /> )} <CustomSettings updateSort={(order, direction) => setQueryParam({ order, direction }, 'replaceIn')} updateStatusFilter={(status: null | string) => setQueryParam({ status })} updateGroupBy={(group) => setQueryParam({ group: group ? 'true' : 'false' }, 'replaceIn')} updateMode={(newMode) => onModeSelect(newMode)} activeMode={activeMode} sort={settings.sort} statusFilter={settings.statusFilter} group={settings.group} counts={counts} /> </SettingsRowLeft> <div> {(onZoom || onSetFullscreen) && ( <ItemRow noWidth> {onZoom && ( <ButtonGroup big> <Button size="sm" onClick={() => onZoom('reset')} active={!userZoomed} data-testid="timeline-header-zoom-fit" title={t('timeline.fit-to-screen') ?? ''} > <span style={{ fontSize: '0.875rem' }}>{t('timeline.fit-to-screen')}</span> </Button> <Button size="sm" onClick={() => onZoom('out')} data-testid="timeline-header-zoom-out" title={t('timeline.zoom-out') ?? ''} > <Icon name="minus" /> </Button> <Button size="sm" onClick={() => onZoom('in')} data-testid="timeline-header-zoom-in" title={t('timeline.zoom-in') ?? ''} > <Icon name="plus" /> </Button> </ButtonGroup> )} {!isFullscreen && onSetFullscreen && ( <ExpandButton onClick={() => onSetFullscreen()} iconOnly title={t('timeline.fullscreen') ?? ''}> <Icon name="maximize" /> </ExpandButton> )} </ItemRow> )} </div> </SettingsRow> </TaskListingContainer> ); }; // // Utils // export function getMode(settings: TaskSettingsState): TaskListMode { if (settings.isCustomEnabled) { return 'custom'; } else if ( settings.group === true && !settings.statusFilter && settings.sort[0] === 'startTime' && settings.sort[1] === 'asc' ) { return 'overview'; } else if ( settings.group === false && !settings.statusFilter && settings.sort[0] === 'startTime' && settings.sort[1] === 'desc' ) { return 'monitoring'; } else if ( settings.group === true && settings.statusFilter === 'failed' && settings.sort[0] === 'startTime' && settings.sort[1] === 'asc' ) { return 'error-tracker'; } return 'custom'; } // // Style // const TaskListingContainer = styled.div` border-bottom: var(--task-list-header-border-bottom); font-size: var(--font-size-primary); position: relative; `; const SettingsRow = styled.div` display: flex; justify-content: space-between; align-items: center; padding: 0 0 1rem 0; width: 100%; `; const SettingsRowLeft = styled.div` display: flex; `; const ExpandButton = styled(Button)` height: var(--input-height); width: var(--input-height); i { margin: 0 auto; } `; export default TaskListingHeader;