src/widgets/PipelineRunList/hooks/useColumns.tsx (202 lines of code) (raw):

import { Icon } from '@iconify/react'; import { Link } from '@kinvolk/headlamp-plugin/lib/components/common'; import { IconButton } from '@mui/material'; import React from 'react'; import { ResourceIconLink } from '../../../components/ResourceIconLink'; import { StatusIcon } from '../../../components/StatusIcon'; import { TableColumn } from '../../../components/Table/types'; import { TextWithTooltip } from '../../../components/TextWithTooltip'; import { ICONS } from '../../../icons/iconify-icons-mapping'; import { PipelineRunKubeObject } from '../../../k8s/groups/Tekton/PipelineRun'; import { PipelineRunKubeObjectInterface } from '../../../k8s/groups/Tekton/PipelineRun/types'; import { getPullRequestURL } from '../../../k8s/groups/Tekton/PipelineRun/utils/getPullRequestURL'; import { routePipelineDetails } from '../../../pages/configuration/pages/pipeline-details/route'; import { routePipelineRunDetails } from '../../../pages/pipeline-details/route'; import { useDialogContext } from '../../../providers/Dialog/hooks'; import { humanize } from '../../../utils/date/humanize'; import { PipelineRunGraphDialog } from '../../dialogs/PipelineRunGraph'; import { Actions } from '../components/Actions'; import { WidgetPermissions } from '../types'; export const useColumns = ({ permissions, }: { permissions: WidgetPermissions; }): TableColumn<PipelineRunKubeObjectInterface>[] => { const { setDialog } = useDialogContext(); return React.useMemo( () => [ { id: 'status', label: 'Status', columnSortableValuePath: 'status.conditions[0].status', render: (resource) => { const status = PipelineRunKubeObject.parseStatus(resource); const reason = PipelineRunKubeObject.parseStatusReason(resource); const [icon, color, isRotating] = PipelineRunKubeObject.getStatusIcon(status, reason); return ( <StatusIcon icon={icon} color={color} isRotating={isRotating} width={25} Title={`Status: ${status}. Reason: ${reason}`} /> ); }, width: '5%', }, { id: 'run', label: 'Run', columnSortableValuePath: 'metadata.name', render: (resource) => { const { metadata: { name, namespace }, } = resource; return ( <Link routeName={routePipelineRunDetails.path} params={{ name, namespace, }} > <TextWithTooltip text={name} /> </Link> ); }, width: '25%', }, { id: 'pipeline', label: 'Pipeline', columnSortableValuePath: 'spec.pipelineRef.name', render: (resource) => { const { metadata: { namespace }, spec: { pipelineRef: { name: pipelineRefName }, }, } = resource; return ( <Link routeName={routePipelineDetails.path} params={{ name: pipelineRefName, namespace, }} > <TextWithTooltip text={pipelineRefName} /> </Link> ); }, width: '25%', }, { id: 'pullRequestUrl', label: 'Pull Request', render: (resource) => { const link = getPullRequestURL(resource); if (!link) { return null; } return ( <ResourceIconLink tooltipTitle={'Go to the Pull Request page'} link={link} icon={ICONS.NEW_WINDOW} name="pull request" /> ); }, width: '10%', textAlign: 'center', }, { id: 'startedAt', label: 'Started at', customSortFn: (a, b) => { const aStartTime = a?.status?.startTime; const bStartTime = b?.status?.startTime; const aStartTimeDate = new Date(aStartTime).getTime(); const bStartTimeDate = new Date(bStartTime).getTime(); if (aStartTimeDate < bStartTimeDate) { return -1; } else if (aStartTimeDate > bStartTimeDate) { return 1; } return 0; }, render: (resource) => { const startedAt = new Date(resource.status?.startTime).toLocaleString('en-mini', { month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', }); return startedAt; }, width: '15%', }, { id: 'time', label: 'Time', customSortFn: (a, b) => { const aStartTime = a?.status?.startTime; const aCompletionTime = a?.status?.completionTime; const bStartTime = b?.status?.startTime; const bCompletionTime = b?.status?.completionTime; const aDurationTime = !!aCompletionTime ? new Date(aCompletionTime).getTime() - new Date(aStartTime).getTime() : new Date().getTime() - new Date(aStartTime).getTime(); const bDurationTime = !!bCompletionTime ? new Date(bCompletionTime).getTime() - new Date(bStartTime).getTime() : new Date().getTime() - new Date(bStartTime).getTime(); if (aDurationTime < bDurationTime) { return -1; } else if (aDurationTime > bDurationTime) { return 1; } return 0; }, render: (resource) => { const completionTime = resource?.status?.completionTime; const durationTime = !!completionTime ? new Date(completionTime).getTime() - new Date(resource.status?.startTime).getTime() : new Date().getTime() - new Date(resource.status?.startTime).getTime(); const activeDuration = humanize(durationTime, { language: 'en-mini', spacer: '', delimiter: ' ', fallbacks: ['en'], largest: 2, round: true, units: ['d', 'h', 'm', 's'], }); return activeDuration; }, width: '10%', }, { id: 'diagram', label: 'Diagram', render: (resource) => { return ( <IconButton onClick={() => setDialog(PipelineRunGraphDialog, { pipelineRun: resource, }) } size="medium" > <Icon icon={ICONS.DIAGRAM} /> </IconButton> ); }, width: '5%', }, { id: 'rerun', label: 'Actions', render: (resource) => <Actions resource={resource} permissions={permissions} />, width: '5%', }, ], [permissions, setDialog] ); };