@patternfly/react-core#Grid JavaScript Examples
The following examples show how to use
@patternfly/react-core#Grid.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ReviewSection.js From edge-frontend with Apache License 2.0 | 6 votes |
ReviewSection = ({ title, data, testid }) => {
return (
<Grid className="pf-u-pb-xl" data-testid={testid} hasGutter>
<GridItem span={12}>
<Text component={TextVariants.h2}>{title}</Text>
</GridItem>
{data.map(({ name, value }) => (
<Grid key={name}>
<GridItem span={3}>
<TextListItem component={TextListItemVariants.dt}>
{name}
</TextListItem>
</GridItem>
<GridItem span={9}>
<TextListItem component={TextListItemVariants.dd}>
{value}
</TextListItem>
</GridItem>
</Grid>
))}
</Grid>
);
}
Example #2
Source File: DeviceSummaryTile.js From edge-frontend with Apache License 2.0 | 5 votes |
DeviceSummaryTileBase = ({ orphaned, active, noReports, neverReported, }) => ( <Card className="tiles-card"> <CardTitle>Device summary</CardTitle> <CardBody> <Grid> <GridItem span={6}> <Stack hasGutter> <StackItem> <Button isDisabled isInline className="pf-u-pr-md" variant="link"> {active} </Button>{' '} Active </StackItem> <StackItem> <Button isDisabled isInline className="pf-u-pr-md" variant="link"> {orphaned} </Button>{' '} Orphaned </StackItem> </Stack> </GridItem> <GridItem span={6}> <Stack hasGutter> <StackItem> <Button isDisabled isInline className="pf-u-pr-md" variant="link"> {noReports} </Button> Stale </StackItem> <StackItem> <Button isDisabled isInline className="pf-u-pr-md" variant="link"> {neverReported} </Button> Registered but never reported </StackItem> </Stack> </GridItem> </Grid> </CardBody> </Card> )
Example #3
Source File: Details.js From malware-detection-frontend with Apache License 2.0 | 5 votes |
Details = () => { const intl = useIntl(); const [isCodeEditorEnabled] = React.useState(false); const { id: sigId } = useParams(); const breadcrumbs = [{ name: intl.formatMessage(messages.malwareDetectionSignatures), to: `${isBeta()}/insights/malware` }, { name: sigId, to: '#' }]; const { data, loading } = useQuery(GET_SIGNATURE_DETAILS_PAGE, { variables: { ruleName: sigId } }); const sigDetailsData = data?.rulesList[0]; const detailBlock = (title, detail) => <React.Fragment> <p className='ins-l-detailBlockHeader'>{title}</p> <p>{detail}</p> </React.Fragment>; return <React.Fragment> <PageHeader> <Breadcrumb items={breadcrumbs} /> <Grid hasGutter> <GridItem md={12} sm={12}> <Title headingLevel='h1' size={TitleSizes['3xl']} >{sigId}</Title> </GridItem> {isCodeEditorEnabled && (<GridItem md={7} sm={12}> { sigDetailsData && <CodeEditor height='250px' code={sigDetailsData.rawRule} isReadOnly isDownloadEnabled isCopyEnabled />} </GridItem>)} {loading ? <Loading /> : <GridItem md={isCodeEditorEnabled && 5 || 12} sm={12}> <Grid hasGutter> <GridItem xl2={isCodeEditorEnabled && 6 || 1} xl={isCodeEditorEnabled && 6 || 3} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.lastmatch), sigDetailsData?.lastMatchDate ? <DateFormat date={new Date(sigDetailsData.lastMatchDate)} type="onlyDate" /> : intl.formatMessage(messages.never))} </GridItem> <GridItem xl2={isCodeEditorEnabled && 6 || 1} xl={isCodeEditorEnabled && 6 || 3} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.hostmatch), <span>{`${sigDetailsData?.affectedHosts?.totalCount}/${data?.hosts?.totalCount}`}</span>)} </GridItem> {isCodeEditorEnabled && <GridItem xl2={6} xl={6} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.description), sigDetailsData?.metadata?.description)} </GridItem>} <GridItem xl2={isCodeEditorEnabled && 6 || 1} xl={isCodeEditorEnabled && 6 || 3} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.enablement), sigDetailsData && <StatusLabel {...sigDetailsData} />)} </GridItem> <GridItem xl2={isCodeEditorEnabled && 6 || 2} xl={isCodeEditorEnabled && 6 || 3} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.author), sigDetailsData?.metadata?.author)} </GridItem> {!isCodeEditorEnabled && <GridItem xl2={7} xl={3} md={6} xs={12}> {detailBlock(intl.formatMessage(messages.description), sigDetailsData?.metadata?.description)} </GridItem>} </Grid> </GridItem> } </Grid> </PageHeader> <Main> <Title className='ins-l-tableBlockHeader' headingLevel='h1' size={TitleSizes['3xl']}> {intl.formatMessage(messages.affectedHosts)} </Title> <SigDetailsTable ruleName={sigId} isEmptyAccount={data?.hosts?.totalCount === 0} affectedCount={sigDetailsData?.affectedHosts?.totalCount} /> </Main> </React.Fragment>; }
Example #4
Source File: Signatures.js From malware-detection-frontend with Apache License 2.0 | 5 votes |
Signatures = () => {
const intl = useIntl();
const sigPageData = useQuery(GET_SIGNATURE_PAGE);
const chartCmpData = useQuery(GET_TIME_SERIES_STATS);
return <React.Fragment>
<PageHeader>
<Split hasGutter isWrappable>
<SplitItem>
<PageHeaderTitle title={(<Popover
enableFlip
position={'right'}
headerContent={intl.formatMessage(messages.headerPopoverTitle)}
bodyContent={(<Grid hasGutter>
<GridItem>{intl.formatMessage(messages.headerPopoverBody1)}</GridItem>
</Grid>)}
footerContent={<a
href={'https://access.redhat.com/documentation/en-us/red_hat_insights/2022/html/' +
'assessing_and_reporting_malware_signatures_on_rhel_systems_with_the_insights_for' +
'_rhel_malware_service/'}
target="__blank" rel="noopener noreferrer">
{intl.formatMessage(messages.headerPopoverFooter)} <ExternalLinkAltIcon />
</a>}
>
<Title headingLevel='h1' size={TitleSizes['3xl']}>
{intl.formatMessage(messages.malwareDetection)}
<OutlinedQuestionCircleIcon
color={'var(--pf-global--secondary-color--100)'}
className="pf-u-ml-sm pointer cves-header-questionmark"
style={{ verticalAlign: '-2' }}
/>
</Title>
</Popover>)} />
</SplitItem>
</Split>
</PageHeader>
<Main>
<Grid hasGutter>
<GridItem lg={6} md={12}>
<Suspense fallback={<Loading />}><StatusCard {...sigPageData} /></Suspense>
</GridItem>
<GridItem lg={6} md={12}>
<Suspense fallback={<Loading />}><ChartCard sysStats={sigPageData} chartStats={chartCmpData}/></Suspense>
</GridItem>
<GridItem span={12}>
<Suspense fallback={<Loading />}><SigTable /></Suspense>
</GridItem>
</Grid>
</Main>
</React.Fragment>;
}
Example #5
Source File: Footer.js From operate-first.github.io-old with GNU General Public License v3.0 | 5 votes |
Footer = () => (
<footer key="footer-2" className="ws-org-pfsite-l-footer-dark pf-m-no-fill">
<Grid className="pf-u-py-xl-on-sm pf-u-py-0-on-md pf-u-align-items-center">
<GridItem md={2} mdOffset={1}>
<Text
component={TextVariants.a}
href="//www.redhat.com"
target="top"
aria-label="Visit Red Hat.com"
>
<img src={redhatLogo} alt="Red Hat logo" width="100px" />
</Text>
</GridItem>
<GridItem md={3}>
<span className="ws-org-pfsite-site-copyright">Operate First is a Red Hat Initiative.</span>
</GridItem>
<GridItem md={6}>
<Text
component={TextVariants.a}
href="//www.redhat.com/en/about/privacy-policy"
target="top"
aria-label="Privacy statement"
>
Privacy statement
</Text>
<Text
component={TextVariants.a}
href="//www.redhat.com/en/about/terms-use"
target="top"
aria-label="Terms of use"
>
Terms of use
</Text>
<Text
component={TextVariants.a}
href="//www.redhat.com/en/about/all-policies-guidelines"
target="top"
aria-label="All policies and guidelines"
>
All policies and guidelines
</Text>
<Text
component={TextVariants.a}
href="//thenounproject.com/exgoya/"
target="top"
aria-label="Operate First Logo Creator"
>
Creator of Operate-First Logo
</Text>
<Text
component={TextVariants.a}
href="//www.openstack.org/legal/community-code-of-conduct/"
target="top"
aria-label="Code of Conduct"
>
Code of Conduct
</Text>
</GridItem>
</Grid>
</footer>
)
Example #6
Source File: Details.js From content-preview with Apache License 2.0 | 4 votes |
Details = ({
match,
fetchContentDetails,
details,
fetchContentDetailsHits,
contentDetailsHits
}) => {
const [selectedListItem, setSelectedListItem] = useState(0);
const capitalize = (string) => string[0].toUpperCase() + string.substring(1);
const [expanded, setExpanded] = useState(true);
const pyFilter = (data) => {
const keysToInclude = Object.keys(data).filter(
(key) => !key.includes('__')
);
const arrayObj = keysToInclude.map((key) => ({ [key]: data[key] }));
return Object.assign({}, ...arrayObj);
};
const selectedPyData =
selectedListItem >= 1 && pyFilter(contentDetailsHits[selectedListItem - 1]);
const detailHref = `https://access.redhat.com/node/${details.node_id}`;
const [freeStyle, setFreeStyle] = useState('');
const [freeStyleValidated, setFreeStyleValidated] = useState('default');
const [validFreeStyle, setValidFreeStyle] = useState('');
const [helperText, setHelperText] = useState('Please enter valid JSON');
const [kbaDetailsData, setLbaDetailsData] = useState({});
const [kbaLoading, setKbaLoading] = useState(true);
const freeStyleChange = (input) => {
let isValid;
const parser = (input) => {
try {
return JSON.parse(input);
} catch (error) {
return false;
}
};
if (input.length > 0) {
const validInput = parser(input);
if (validInput) {
isValid = 'success';
setValidFreeStyle(validInput);
setHelperText('Valid JSON! ?');
} else {
isValid = 'error';
setValidFreeStyle('');
}
} else {
isValid = 'default';
setValidFreeStyle('');
setHelperText('Please enter valid JSON');
}
setFreeStyleValidated(isValid);
setFreeStyle(input);
};
const severityLabelColor = (severity) =>
severity === 'ERROR'
? 'red'
: severity === 'WARN'
? 'orange'
: severity === 'INFO'
? 'purple'
: 'blue';
const fetchKbaDetails = async (kbaId) => {
try {
const kbaDetailsFetch = (
await API.get(
`https://access.redhat.com/hydra/rest/search/kcs?q=id:(${kbaId})&fl=view_uri,id,publishedTitle&rows=1&redhat_client=$ADVISOR`,
{},
{ credentials: 'include' }
)
).data.response.docs;
setLbaDetailsData(kbaDetailsFetch[0]);
setKbaLoading(false);
} catch (error) {
console.error(error, 'KBA fetch failed.');
}
};
const ruleDescription = (data, isGeneric) =>
typeof data === 'string' &&
Boolean(data) && (
<span className={isGeneric && 'genericOverride'}>
<Markdown rehypePlugins={[rehypeRaw, rehypeSanitize]}>{data}</Markdown>
</span>
);
useEffect(() => {
const detailName = { name: match.params.recDetail };
fetchContentDetails(detailName);
fetchContentDetailsHits(detailName);
fetchKbaDetails(details.node_id);
}, [
fetchContentDetails,
match.params.recDetail,
fetchContentDetailsHits,
details.node_id
]);
return (
<Page
breadcrumb={
<Breadcrumb>
<BreadcrumbItem>
<Link to="/preview">Content Preview</Link>
</BreadcrumbItem>
<BreadcrumbHeading to="#">{`${match.params.recDetail}`}</BreadcrumbHeading>
</Breadcrumb>
}
>
<PageHeader>
<Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
<PageHeaderTitle
title={
<>
{details.rule_id || 'loading...'}{' '}
{details.status !== undefined && (
<Label color={details.status === 'active' ? 'green' : 'red'}>
{capitalize(details.status)}
</Label>
)}{' '}
</>
}
/>
<Toolbar>
<HostSelector />
</Toolbar>
</Flex>
</PageHeader>
<PageSection>
<Grid hasGutter>
<GridItem span={6}>
<Stack hasGutter>
<Card>
<CardBody>
<ExpandableSection
toggleText={details.description}
onToggle={() => setExpanded(!expanded)}
isExpanded={expanded}
>
<Stack hasGutter>
<StackItem>
<p>
{`Publish Date: ${details.publish_date} | `}
{details.node_id ? (
<a href={detailHref}>{detailHref}</a>
) : (
<Label variant="outline" color="gray">
No node_id present
</Label>
)}
</p>
{(details.reboot_required ||
details.category ||
details.severity) && (
<LabelGroup>
{details.reboot_required && (
<Label variant="outline" color="gray">
Reboot required
</Label>
)}
{details.category && (
<Label variant="outline" color="gray">
{details.category}
</Label>
)}
{details.severity && (
<Label
variant="outline"
color={severityLabelColor(details.severity)}
>
{details.severity}
</Label>
)}
</LabelGroup>
)}
</StackItem>
<StackItem>
<Stack hasGutter>
<StackItem>
<strong>Name:</strong>
{ruleDescription(details.name)}
</StackItem>
<StackItem>
<strong>Summary:</strong>
{ruleDescription(details.summary)}
</StackItem>
<StackItem>
<strong>Generic:</strong>
{ruleDescription(details.generic, true)}
</StackItem>
</Stack>
</StackItem>
<StackItem>
<Form>
<FormGroup
label="Free Style JSON input:"
type="string"
helperText={helperText}
helperTextInvalid="Not valid JSON"
fieldId="selection"
validated={freeStyleValidated}
>
<TextArea
value={freeStyle}
onChange={freeStyleChange}
isRequired
validated={freeStyleValidated}
aria-label="free style JSON input"
/>
</FormGroup>
</Form>
</StackItem>
</Stack>
</ExpandableSection>
</CardBody>
</Card>
<DataList
className="pyDataList"
aria-label="selectable data list example"
selectedDataListItemId={selectedListItem}
onSelectDataListItem={(id) =>
id !== selectedListItem
? setSelectedListItem(id)
: setSelectedListItem(0)
}
>
{contentDetailsHits.map((item, key) => (
<DataListItem
aria-labelledby="selectable-action-item1"
key={key + 1}
id={key + 1}
>
<DataListItemRow className="overFlow">
<DataListItemCells
dataListCells={[
<DataListCell key="primary content">
<Split hasGutter>
<SplitItem>
<b>{item.__name}</b>
</SplitItem>
<SplitItem>
<Label color="blue">{item.__source}</Label>
</SplitItem>
</Split>
<h5>{item.__date}</h5>
<pre>{JSON.stringify(pyFilter(item), null, 2)}</pre>
</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
))}
</DataList>
</Stack>
</GridItem>
<GridItem span={6}>
<ReportDetails
report={{
...details,
rule: details,
...(selectedPyData && { details: selectedPyData }),
...(validFreeStyle && { details: validFreeStyle }),
resolution: details.resolution
}}
kbaDetail={kbaDetailsData}
kbaLoading={kbaLoading}
/>
</GridItem>
</Grid>
</PageSection>
</Page>
);
}
Example #7
Source File: index.js From dbaas-ui with Apache License 2.0 | 4 votes |
HomePage = () => {
return (
<React.Fragment>
<PageHeader className="dbaas-home-page__header pf-u-p-2xl">
<Grid>
<GridItem sm={12} md={6}>
<Title size="2xl" headingLevel="h1">
Get started with Red Hat OpenShift Database Access
</Title>
<Stack hasGutter>
<StackItem>
<TextContent>
<Text size="lg" className="dbaas-home-page__subtitle">
Add-on service for managed OpenShift
</Text>
<Text>
Easily discover, consume, monitor, and manage databases as a
service on the managed OpenShift Platform. OpenShift
database access helps accelerate your development for
applications that use MongoDB Atlas, Crunchy Bridge and
CockroachDB managed database services.
</Text>
</TextContent>
</StackItem>
<StackItem>
<Button
iconPosition="right"
icon={<ExternalLinkAltIcon />}
component="a"
target="_blank"
variant="secondary"
href="https://access.redhat.com/documentation/en-us/red_hat_openshift_database_access/1/html-single/quick_start_guide/index"
>
Get Started with OpenShift Database Access
</Button>
</StackItem>
</Stack>
</GridItem>
</Grid>
</PageHeader>
<Main className="pf-u-pt-xl pf-u-pb-xl pf-u-pl-2xl pf-u-pr-2xl">
<Title className="pf-u-mb-lg" headingLevel="h2" size="xl">
Demo of OpenShift Database Access
</Title>
<Stack hasGutter>
<StackItem>
<Grid hasGutter>
<GridItem md={6} sm={12}>
<Stack hasGutter>
<StackItem>
<TextContent>
<Text>
<b>For database admins:</b> in this video you’ll learn
how to set up a cloud database service connection on
your OpenShift cluster for self-service consumption by
application developers.
</Text>
</TextContent>
</StackItem>
<StackItem>
<Button
iconPosition="right"
icon={<ExternalLinkAltIcon />}
target="_blank"
component="a"
variant="secondary"
href="https://youtu.be/vDrh3SnciL0"
>
View the demo
</Button>
</StackItem>
</Stack>
</GridItem>
<GridItem md={6} sm={12}>
<iframe
style={{ width: '100%', height: '315px' }}
width="560"
height="315"
src="https://www.youtube.com/embed/vDrh3SnciL0"
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</GridItem>
</Grid>
</StackItem>
<StackItem>
<Grid hasGutter>
<GridItem md={6} sm={12}>
<Stack hasGutter>
<StackItem>
<TextContent>
<Text>
<b>For application developers:</b> in this video, you’ll
learn how to quickly and easily connect your application
to a cloud database service on your OpenShift cluster.
</Text>
</TextContent>
</StackItem>
<StackItem>
<Button
iconPosition="right"
icon={<ExternalLinkAltIcon />}
target="_blank"
component="a"
variant="secondary"
href="https://youtu.be/qWaAwhxwjWs"
>
View the demo
</Button>
</StackItem>
</Stack>
</GridItem>
<GridItem md={6} sm={12}>
<iframe
style={{ width: '100%', height: '315px' }}
width="560"
height="315"
src="https://www.youtube.com/embed/qWaAwhxwjWs"
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</GridItem>
</Grid>
</StackItem>
</Stack>
</Main>
</React.Fragment>
);
}
Example #8
Source File: DeviceDetail.js From edge-frontend with Apache License 2.0 | 4 votes |
DeviceDetail = () => {
const [imageId, setImageId] = useState(null);
const { getRegistry } = useContext(RegistryContext);
const { inventoryId, uuid } = useParams();
const entity = useSelector(({ entityDetails }) => entityDetails?.entity);
const groupName = useSelector(
({ groupsDetailReducer }) => groupsDetailReducer?.name
);
const deviceId = useSelector(
({ entityDetails }) => entityDetails?.entity?.id
);
const [imageData, setImageData] = useState();
const [updateModal, setUpdateModal] = useState({
isOpen: false,
deviceData: null,
});
const [isDeviceStatusLoading, setIsDeviceStatusLoading] = useState(true);
const [reload, setReload] = useState(false);
useEffect(() => {
insights.chrome.registerModule('inventory');
insights.chrome?.hideGlobalFilter?.(true);
insights.chrome.appAction('system-detail');
}, []);
useEffect(() => {
(async () => {
if (!entity?.display_name) {
return;
}
const image_data = await getDeviceHasUpdate(deviceId);
setImageData(image_data);
setIsDeviceStatusLoading(false);
setUpdateModal((prevState) => ({
...prevState,
deviceData: [
{
display_name: entity.display_name,
id: entity.id,
},
],
imageSetId: image_data?.ImageInfo?.Image?.ImageSetID,
}));
setImageId(image_data?.ImageInfo?.Image?.ID);
})();
}, [entity, reload]);
useEffect(() => {
insights?.chrome?.appObjectId?.(inventoryId);
}, [inventoryId]);
return (
<>
<DetailWrapper
hideInvLink
showTags
onLoad={({ mergeWithDetail }) => {
getRegistry().register({
systemProfileStore,
...mergeWithDetail(deviceDetail),
});
}}
>
<PageHeader>
<Breadcrumb ouiaId="systems-list">
<BreadcrumbItem>
<Link to={uuid ? `/groups` : '/inventory'}>
{uuid ? 'Groups' : 'Systems'}
</Link>
</BreadcrumbItem>
{uuid && (
<BreadcrumbItem>
{groupName ? (
<Link to={`/groups/${uuid}`}>{groupName}</Link>
) : (
<Skeleton size={SkeletonSize.xs} />
)}
</BreadcrumbItem>
)}
<BreadcrumbItem isActive>
<div className="ins-c-inventory__detail--breadcrumb-name">
{entity?.display_name || <Skeleton size={SkeletonSize.xs} />}
</div>
</BreadcrumbItem>
</Breadcrumb>
<InventoryDetailHead
fallback=""
actions={[
{
title: 'Update',
isDisabled:
imageData?.UpdateTransactions?.[
imageData?.UpdateTransactions.length - 1
]?.Status === 'BUILDING' ||
imageData?.UpdateTransactions?.[
imageData?.UpdateTransactions.length - 1
]?.Status === 'CREATED' ||
!imageData?.ImageInfo?.UpdatesAvailable?.length > 0 ||
!updateModal.imageSetId,
onClick: () => {
setUpdateModal((prevState) => ({
...prevState,
isOpen: true,
}));
},
},
]}
hideBack
hideInvDrawer
/>
{isDeviceStatusLoading ? (
<Skeleton size={SkeletonSize.xs} />
) : imageData?.UpdateTransactions[
imageData?.UpdateTransactions?.length - 1
]?.Status === 'BUILDING' ||
imageData?.UpdateTransactions[
imageData?.UpdateTransactions?.length - 1
]?.Status === 'CREATED' ? (
<Status type="updating" isLabel={true} className="pf-u-mt-sm" />
) : imageData?.Device?.UpdateAvailable ? (
<Status
type="updateAvailable"
isLabel={true}
className="pf-u-mt-sm"
/>
) : (
<Status type="running" isLabel={true} className="pf-u-mt-sm" />
)}
</PageHeader>
<Grid gutter="md">
<GridItem span={12}>
<DeviceDetailTabs
systemProfile={imageData}
imageId={imageId}
setUpdateModal={setUpdateModal}
setReload={setReload}
/>
</GridItem>
</Grid>
{updateModal.isOpen && (
<Suspense
fallback={
<Bullseye>
<Spinner />
</Bullseye>
}
>
<UpdateDeviceModal
navigateBack={() => {
history.push({ pathname: history.location.pathname });
setUpdateModal((prevState) => {
return {
...prevState,
isOpen: false,
};
});
}}
setUpdateModal={setUpdateModal}
updateModal={updateModal}
refreshTable={() => setReload(true)}
/>
</Suspense>
)}
</DetailWrapper>
</>
);
}
Example #9
Source File: ImageDetailTab.js From edge-frontend with Apache License 2.0 | 4 votes |
ImageDetailTab = ({ imageData, imageVersion }) => {
const [data, setData] = useState({});
useEffect(() => {
imageVersion
? setData(imageVersion)
: setData(imageData?.data?.Data?.images?.[0]);
}, [imageData, imageVersion]);
const createSkeleton = (rows) =>
[...Array(rows * 2)].map((_, key) => <Skeleton width="180px" key={key} />);
const dateFormat = () => <DateFormat date={data?.image?.['CreatedAt']} />;
const detailsMapper = {
Version: 'Version',
Created: () => dateFormat(),
'Type(s)': () =>
data?.image?.['OutputTypes']?.map((outputType, index) => (
<div key={index}>{outputType}</div>
)),
Release: () => distributionMapper?.[data?.image?.['Distribution']],
//Size: 'Size',
Description: 'Description',
};
const userInfoMapper = {
Username: () => data?.image?.Installer?.Username,
'SSH key': () => data?.image?.Installer?.SshKey,
};
const renderAdditionalPackageLink = () => {
return (
<Link
to={`${paths['manage-images']}/${data?.image?.ImageSetID}/versions/${data?.image?.ID}/packages/additional`}
>
{data?.additional_packages}
</Link>
);
};
const renderTotalPackageLink = () => {
return (
<Link
to={`${paths['manage-images']}/${data?.image?.ImageSetID}/versions/${data?.image?.ID}/packages/all`}
>
{data?.packages}
</Link>
);
};
const packageMapper = {
'Total additional packages': renderAdditionalPackageLink,
'Total packages': renderTotalPackageLink,
};
const packageDiffMapper = {
Added: () => data?.update_added,
Removed: () => data?.update_removed,
Updated: () => data?.update_updated,
};
if (data?.image?.Installer?.Checksum) {
detailsMapper['SHA-256 checksum'] = () => data?.image?.Installer?.Checksum;
}
if (data?.image?.Commit?.OSTreeCommit) {
detailsMapper['Ostree commit hash'] = () =>
data?.image?.Commit?.OSTreeCommit;
}
const buildTextList = (labelsToValueMapper) =>
data
? Object.entries(labelsToValueMapper).map(([label, value], index) => {
return (
<Fragment key={index}>
<TextListItem
className="details-label"
component={TextListItemVariants.dt}
>
{label}
</TextListItem>
{label === 'SHA-256 checksum' ||
label === 'Ostree commit hash' ||
(label === 'SSH key' && value()) ? (
<TextListItem component={TextListItemVariants.dd}>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant="expansion"
className="pf-u-text-break-word"
id={`${label
.replace(/\s+/g, '-')
.toLowerCase()}-clipboard-copy`}
>
{typeof value === 'function'
? value() || 'Unavailable'
: data?.image?.[value] || 'Unavailable'}
</ClipboardCopy>
</TextListItem>
) : (
<TextListItem
className="pf-u-text-break-word"
component={TextListItemVariants.dd}
>
{typeof value === 'function'
? value() === 0
? 0
: value() || 'Unavailable'
: data?.image?.[value] || 'Unavailable'}
</TextListItem>
)}
</Fragment>
);
})
: null;
return (
<TextContent className="pf-u-ml-lg pf-u-mt-md">
<Grid span={12}>
<GridItem span={5}>
<Text component={TextVariants.h2}>
{imageVersion ? 'Details' : 'Most recent image'}
</Text>
<TextList component={TextListVariants.dl}>
{buildTextList(detailsMapper) || createSkeleton(6)}
</TextList>
<Text component={TextVariants.h2}>User information </Text>
<TextList component={TextListVariants.dl}>
{buildTextList(userInfoMapper) || createSkeleton(2)}
</TextList>
</GridItem>
<GridItem span={1} />
<GridItem span={6}>
<Text component={TextVariants.h2}>Packages </Text>
<TextList component={TextListVariants.dl}>
{buildTextList(packageMapper) || createSkeleton(3)}
</TextList>
<Text component={TextVariants.h2}>Changes from previous version</Text>
<TextList component={TextListVariants.dl}>
{buildTextList(packageDiffMapper) || createSkeleton(3)}
</TextList>
</GridItem>
</Grid>
</TextContent>
);
}
Example #10
Source File: ClusterHeader.js From ocp-advisor-frontend with Apache License 2.0 | 4 votes |
ClusterHeader = ({ clusterId, clusterData, clusterInfo }) => {
const location = window.location;
const [isOpen, setIsOpen] = useState(false);
const intl = useIntl();
// subscribe to the cluster data query
const {
isUninitialized: isUninitializedCluster,
isFetching: isFetchingCluster,
data: cluster,
} = clusterData;
const {
isUninitialized: isUninitializedInfo,
isFetching: isFetchingInfo,
data: info,
} = clusterInfo;
const redirectOCM = (clusterId) => {
location.assign(
location.origin +
(location.pathname.includes('beta') ? `/beta` : '') +
`/openshift/details/${clusterId}`
);
};
const dropDownItems = [
<DropdownItem key="link" onClick={() => redirectOCM(clusterId)}>
<snap>{intl.formatMessage(messages.clusterDetailsRedirect)}</snap>
</DropdownItem>,
];
return (
<Grid id="cluster-header" md={12} hasGutter>
<GridItem span={8}>
<Title
size="2xl"
headingLevel="h1"
id="cluster-header-title"
ouiaId="cluster-name"
>
{isUninitializedInfo || isFetchingInfo ? (
<Skeleton size="sm" />
) : (
info?.display_name || clusterId
)}
</Title>
</GridItem>
<GridItem span={4} id="cluster-header-dropdown">
<Dropdown
position="right"
onSelect={() => setIsOpen(!isOpen)}
autoFocus={false}
isOpen={isOpen}
toggle={
<DropdownToggle
id="toggle-id-2"
onToggle={(isOpen) => setIsOpen(isOpen)}
>
{intl.formatMessage(messages.dropDownActionSingleCluster)}
</DropdownToggle>
}
dropdownItems={dropDownItems}
/>
</GridItem>
<GridItem>
<Stack>
<StackItem id="cluster-header-uuid">
<span>UUID:</span> <span>{clusterId}</span>
</StackItem>
<StackItem id="cluster-header-last-seen">
<span>{intl.formatMessage(messages.lastSeen)}: </span>
<span>
{isUninitializedCluster || isFetchingCluster ? (
<OneLineLoader />
) : cluster?.report?.meta?.last_checked_at ? (
<DateFormat
date={cluster?.report?.meta?.last_checked_at}
type="exact"
/>
) : (
intl.formatMessage(messages.unknown)
)}
</span>
</StackItem>
</Stack>
</GridItem>
</Grid>
);
}
Example #11
Source File: new-widget-wizard.js From ibutsu-server with MIT License | 4 votes |
render() {
const { widgetTypes, selectedType, selectedTypeId, stepIdReached, isTitleValid, areParamsFilled } = this.state;
const steps = [
{
id: 1,
name: 'Select type',
enableNext: selectedType,
component: (
<Form>
<Title headingLevel="h1" size="xl">Select a widget type</Title>
{widgetTypes.map(widgetType => {
return (
<div key={widgetType.id}>
<Radio id={widgetType.id} value={widgetType.id} label={widgetType.title} description={widgetType.description} isChecked={selectedTypeId === widgetType.id} onChange={this.onSelectType}/>
</div>
);
})}
</Form>
)
},
{
id: 2,
name: 'Set info',
canJumpTo: stepIdReached >= 2,
enableNext: isTitleValid,
component: (
<Form isHorizontal>
<Title headingLevel="h1" size="xl">Set widget information</Title>
<FormGroup label="Title" fieldId="widget-title" helperText="A title for the widget" validated={this.isTitleValid} helperTextInvalid="Please enter a title for this widget" helperTextInvalidIcon={<ExclamationCircleIcon/>} isRequired>
<TextInput type="text" id="widget-title" name="widget-title" value={this.state.title} onChange={this.onTitleChange} validated={this.state.isTitleValid} isRequired />
</FormGroup>
<FormGroup label="Weight" fieldId="widget-weight" helperText="How widgets are ordered on the dashboard">
<TextInput type="number" id="widget-weight" name="widget-weight" value={this.state.weight} onChange={this.onWeightChange} />
</FormGroup>
</Form>
)
},
{
id: 3,
name: 'Set parameters',
canJumpTo: stepIdReached >= 3,
enableNext: areParamsFilled,
component: (
<Form isHorizontal>
<Title headingLevel="h1" size="xl">Set widget parameters</Title>
{!!selectedType && selectedType.params.map(param => {
return (
<React.Fragment key={param.name}>
{(param.type === 'string' || param.type === 'integer' || param.type === 'float') &&
<FormGroup
label={param.name}
fieldId={param.name}
helperText={<Linkify componentDecorator={linkifyDecorator}>{param.description}</Linkify>}
isRequired={param.required}>
<TextInput
value={this.state.params[param.name]}
type={(param.type === 'integer' || param.type === 'float') ? 'number' : 'text'}
id={param.name}
aria-describedby={`${param.name}-helper`}
name={param.name}
onChange={this.onParamChange}
isRequired={param.required}
/>
</FormGroup>
}
{param.type === 'boolean' &&
<FormGroup
label={param.name}
fieldId={param.name}
isRequired={param.required}
hasNoPaddingTop>
<Checkbox
isChecked={this.state.params[param.name]}
onChange={this.onParamChange}
id={param.name}
name={param.name}
label={param.description} />
</FormGroup>
}
{param.type === 'list' &&
<FormGroup
label={param.name}
fieldId={param.name}
helperText={`${param.description}. Place items on separate lines.`}>
isRequired={param.required}
<TextArea
id={param.name}
name={param.name}
isRequired={param.required}
value={this.state.params[param.name]}
onChange={this.onParamChange}
resizeOrientation='vertical' />
</FormGroup>
}
</React.Fragment>
);
})}
</Form>
)
},
{
id: 4,
name: 'Review details',
canJumpTo: stepIdReached >= 4,
nextButtonText: 'Finish',
component: (
<Stack hasGutter>
<StackItem>
<Title headingLevel="h1" size="xl">Review details</Title>
</StackItem>
<StackItem>
<Grid hasGutter>
<GridItem span="2">
<Title headingLevel="h4">Title</Title>
</GridItem>
<GridItem span="10">
<TextContent><Text>{this.state.title}</Text></TextContent>
</GridItem>
<GridItem span="2">
<Title headingLevel="h4">Weight</Title>
</GridItem>
<GridItem span="10">
<TextContent><Text>{this.state.weight}</Text></TextContent>
</GridItem>
<GridItem span="2">
<Title headingLevel="h4">Parameters</Title>
</GridItem>
<GridItem span="10">
<Table
cells={["Name", "Value"]}
variant="compact"
borders="compactBorderless"
rows={Object.entries(this.state.params).map(param => { return [param[0], param[1].toString()]; })}
aria-label="Parameters">
<TableHeader />
<TableBody />
</Table>
</GridItem>
</Grid>
</StackItem>
</Stack>
)
}
];
return (
<Modal
isOpen={this.props.isOpen}
variant={ModalVariant.large}
showClose={false}
onClose={this.onClose}
hasNoBodyWrapper
aria-describedby="add-widget-description"
aria-labelledby="add-widget-title"
>
<Wizard
titleId="add-widget-title"
descriptionId="add-widget-description"
title="Add Widget"
description="Add a widget to the current dashboard"
steps={steps}
onNext={this.onNext}
onSave={this.onSave}
onClose={this.onClose}
height={400}
/>
</Modal>
);
}
Example #12
Source File: dashboard.js From ibutsu-server with MIT License | 4 votes |
render() {
document.title = 'Dashboard | Ibutsu';
const { widgets } = this.state;
const project = getActiveProject();
const dashboard = getActiveDashboard();
return (
<React.Fragment>
<PageSection variant={PageSectionVariants.light}>
<Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
<Flex>
<FlexItem spacer={{ default: 'spacerLg' }}>
<TextContent>
<Text component="h1">Dashboard</Text>
</TextContent>
</FlexItem>
<FlexItem id="dashboard-selector" spacer={{ default: 'spacerNone' }}>
<Select
ariaLabelTypeAhead="Select a dashboard"
placeholderText="No active dashboard"
variant={SelectVariant.typeahead}
isOpen={this.state.isDashboardSelectorOpen}
isDisabled={!project}
selections={this.state.selectedDashboard}
onToggle={this.onDashboardToggle}
onSelect={this.onDashboardSelect}
onClear={this.onDashboardClear}
onTypeaheadInputChanged={this.onDashboardChanged}
footer={this.state.dashboards.length == 10 && "Search for more..."}
isPlain
>
{this.state.dashboards.map(dash => (
<SelectOption key={dash.id} value={dashboardToSelect(dash)} />
))}
</Select>
</FlexItem>
<FlexItem spacer={{ default: 'spacerNone' }}>
<Button
aria-label="New dashboard"
variant="plain"
title="New dashboard"
isDisabled={!project}
onClick={this.onNewDashboardClick}
>
<PlusCircleIcon />
</Button>
</FlexItem>
<FlexItem>
<Button
aria-label="Delete dashboard"
variant="plain"
title="Delete dashboard"
isDisabled={!dashboard}
onClick={this.onDeleteDashboardClick}
>
<TimesCircleIcon />
</Button>
</FlexItem>
</Flex>
<Flex>
<FlexItem>
<Button
aria-label="Add widget"
variant="secondary"
title="Add widget"
isDisabled={!this.state.selectedDashboard}
onClick={this.onAddWidgetClick}
>
<PlusCircleIcon /> Add Widget
</Button>
</FlexItem>
</Flex>
</Flex>
</PageSection>
<PageSection>
{!!project && !!dashboard && !!widgets &&
<Grid hasGutter>
{widgets.map(widget => {
if (KNOWN_WIDGETS.includes(widget.widget)) {
return (
<GridItem xl={4} lg={6} md={12} key={widget.id}>
{(widget.type === "widget" && widget.widget === "jenkins-heatmap") &&
<JenkinsHeatmapWidget
title={widget.title}
params={widget.params}
includeAnalysisLink={true}
onDeleteClick={() => this.onDeleteWidgetClick(widget.id)}
/>
}
{(widget.type === "widget" && widget.widget === "run-aggregator") &&
<GenericBarWidget
title={widget.title}
params={widget.params}
horizontal={true}
percentData={true}
barWidth={20}
onDeleteClick={() => this.onDeleteWidgetClick(widget.id)}
/>
}
{(widget.type === "widget" && widget.widget === "result-summary") &&
<ResultSummaryWidget
title={widget.title}
params={widget.params}
onDeleteClick={() => this.onDeleteWidgetClick(widget.id)}
/>
}
{(widget.type === "widget" && widget.widget === "result-aggregator") &&
<ResultAggregatorWidget
title={widget.title}
params={widget.params}
onDeleteClick={() => this.onDeleteWidgetClick(widget.id)}
/>
}
</GridItem>
);
}
else {
return '';
}
})}
</Grid>
}
{!project &&
<EmptyState>
<EmptyStateIcon icon={ArchiveIcon} />
<Title headingLevel="h4" size="lg">
No Project Selected
</Title>
<EmptyStateBody>
There is currently no project selected. Please select a project from the dropdown in
order to view the dashboard.
</EmptyStateBody>
</EmptyState>
}
{!!project && !dashboard &&
<EmptyState>
<EmptyStateIcon icon={TachometerAltIcon} />
<Title headingLevel="h4" size="lg">
No Dashboard Selected
</Title>
<EmptyStateBody>
There is currently no dashboard selected. Please select a dashboard from the dropdown
in order to view widgets, or create a new dashboard.
</EmptyStateBody>
<Button variant="primary" onClick={this.onNewDashboardClick}>New Dashboard</Button>
</EmptyState>
}
{(!!project && !!dashboard && widgets.length === 0) &&
<EmptyState>
<EmptyStateIcon icon={CubesIcon} />
<Title headingLevel="h4" size="lg">
No Widgets
</Title>
<EmptyStateBody>
This dashboard currently has no widgets defined.<br />Click on the "Add Widget" button
below to add a widget to this dashboard.
</EmptyStateBody>
<Button variant="primary" onClick={this.onAddWidgetClick}>Add Widget</Button>
</EmptyState>
}
</PageSection>
<NewDashboardModal
project={project}
isOpen={this.state.isNewDashboardOpen}
onSave={this.onNewDashboardSave}
onClose={this.onNewDashboardClose}
/>
<NewWidgetWizard
dashboard={dashboard}
isOpen={this.state.isWidgetWizardOpen}
onSave={this.onNewWidgetSave}
onClose={this.onNewWidgetClose}
/>
<DeleteModal
title="Delete dashboard"
body={<>Would you like to delete the current dashboard? <strong>ALL WIDGETS</strong> on the dashboard will also be deleted.</>}
isOpen={this.state.isDeleteDashboardOpen}
onDelete={this.onDeleteDashboard}
onClose={this.onDeleteDashboardClose}
/>
<DeleteModal
title="Delete widget"
body="Would you like to delete the selected widget?"
isOpen={this.state.isDeleteWidgetOpen}
onDelete={this.onDeleteWidget}
onClose={this.onDeleteWidgetClose}
/>
</React.Fragment>
);
}
Example #13
Source File: run.js From ibutsu-server with MIT License | 4 votes |
render() {
let passed = 0, failed = 0, errors = 0, xfailed = 0, xpassed = 0, skipped = 0, not_run = 0;
let created = 0;
let calculatePasses = true;
const { run, columns, rows, classificationTable, artifactTabs } = this.state;
const jsonViewTheme = getTheme() === 'dark' ? 'tomorrow' : 'rjv-default';
if (run.start_time) {
created = new Date(run.start_time);
}
else {
created = new Date(run.created);
}
if (run.summary) {
if (run.summary.passes) {
passed = run.summary.passes;
calculatePasses = false;
}
if (run.summary.tests && calculatePasses) {
passed = run.summary.tests;
}
if (run.summary.failures) {
passed -= calculatePasses ? run.summary.failures : 0;
failed = run.summary.failures;
}
if (run.summary.errors) {
passed -= calculatePasses ? run.summary.errors : 0;
errors = run.summary.errors;
}
if (run.summary.xfailures) {
passed -= calculatePasses ? run.summary.xfailures : 0;
xfailed = run.summary.xfailures;
}
if (run.summary.xpasses) {
passed -= calculatePasses ? run.summary.xpasses : 0;
xpassed = run.summary.xpasses;
}
if (run.summary.skips) {
passed -= calculatePasses ? run.summary.skips : 0;
skipped = run.summary.skips;
}
if (run.summary.not_run) {
not_run = run.summary.not_run;
}
else if (run.summary.collected) {
not_run = run.summary.collected - run.summary.tests;
}
}
const pagination = {
pageSize: this.state.pageSize,
page: this.state.page,
totalItems: this.state.totalItems
}
return (
<React.Fragment>
<PageSection variant={PageSectionVariants.light}>
<TextContent>
<Text component="h1" className="pf-c-title">Run {run.id}</Text>
</TextContent>
</PageSection>
<PageSection>
{!this.state.isRunValid &&
<EmptyObject headingText="Run not found" returnLink="/runs" returnLinkText="Return to runs list" />
}
{this.state.isRunValid &&
<Tabs activeKey={this.state.activeTab} onSelect={this.onTabSelect} isBox>
<Tab eventKey={'summary'} title={<TabTitle icon={InfoCircleIcon} text="Summary" />}>
<Card>
<CardBody style={{padding: 0}} id="run-detail">
<Grid style={{backgroundColor: '#fff'}}>
<GridItem span={6}>
<DataList selectedDataListItemId={null} aria-label="Run properties" style={{borderBottom: 'none', borderTop: 'none'}}>
<DataListItem aria-labelledby="Duration">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Duration:</strong></DataListCell>,
<DataListCell key={2} width={4}>{round(run.duration)}s</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Started">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Started:</strong></DataListCell>,
<DataListCell key={2} width={4}>{created.toLocaleString()}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
{run.metadata && run.metadata.component &&
<DataListItem aria-labelledby="Component">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Component:</strong></DataListCell>,
<DataListCell key={2} width={4}>{run.metadata.component}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
}
{run.metadata && run.metadata.env &&
<DataListItem aria-labelledby="Environment">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Environment:</strong></DataListCell>,
<DataListCell key={2} width={4}>{run.metadata.env}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
}
{run.metadata && run.metadata.tags &&
<DataListItem aria-labelledby="tags-label">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key="tags-label" width={2}><strong>Tags:</strong></DataListCell>,
<DataListCell key="tags-data" width={4}>
<Flex>
{run.metadata.tags.map((tag) => <FlexItem spacer={{ default: 'spacerXs' }} key={tag}><Label color="blue" variant="filled">{tag}</Label></FlexItem>)}
</Flex>
</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
}
{run.metadata && run.metadata.jenkins && run.metadata.jenkins.job_name &&
<DataListItem aria-labelledby="Jenkins Job Name">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Jenkins Job Name:</strong></DataListCell>,
<DataListCell key={2} width={4}>{run.metadata.jenkins.job_name}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
}
{run.source &&
<DataListItem aria-labelledby="Source">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1} width={2}><strong>Source:</strong></DataListCell>,
<DataListCell key={2} width={4}>{run.source}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
}
</DataList>
</GridItem>
<GridItem span={6}>
<DataList selectedDataListItemId={null} aria-label="Summary properties" style={{borderBottom: 0, borderTop: 0}}>
<DataListItem aria-labelledby="Summary">
<DataListItemRow>
<DataListItemCells
style={{paddingBottom: 0}}
dataListCells={[
<DataListCell key={1} width={2}><strong>Summary:</strong></DataListCell>,
<DataListCell key={2} width={4} style={{paddingTop: 0}}>
<DataList selectedDataListItemId={null} aria-label="Summary" style={{borderBottom: 0, borderTop: 0}}>
<DataListItem aria-labelledby="Total">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Total:</DataListCell>,
<DataListCell key={2}>{run.summary.collected ? run.summary.collected : run.summary.tests}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Passed">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Passed:</DataListCell>,
<DataListCell key={2}>{passed}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Failed">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Failed:</DataListCell>,
<DataListCell key={2}>{failed}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Error">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Error:</DataListCell>,
<DataListCell key={2}>{errors}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Xfailed">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Xfailed:</DataListCell>,
<DataListCell key={2}>{xfailed}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Xpassed">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Xpassed:</DataListCell>,
<DataListCell key={2}>{xpassed}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Skipped">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Skipped:</DataListCell>,
<DataListCell key={2}>{skipped}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
<DataListItem aria-labelledby="Not Run">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={1}>Not Run:</DataListCell>,
<DataListCell key={2}>{not_run}</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
</DataList>
</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
</DataList>
</GridItem>
</Grid>
</CardBody>
</Card>
</Tab>
<Tab eventKey={'results-list'} title={<TabTitle icon={CatalogIcon} text="Results List" />}>
<Card className="pf-u-mt-lg">
<CardHeader>
<Flex style={{ width: '100%' }}>
<FlexItem grow={{ default: 'grow' }}>
<TextContent>
<Text component="h2" className="pf-c-title pf-m-xl">Test Results</Text>
</TextContent>
</FlexItem>
<FlexItem>
<Button variant="secondary" onClick={this.refreshResults}>Refresh results</Button>
</FlexItem>
<FlexItem>
<Link to={`/results?run_id[eq]=${run.id}`} className="pf-c-button pf-m-primary" style={{marginLeft: '2px'}}>See all results <ChevronRightIcon /></Link>
</FlexItem>
</Flex>
</CardHeader>
<CardBody>
<FilterTable
columns={columns}
rows={rows}
pagination={pagination}
isEmpty={this.state.isEmpty}
isError={this.state.isError}
onSetPage={this.setPage}
onSetPageSize={this.pageSizeSelect}
/>
</CardBody>
</Card>
</Tab>
<Tab eventKey={'results-tree'} title={<TabTitle icon={RepositoryIcon} text="Results Tree" />}>
<Card className="pf-u-mt-lg">
<CardBody>
<Grid gutter="sm">
{false && <GridItem span={12}>
<div style={{paddingTop: "1em"}}>
<TextInput value={this.state.treeSearch} type="text" onChange={this.onSearch} placeholder="Search tree..." aria-label="Filter tree" />
</div>
</GridItem>
}
{this.state.resultsTree.core.data.length === 0 &&
<GridItem span={12}>
<Bullseye><center><Spinner size="xl"/></center></Bullseye>
</GridItem>
}
{this.state.resultsTree.core.data !== 0 &&
<React.Fragment>
<GridItem span={5}>
<TreeView treeData={this.state.resultsTree} onChange={(e, data) => this.handleJSTreeChange(e, data)}/>
</GridItem>
<GridItem span={7}>
{this.state.testResult &&
<Card className={this.state.testResult.result}>
<CardHeader>
{this.state.testResult.test_id}
{this.state.testResult.metadata.markers &&
<div style={{float: 'right'}}>
{this.state.testResult.metadata.markers.map((marker) => {
return <Badge isRead key={marker.name}>{marker.name}</Badge>;
})}
</div>
}
</CardHeader>
<CardBody style={{backgroundColor: "var(--pf-c-page__main-section--BackgroundColor)", paddingTop: "1.2em"}}>
<ResultView testResult={this.state.testResult}/>
</CardBody>
</Card>
}
</GridItem>
</React.Fragment>
}
</Grid>
</CardBody>
</Card>
</Tab>
<Tab eventKey={'classify-failures'} title={<TabTitle icon={MessagesIcon} text="Classify Failures" />}>
{classificationTable}
</Tab>
{artifactTabs}
<Tab eventKey={'run-object'} title={<TabTitle icon={CodeIcon} text="Run Object" />}>
<Card>
<CardBody>
<ReactJson src={run} name={null} iconStyle={"triangle"} collapseStringsAfterLength={120} enableClipboard={false} displayDataTypes={false} theme={jsonViewTheme} />
</CardBody>
</Card>
</Tab>
</Tabs>
}
</PageSection>
</React.Fragment>
);
}