-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pipelines-output): add pipelinerun output tab component
- Loading branch information
1 parent
24fca48
commit 7459aee
Showing
93 changed files
with
9,160 additions
and
1,455 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import '@patternfly/react-core/dist/styles/base.css'; | ||
import { AdvancedClusterSecurity } from '@aonic-ui/pipelines/src'; | ||
import { | ||
acsDeploymentCheck, | ||
acsImageCheckResults, | ||
acsImageScanResult, | ||
} from '@aonic-ui/pipelines/src/components/Output/data'; | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export | ||
const meta = { | ||
title: 'Pipelines/Output/Cards/AdvancedClusterSecurity', | ||
component: AdvancedClusterSecurity, | ||
parameters: { | ||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout | ||
layout: 'padded', | ||
}, | ||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs | ||
tags: ['autodocs'], | ||
// More on argTypes: https://storybook.js.org/docs/api/argtypes | ||
argTypes: {}, | ||
} satisfies Meta<typeof AdvancedClusterSecurity>; | ||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const ACSCard: Story = { | ||
args: { | ||
acsImageCheckResults: acsImageCheckResults, | ||
acsImageScanResult: acsImageScanResult, | ||
acsDeploymentCheckResults: acsDeploymentCheck, | ||
}, | ||
parameters: {}, | ||
}; |
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,31 @@ | ||
import '@patternfly/react-core/dist/styles/base.css'; | ||
import { EnterpriseContract } from '@aonic-ui/pipelines/src'; | ||
import { mockEnterpriseContractUIData } from '@aonic-ui/pipelines/src/components/Output/data'; | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export | ||
const meta = { | ||
title: 'Pipelines/Output/Cards/EnterpriseContract', | ||
component: EnterpriseContract, | ||
parameters: { | ||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout | ||
layout: 'padded', | ||
}, | ||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs | ||
tags: ['autodocs'], | ||
// More on argTypes: https://storybook.js.org/docs/api/argtypes | ||
argTypes: { | ||
enterpriseContractPolicies: {}, | ||
}, | ||
} satisfies Meta<typeof EnterpriseContract>; | ||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const ECCard: Story = { | ||
args: { | ||
enterpriseContractPolicies: mockEnterpriseContractUIData, | ||
}, | ||
parameters: {}, | ||
}; |
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,73 @@ | ||
import '@patternfly/react-core/dist/styles/base.css'; | ||
import { Output } from '@aonic-ui/pipelines/src'; | ||
import { | ||
acsDeploymentCheck, | ||
acsImageCheckResults, | ||
acsImageScanResult, | ||
mockEnterpriseContractJSON, | ||
Check warning on line 7 in docs/stories/pipelines/Output.stories.tsx GitHub Actions / Test
|
||
mockEnterpriseContractUIData, | ||
} from '@aonic-ui/pipelines/src/components/Output/data'; | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export | ||
const meta = { | ||
title: 'Pipelines/Output', | ||
component: Output, | ||
parameters: { | ||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout | ||
layout: 'padded', | ||
}, | ||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs | ||
tags: ['autodocs'], | ||
// More on argTypes: https://storybook.js.org/docs/api/argtypes | ||
argTypes: { | ||
pipelineRunStatus: { control: 'select', options: ['Failed', 'Succeeded'] }, | ||
}, | ||
} satisfies Meta<typeof Output>; | ||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const OutputTab: Story = { | ||
args: { | ||
enterpriseContractPolicies: mockEnterpriseContractUIData, | ||
acsImageScanResult: acsImageScanResult, | ||
acsImageCheckResults: acsImageCheckResults, | ||
acsDeploymentCheckResults: acsDeploymentCheck, | ||
results: [{ name: 'result-1', value: 'value' }], | ||
pipelineRunName: 'pipelineRunName', | ||
pipelineRunStatus: 'Succeeded', | ||
}, | ||
parameters: {}, | ||
}; | ||
|
||
export const OutputTabEC: Story = { | ||
args: { | ||
enterpriseContractPolicies: mockEnterpriseContractUIData, | ||
results: [{ name: 'result-1', value: 'value' }], | ||
pipelineRunName: 'pipelineRunName', | ||
pipelineRunStatus: 'Succeeded', | ||
}, | ||
parameters: {}, | ||
}; | ||
|
||
export const OutputTabACS: Story = { | ||
args: { | ||
acsImageScanResult: acsImageScanResult, | ||
acsImageCheckResults: acsImageCheckResults, | ||
acsDeploymentCheckResults: acsDeploymentCheck, | ||
results: [{ name: 'result-1', value: 'value' }], | ||
pipelineRunName: 'pipelineRunName', | ||
pipelineRunStatus: 'Succeeded', | ||
}, | ||
parameters: {}, | ||
}; | ||
|
||
export const OutputTabResults: Story = { | ||
args: { | ||
results: [{ name: 'result-1', value: 'value' }], | ||
pipelineRunName: 'pipelineRunName', | ||
pipelineRunStatus: 'Succeeded', | ||
}, | ||
parameters: {}, | ||
}; |
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,37 @@ | ||
import '@patternfly/react-core/dist/styles/base.css'; | ||
import { ResultsList } from '@aonic-ui/pipelines/src'; | ||
import { acsImageCheckResults } from '@aonic-ui/pipelines/src/components/Output/data'; | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export | ||
const meta = { | ||
title: 'Pipelines/Output/Cards/Others', | ||
component: ResultsList, | ||
parameters: { | ||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout | ||
layout: 'padded', | ||
}, | ||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs | ||
tags: ['autodocs'], | ||
// More on argTypes: https://storybook.js.org/docs/api/argtypes | ||
argTypes: {}, | ||
} satisfies Meta<typeof ResultsList>; | ||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const OtherTab: Story = { | ||
args: { | ||
results: [ | ||
{ name: 'result-key', value: 'results-value' }, | ||
{ name: 'result-key-2', value: 'http://www.google.com' }, | ||
{ | ||
name: 'result-key-3', | ||
value: JSON.stringify(acsImageCheckResults), | ||
}, | ||
], | ||
pipelineRunName: 'pipelinerun-name', | ||
pipelineRunStatus: 'Succeeded', | ||
}, | ||
parameters: {}, | ||
}; |
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,7 @@ | ||
module.exports = { | ||
presets: [ | ||
"@babel/preset-env", | ||
"@babel/preset-react", | ||
["@babel/preset-react", { runtime: 'automatic' }], | ||
"@babel/preset-typescript", | ||
], | ||
}; |
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,80 @@ | ||
import * as React from 'react'; | ||
import OutputTabCard from './OutputTabCard'; | ||
import AdvancedClusterSecurity from './Tabs/AdvancedClusterSecurity/AdvancedClusterSecurity'; | ||
import EnterpriseContract from './Tabs/EnterpriseContract/EnterpriseContract'; | ||
import ResultsList, { ResultsListProps } from './Tabs/Others/ResultsList'; | ||
import { ACSCheckResults, ACSImageScanResult, EnterpriseContractPolicy } from './types'; | ||
import { getACSCheckIssues } from './utils/acs-image-check-utils'; | ||
import { getImageScanIssues } from './utils/acs-image-scan-utils'; | ||
import { getEnterpriseContractStatus } from './utils/ec-utils'; | ||
import { isEmpty } from './utils/helper-utils'; | ||
import { getACStatusLabel, getECStatusLabel } from './utils/summary-utils'; | ||
|
||
type OutputTabProps = { | ||
enterpriseContractPolicies?: EnterpriseContractPolicy[]; | ||
acsImageScanResult?: ACSImageScanResult; | ||
acsImageCheckResults?: ACSCheckResults; | ||
acsDeploymentCheckResults?: ACSCheckResults; | ||
} & ResultsListProps; | ||
|
||
const OutputTab: React.FC<OutputTabProps> = ({ | ||
enterpriseContractPolicies = [], | ||
acsImageCheckResults = {} as ACSCheckResults, | ||
acsImageScanResult = {} as ACSImageScanResult, | ||
acsDeploymentCheckResults = {} as ACSCheckResults, | ||
results, | ||
pipelineRunName, | ||
pipelineRunStatus, | ||
}) => { | ||
const acsIssuesFound = | ||
getImageScanIssues(acsImageScanResult) || | ||
getACSCheckIssues(acsImageCheckResults, acsDeploymentCheckResults); | ||
|
||
const showECCard = enterpriseContractPolicies?.length > 0; | ||
const showACSCard = | ||
[acsImageScanResult, acsImageCheckResults, acsDeploymentCheckResults].filter((a) => !isEmpty(a)) | ||
.length > 0; | ||
|
||
const showOnlyResults = !showECCard && !showACSCard; | ||
const ResultsComponent = () => ( | ||
<ResultsList | ||
results={results} | ||
pipelineRunName={pipelineRunName} | ||
pipelineRunStatus={pipelineRunStatus} | ||
/> | ||
); | ||
return ( | ||
<> | ||
{showECCard && ( | ||
<OutputTabCard | ||
title="Enterprise Contract" | ||
badge={getECStatusLabel(getEnterpriseContractStatus(enterpriseContractPolicies))} | ||
isOpen={true} | ||
> | ||
<EnterpriseContract enterpriseContractPolicies={enterpriseContractPolicies} /> | ||
</OutputTabCard> | ||
)} | ||
{showACSCard && ( | ||
<OutputTabCard | ||
title="Advanced Cluster Security" | ||
badge={getACStatusLabel(acsIssuesFound)} | ||
isOpen={!showECCard} | ||
> | ||
<AdvancedClusterSecurity | ||
acsImageScanResult={acsImageScanResult} | ||
acsImageCheckResults={acsImageCheckResults} | ||
acsDeploymentCheckResults={acsDeploymentCheckResults} | ||
/> | ||
</OutputTabCard> | ||
)} | ||
{results.length > 0 && showOnlyResults ? ( | ||
<ResultsComponent data-testid="ec" /> | ||
) : results.length > 0 ? ( | ||
<OutputTabCard data-testid="results-card" title="Others" isOpen={showOnlyResults}> | ||
<ResultsComponent /> | ||
</OutputTabCard> | ||
) : null} | ||
</> | ||
); | ||
}; | ||
export default OutputTab; |
47 changes: 47 additions & 0 deletions
47
packages/pipelines/src/components/Output/OutputTabCard.tsx
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,47 @@ | ||
import * as React from 'react'; | ||
import { | ||
Card, | ||
CardBody, | ||
CardExpandableContent, | ||
CardHeader, | ||
CardTitle, | ||
Flex, | ||
FlexItem, | ||
} from '@patternfly/react-core'; | ||
|
||
type OutputTabCardProps = { | ||
title: string; | ||
isOpen?: boolean; | ||
badge?: React.ReactNode; | ||
children: React.ReactNode; | ||
}; | ||
const OutputTabCard: React.FC<OutputTabCardProps> = ({ title, badge, isOpen, children }) => { | ||
const [tabOpen, setTabOpen] = React.useState<boolean>(isOpen ?? false); | ||
const id = title?.replace(/\//g, '-')?.toLowerCase(); | ||
|
||
return ( | ||
<Card id={id} isExpanded={tabOpen}> | ||
<CardHeader | ||
onExpand={() => setTabOpen((open) => !open)} | ||
isToggleRightAligned={false} | ||
toggleButtonProps={{ | ||
id: `${id}-toggle-button`, | ||
'aria-label': title, | ||
'aria-labelledby': `${id}-toggle-button`, | ||
'aria-expanded': tabOpen, | ||
}} | ||
> | ||
<CardTitle id={`{${id}-title}`}> | ||
<Flex gap={{ default: 'gapSm' }}> | ||
<FlexItem data-testid="card-title">{title}</FlexItem> | ||
<FlexItem data-testid="card-badge">{badge}</FlexItem> | ||
</Flex> | ||
</CardTitle> | ||
</CardHeader> | ||
<CardExpandableContent> | ||
<CardBody>{children}</CardBody> | ||
</CardExpandableContent> | ||
</Card> | ||
); | ||
}; | ||
export default OutputTabCard; |
Oops, something went wrong.