-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(RHINENG-9248): create bootc tree view (#2178)
* feat(RHINENG-9248): create bootc tree view To test: Log into account with systems with bootc data Go to /insights/inventory url Click the toggle that is right-aligned in the Systems page header From this point, you should see a table with expandable rows. Those expanded rows include specific hash data for each image name. The system counts for the hash commits for the nested table should add up to equal the system counts for the parent image. Please also ensure that the numbers in the system column line up for the table and nested table. * feat: Make suggested updates * feat: Add non bootc system count Adds count of systems without bootc images to the bootc image table. --------- Co-authored-by: Michael Johnson <[email protected]>
- Loading branch information
1 parent
5fc6d2d
commit fd9bff4
Showing
10 changed files
with
303 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import axios from 'axios'; | ||
import { | ||
INVENTORY_FETCH_BOOTC, | ||
INVENTORY_FETCH_NON_BOOTC, | ||
INVENTORY_TOTAL_FETCH_URL_SERVER, | ||
} from '../../Utilities/constants'; | ||
import BifrostTable from './BifrostTable'; | ||
|
||
const BifrostPage = () => { | ||
const [bootcImages, setBootcImages] = useState(); | ||
const [loaded, setLoaded] = useState(false); | ||
|
||
useEffect(() => { | ||
const fetchBootcImages = async () => { | ||
setLoaded(false); | ||
const result = await axios.get( | ||
`${INVENTORY_TOTAL_FETCH_URL_SERVER}${INVENTORY_FETCH_BOOTC}&fields[system_profile]=bootc_status` | ||
); | ||
|
||
const packageBasedSystems = await axios.get( | ||
`${INVENTORY_TOTAL_FETCH_URL_SERVER}${INVENTORY_FETCH_NON_BOOTC}&per_page=1` | ||
); | ||
|
||
const booted = result.data.results.map( | ||
(system) => system.system_profile.bootc_status.booted | ||
); | ||
|
||
const target = {}; | ||
|
||
booted.forEach((bootedImage) => { | ||
const { image, image_digest } = bootedImage; | ||
if (!target[image]) { | ||
target[image] = { | ||
image, | ||
systemCount: 1, | ||
hashes: {}, | ||
hashCommitCount: 0, | ||
}; | ||
} else { | ||
target[image].systemCount += 1; | ||
} | ||
|
||
if (!target[image].hashes[image_digest]) { | ||
target[image].hashes[image_digest] = { | ||
image_digest, | ||
hashSystemCount: 1, | ||
}; | ||
target[image].hashCommitCount += 1; | ||
} else { | ||
target[image].hashes[image_digest].hashSystemCount += 1; | ||
} | ||
}); | ||
|
||
const updated = [ | ||
...Object.values(target).map((val) => ({ | ||
...val, | ||
hashes: Object.values(val.hashes), | ||
})), | ||
{ | ||
image: 'Package based systems', | ||
systemCount: packageBasedSystems.data.total, | ||
hashCommitCount: '-', | ||
}, | ||
]; | ||
|
||
setLoaded(true); | ||
setBootcImages(updated); | ||
}; | ||
|
||
fetchBootcImages(); | ||
}, []); | ||
|
||
return <BifrostTable bootcImages={bootcImages} loaded={loaded} />; | ||
}; | ||
|
||
export default BifrostPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,110 @@ | ||
import React from 'react'; | ||
import React, { useState } from 'react'; | ||
import propTypes from 'prop-types'; | ||
import { | ||
Table, | ||
Thead, | ||
Tr, | ||
Th, | ||
Tbody, | ||
Td, | ||
ExpandableRowContent, | ||
} from '@patternfly/react-table'; | ||
import { SkeletonTable } from '@redhat-cloud-services/frontend-components/SkeletonTable'; | ||
import { imageTableColumns } from './BifrostTableColumns'; | ||
import NestedHashTable from './NestedHashTable'; | ||
import BifrostTableRows from './BifrostTableRows'; | ||
|
||
const BifrostTable = () => { | ||
return <div>Bifrost table will be here</div>; | ||
const BifrostTable = ({ bootcImages, loaded }) => { | ||
const [expandedImageNames, setExpandedImageNames] = useState([]); | ||
|
||
const setImageExpanded = (image, isExpanding = true) => | ||
setExpandedImageNames((prevExpanded) => { | ||
const otherExpandedImageNames = prevExpanded.filter( | ||
(r) => r !== image.image | ||
); | ||
return isExpanding | ||
? [...otherExpandedImageNames, image.image] | ||
: otherExpandedImageNames; | ||
}); | ||
|
||
const isImageExpanded = (image) => expandedImageNames.includes(image.image); | ||
|
||
return ( | ||
<> | ||
{loaded ? ( | ||
<Table aria-label="Bootc image table"> | ||
<Thead> | ||
<Tr> | ||
<Td /> | ||
{imageTableColumns.map((col) => ( | ||
<Th | ||
key={col.title} | ||
colSpan={col.colSpan} | ||
className={col.classname} | ||
> | ||
{col.title} | ||
</Th> | ||
))} | ||
</Tr> | ||
</Thead> | ||
<Tbody> | ||
{bootcImages?.map((image, rowIndex) => ( | ||
<> | ||
<Tr key={image.image}> | ||
{image.hashes ? ( | ||
<Td | ||
expand={{ | ||
rowIndex, | ||
isExpanded: isImageExpanded(image), | ||
onToggle: () => | ||
setImageExpanded(image, !isImageExpanded(image)), | ||
expandId: 'composable-nested-table-expandable-example', | ||
}} | ||
/> | ||
) : ( | ||
<Td /> | ||
)} | ||
{imageTableColumns.map((col) => ( | ||
<BifrostTableRows | ||
key={`${image.image}-${col.title}`} | ||
column={col} | ||
data={image} | ||
/> | ||
))} | ||
</Tr> | ||
{image.hashes ? ( | ||
<Tr isExpanded={isImageExpanded(image)}> | ||
<Td | ||
dataLabel={`${imageTableColumns[0].title} expanded`} | ||
colSpan={12} | ||
style={{ paddingRight: '0px' }} | ||
> | ||
<ExpandableRowContent | ||
style={{ paddingTop: '0px', paddingLeft: '64px' }} | ||
> | ||
<NestedHashTable hashes={image.hashes} /> | ||
</ExpandableRowContent> | ||
</Td> | ||
</Tr> | ||
) : null} | ||
</> | ||
))} | ||
</Tbody> | ||
</Table> | ||
) : ( | ||
<SkeletonTable | ||
columns={imageTableColumns.map(({ title }) => title)} | ||
rows={15} | ||
variant={'compact'} | ||
/> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
BifrostTable.propTypes = { | ||
bootcImages: propTypes.array, | ||
loaded: propTypes.bool, | ||
}; | ||
|
||
export default BifrostTable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const ImageColumn = { | ||
title: 'Image name', | ||
colSpan: 8, | ||
ref: 'image', | ||
}; | ||
|
||
const HashCommitsColumn = { | ||
title: 'Hash commits', | ||
colSpan: 2, | ||
ref: 'hashCommitCount', | ||
}; | ||
|
||
const SystemsColumn = { | ||
title: 'Systems', | ||
colSpan: 2, | ||
ref: 'systemCount', | ||
classname: 'ins-c-inventory__bootc-systems-count-cell', | ||
}; | ||
|
||
const HashCommitColumn = { | ||
title: 'Hash commit', | ||
colSpan: 2, | ||
ref: 'image_digest', | ||
}; | ||
|
||
const HashSystemColumn = { | ||
title: '', | ||
colSpan: 10, | ||
ref: 'hashSystemCount', | ||
classname: 'ins-c-inventory__bootc-systems-count-cell', | ||
}; | ||
|
||
export const imageTableColumns = [ | ||
ImageColumn, | ||
HashCommitsColumn, | ||
SystemsColumn, | ||
]; | ||
|
||
export const hashTableColumns = [HashCommitColumn, HashSystemColumn]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
import propTypes from 'prop-types'; | ||
import { Td } from '@patternfly/react-table'; | ||
|
||
const BifrostTableRows = ({ column, data }) => { | ||
return ( | ||
<Td | ||
dataLabel={column.title} | ||
colSpan={column.colSpan} | ||
className={column.classname} | ||
> | ||
{data[column.ref]} | ||
</Td> | ||
); | ||
}; | ||
|
||
BifrostTableRows.propTypes = { | ||
column: propTypes.object, | ||
data: propTypes.object, | ||
}; | ||
|
||
export default BifrostTableRows; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import propTypes from 'prop-types'; | ||
import { Table, Thead, Tr, Th, Tbody } from '@patternfly/react-table'; | ||
import { hashTableColumns } from './BifrostTableColumns'; | ||
import BifrostTableRows from './BifrostTableRows'; | ||
|
||
const NestedHashTable = ({ hashes }) => { | ||
return ( | ||
<Table aria-label="Image table" variant="compact"> | ||
<Thead> | ||
<Tr> | ||
{hashTableColumns.map((col) => { | ||
return ( | ||
<Th key={col.title} colSpan={col.colSpan}> | ||
{col.title} | ||
</Th> | ||
); | ||
})} | ||
</Tr> | ||
</Thead> | ||
<Tbody> | ||
{hashes.map((hash) => ( | ||
<Tr key={hash.image_digest}> | ||
{hashTableColumns.map((col) => ( | ||
<BifrostTableRows | ||
key={`${hash.image_digest}-${col.title}`} | ||
column={col} | ||
data={hash} | ||
/> | ||
))} | ||
</Tr> | ||
))} | ||
</Tbody> | ||
</Table> | ||
); | ||
}; | ||
|
||
NestedHashTable.propTypes = { | ||
hashes: propTypes.array, | ||
}; | ||
|
||
export default NestedHashTable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters