ImagesTable: Show UUID in expandable details row

This commit displays the UUID in an expandable details row. This is
necessary because if an image was named, the UUID was not displayed.
It is important that a user know the UUID for troubleshooting, for
example in the case of requesting help with an image.

To facilitate this, the original Table component was converted to a
TableComposable component. TableComposable is newer and recommended over
the older Table by PatternFly.
This commit is contained in:
lucasgarfield 2022-04-08 12:05:52 +02:00 committed by Sanne Raymaekers
parent 110c0c674b
commit d7035d544b
3 changed files with 105 additions and 62 deletions

View file

@ -2,13 +2,13 @@ import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Link, useNavigate } from 'react-router-dom';
import { Table, TableHeader, TableBody } from '@patternfly/react-table';
import { TableComposable, Thead, Tr, Th, Tbody, Td, ActionsColumn, ExpandableRowContent } from '@patternfly/react-table';
import { EmptyState, EmptyStateVariant, EmptyStateIcon, EmptyStateBody, EmptyStateSecondaryActions,
Pagination,
Toolbar, ToolbarContent, ToolbarItem,
Title } from '@patternfly/react-core';
import { PlusCircleIcon } from '@patternfly/react-icons';
import './ImagesTable.scss';
import { composesGet, composeGetStatus } from '../../store/actions/actions';
import DocumentationButton from '../sharedComponents/DocumentationButton';
import ImageBuildStatus from './ImageBuildStatus';
@ -20,6 +20,16 @@ const ImagesTable = () => {
const [ page, setPage ] = useState(1);
const [ perPage, setPerPage ] = useState(10);
const [ expandedComposeIds, setExpandedComposeIds ] = useState([]);
const isExpanded = compose => expandedComposeIds.includes(compose.id);
const handleToggle = (compose, isExpanding) => {
if (isExpanding) {
setExpandedComposeIds([ ...expandedComposeIds, compose.id ]);
} else {
setExpandedComposeIds(expandedComposeIds.filter(id => id !== compose.id));
}};
const composes = useSelector((state) => state.composes);
const dispatch = useDispatch();
@ -83,49 +93,19 @@ const ImagesTable = () => {
return tsDisplay;
};
const columns = [
'Image name',
'Created',
'Release',
'Target',
'Status',
'Instance',
''
const actions = (compose) => [
{
title: 'Recreate image',
onClick: () => navigate(
'/imagewizard',
{ state: { composeRequest: compose.request, initialStep: 'review' }}
)
}
];
// the state.page is not an index so must be reduced by 1 get the starting index
const itemsStartInclusive = (page - 1) * perPage;
const itemsEndExlcusive = itemsStartInclusive + perPage;
// only display the current pages section of composes. slice is inclusive, exclusive.
const rows = composes.allIds.slice(itemsStartInclusive, itemsEndExlcusive).map(id => {
const compose = composes.byId[id];
return {
compose,
cells: [
compose.request.image_name || id,
timestampToDisplayString(compose.created_at),
{ title: <Release release={ compose.request.distribution } /> },
{ title: <Target
uploadType={ compose.request.image_requests[0].upload_request.type }
imageType={ compose.request.image_requests[0].image_type } /> },
{ title: <ImageBuildStatus status={ compose.image_status ? compose.image_status.status : '' } /> },
{ title: <ImageLink
imageStatus={ compose.image_status }
imageType={ compose.request.image_requests[0].image_type }
uploadOptions={ compose.request.image_requests[0].upload_request.options } /> }
]
};
});
const actions = [
{
title: 'Recreate image',
onClick: (_event, _rowId, rowData) => navigate(
'/imagewizard',
{ state: { composeRequest: rowData.compose.request, initialStep: 'review' }}
)
}
];
const itemsEndExclusive = itemsStartInclusive + perPage;
return (
<React.Fragment>
@ -170,15 +150,52 @@ const ImagesTable = () => {
</ToolbarItem>
</ToolbarContent>
</Toolbar>
<Table
aria-label="Images"
rows={ rows }
cells={ columns }
actions={ actions }
data-testid="images-table">
<TableHeader />
<TableBody />
</Table>
<TableComposable variant="compact" data-testid="images-table">
<Thead>
<Tr>
<Th />
<Th>Image name</Th>
<Th>Created</Th>
<Th>Release</Th>
<Th>Target</Th>
<Th>Status</Th>
<Th>Instance</Th>
<Th />
</Tr>
</Thead>
{ composes.allIds.slice(itemsStartInclusive, itemsEndExclusive).map((id, rowIndex) => {
const compose = composes.byId[id];
return (
<Tbody key={ id } isExpanded={ isExpanded(compose) }>
<Tr>
<Td expand={ { rowIndex, isExpanded: isExpanded(compose),
onToggle: () => handleToggle(compose, !isExpanded(compose)) } } />
<Td dataLabel="Image name">{compose.request.image_name || id}</Td>
<Td dataLabel="Created">{timestampToDisplayString(compose.created_at)}</Td>
<Td dataLabel="Release"><Release release={ compose.request.distribution } /></Td>
<Td dataLabel="Target"><Target
uploadType={ compose.request.image_requests[0].upload_request.type }
imageType={ compose.request.image_requests[0].image_type } /></Td>
<Td dataLabel="Status"><ImageBuildStatus
status={ compose.image_status ? compose.image_status.status : '' } /></Td>
<Td dataLabel="Instance"><ImageLink
imageStatus={ compose.image_status }
imageType={ compose.request.image_requests[0].image_type }
uploadOptions={ compose.request.image_requests[0].upload_request.options } /></Td>
<Td><ActionsColumn items={ actions(compose) } /></Td>
</Tr>
<Tr isExpanded={ isExpanded(compose) }>
<Td colSpan={ 8 }>
<ExpandableRowContent>
<strong>UUID</strong>
<div>{ id }</div>
</ExpandableRowContent>
</Td>
</Tr>
</Tbody>
);
}) }
</TableComposable>
</React.Fragment>
)}
</React.Fragment>