diff --git a/.tekton/vulnerability-ui-pull-request.yaml b/.tekton/vulnerability-ui-pull-request.yaml index dd4c042da..892d1eeae 100644 --- a/.tekton/vulnerability-ui-pull-request.yaml +++ b/.tekton/vulnerability-ui-pull-request.yaml @@ -46,7 +46,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:9bfc6b99ef038800fe131d7b45ff3cd4da3a415dd536f7c657b3527b01c4a13b + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:945a7c9066d3e0a95d3fddb7e8a6992e4d632a2a75d8f3a9bd2ff2fef0ec9aa0 - name: kind value: task resolver: bundles @@ -65,7 +65,7 @@ spec: - name: name value: summary - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:d97c04ab42f277b1103eb6f3a053b247849f4f5b3237ea302a8ecada3b24e15b + value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:870d9a04d9784840a90b7bf6817cd0d0c4edfcda04b1ba1868cae625a3c3bfcc - name: kind value: task resolver: bundles @@ -156,7 +156,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:092c113b614f6551113f17605ae9cb7e822aa704d07f0e37ed209da23ce392cc + value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:0523b51c28375a3f222da91690e22eff11888ebc98a0c73c468af44762265c69 - name: kind value: task resolver: bundles @@ -173,7 +173,7 @@ spec: - name: name value: git-clone - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:2cccdf8729ad4d5adf65e8b66464f8efa1e1c87ba16d343b4a6c621a2a40f7e1 + value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:d091a9e19567a4cbdc5acd57903c71ba71dc51d749a4ba7477e689608851e981 - name: kind value: task resolver: bundles @@ -198,7 +198,7 @@ spec: - name: name value: prefetch-dependencies - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:fe7234e3824d1e65d6a7aac352e7a6bbce623d90d8d7da9aceeee108ad2c61be + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:d3d8a8bfee292afee3c683692fdd70c031ef430446124285f6abc73365839a6f - name: kind value: task resolver: bundles @@ -372,7 +372,7 @@ spec: - name: name value: buildah - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:2d6e09f356059ccfd8aada165d5b020e1eb025aeac4717a1ea2de239bed2a0d7 + value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:7d3f090943ecb839cc505b3a5e5305c0203dfc6dbc0096713c0add9ef1e45d90 - name: kind value: task resolver: bundles @@ -404,7 +404,7 @@ spec: - name: name value: build-image-index - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.1@sha256:e4871851566d8b496966b37bcb8c5ce9748a52487f116373d96c6cd28ef684c6 + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.1@sha256:7b2c5ab5d711d1d487693072dec6a10ede0076290dabc673bc6ccde9a322674a - name: kind value: task resolver: bundles @@ -413,6 +413,25 @@ spec: operator: in values: - "true" + - name: rpms-signature-scan + params: + - name: image-digest + value: $(tasks.build-container.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-container.results.IMAGE_URL) + - name: fail-unsigned + value: true + runAfter: + - build-container + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:8f3b23bf1b0ef55cc79d28604d2397a0101ac9c0c42ae26e26532eb2778c801b + - name: kind + value: task + resolver: bundles - name: build-source-image params: - name: BINARY_IMAGE @@ -424,7 +443,7 @@ spec: - name: name value: source-build - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:21cb5ebaff7a9216903cf78933dc4ec4dd6283a52636b16590a5f52ceb278269 + value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:957f765b9d7ea9e69f26cd56b11412699574d8543dc99eaf7f3c04cb713d6ac4 - name: kind value: task resolver: bundles @@ -453,7 +472,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:b4f9599f5770ea2e6e4d031224ccc932164c1ecde7f85f68e16e99c98d754003 + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:5a1a165fa02270f0a947d8a2131ee9d8be0b8e9d34123828c2bef589e504ee84 - name: kind value: task resolver: bundles @@ -475,7 +494,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:28fee4bf5da87f2388c973d9336086749cad8436003f9a514e22ac99735e056b + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:0a5421111e7092740398691d5bd7c125cc0896f29531d19414bb5724ae41692a - name: kind value: task resolver: bundles @@ -495,7 +514,7 @@ spec: - name: name value: ecosystem-cert-preflight-checks - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:5131cce0f93d0b728c7bcc0d6cee4c61d4c9f67c6d619c627e41e3c9775b497d + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:df8a25a3431a70544172ed4844f9d0c6229d39130633960729f825a031a7dea9 - name: kind value: task resolver: bundles @@ -517,7 +536,7 @@ spec: - name: name value: sast-snyk-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.2@sha256:c1ea706405f9ae146e31baef4abfea49b1e855a75bfc44c33eb0eb29516831b3 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.3@sha256:9fa8acbd4331e5f7c7ba39c6283a219b084e8b2332996e0988a7907a4a75feb4 - name: kind value: task resolver: bundles @@ -542,7 +561,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:1e29eebe916b81b7100138d62db0e03e22d03657274d37041c59cbaca5fdbf7d + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:b4f450f1447b166da671f1d5819ab5a1485083e5c27ab91f7d8b7a2ff994c8c2 - name: kind value: task resolver: bundles @@ -562,7 +581,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:f485e250fb060060892b633c495a3d7e38de1ec105ae1be48608b0401530ab2c + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:87fd7fc0e937aad1a8db9b6e377d7e444f53394dafde512d68adbea6966a4702 - name: kind value: task resolver: bundles @@ -583,7 +602,7 @@ spec: - name: name value: push-dockerfile - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:674e70f7d724aaf1dd631ba9be2998ab0305fb3e0d9ec361351cc5e57bcdd3ec + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:48bb2ee92ea528b28c0814c9cc126021e499a081b69431987a774561e9ac8047 - name: kind value: task resolver: bundles diff --git a/.tekton/vulnerability-ui-push.yaml b/.tekton/vulnerability-ui-push.yaml index bad849f31..96e6e7d5c 100644 --- a/.tekton/vulnerability-ui-push.yaml +++ b/.tekton/vulnerability-ui-push.yaml @@ -43,7 +43,7 @@ spec: - name: name value: show-sbom - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:9bfc6b99ef038800fe131d7b45ff3cd4da3a415dd536f7c657b3527b01c4a13b + value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:945a7c9066d3e0a95d3fddb7e8a6992e4d632a2a75d8f3a9bd2ff2fef0ec9aa0 - name: kind value: task resolver: bundles @@ -62,7 +62,7 @@ spec: - name: name value: summary - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:d97c04ab42f277b1103eb6f3a053b247849f4f5b3237ea302a8ecada3b24e15b + value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:870d9a04d9784840a90b7bf6817cd0d0c4edfcda04b1ba1868cae625a3c3bfcc - name: kind value: task resolver: bundles @@ -153,7 +153,7 @@ spec: - name: name value: init - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:092c113b614f6551113f17605ae9cb7e822aa704d07f0e37ed209da23ce392cc + value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:0523b51c28375a3f222da91690e22eff11888ebc98a0c73c468af44762265c69 - name: kind value: task resolver: bundles @@ -170,7 +170,7 @@ spec: - name: name value: git-clone - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:2cccdf8729ad4d5adf65e8b66464f8efa1e1c87ba16d343b4a6c621a2a40f7e1 + value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:d091a9e19567a4cbdc5acd57903c71ba71dc51d749a4ba7477e689608851e981 - name: kind value: task resolver: bundles @@ -195,7 +195,7 @@ spec: - name: name value: prefetch-dependencies - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:fe7234e3824d1e65d6a7aac352e7a6bbce623d90d8d7da9aceeee108ad2c61be + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:d3d8a8bfee292afee3c683692fdd70c031ef430446124285f6abc73365839a6f - name: kind value: task resolver: bundles @@ -369,7 +369,7 @@ spec: - name: name value: buildah - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:2d6e09f356059ccfd8aada165d5b020e1eb025aeac4717a1ea2de239bed2a0d7 + value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:7d3f090943ecb839cc505b3a5e5305c0203dfc6dbc0096713c0add9ef1e45d90 - name: kind value: task resolver: bundles @@ -401,7 +401,7 @@ spec: - name: name value: build-image-index - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.1@sha256:e4871851566d8b496966b37bcb8c5ce9748a52487f116373d96c6cd28ef684c6 + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.1@sha256:7b2c5ab5d711d1d487693072dec6a10ede0076290dabc673bc6ccde9a322674a - name: kind value: task resolver: bundles @@ -410,6 +410,25 @@ spec: operator: in values: - "true" + - name: rpms-signature-scan + params: + - name: image-digest + value: $(tasks.build-container.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-container.results.IMAGE_URL) + - name: fail-unsigned + value: true + runAfter: + - build-container + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:8f3b23bf1b0ef55cc79d28604d2397a0101ac9c0c42ae26e26532eb2778c801b + - name: kind + value: task + resolver: bundles - name: build-source-image params: - name: BINARY_IMAGE @@ -421,7 +440,7 @@ spec: - name: name value: source-build - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:21cb5ebaff7a9216903cf78933dc4ec4dd6283a52636b16590a5f52ceb278269 + value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:957f765b9d7ea9e69f26cd56b11412699574d8543dc99eaf7f3c04cb713d6ac4 - name: kind value: task resolver: bundles @@ -450,7 +469,7 @@ spec: - name: name value: deprecated-image-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:b4f9599f5770ea2e6e4d031224ccc932164c1ecde7f85f68e16e99c98d754003 + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:5a1a165fa02270f0a947d8a2131ee9d8be0b8e9d34123828c2bef589e504ee84 - name: kind value: task resolver: bundles @@ -472,7 +491,7 @@ spec: - name: name value: clair-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:28fee4bf5da87f2388c973d9336086749cad8436003f9a514e22ac99735e056b + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:0a5421111e7092740398691d5bd7c125cc0896f29531d19414bb5724ae41692a - name: kind value: task resolver: bundles @@ -492,7 +511,7 @@ spec: - name: name value: ecosystem-cert-preflight-checks - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:5131cce0f93d0b728c7bcc0d6cee4c61d4c9f67c6d619c627e41e3c9775b497d + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:df8a25a3431a70544172ed4844f9d0c6229d39130633960729f825a031a7dea9 - name: kind value: task resolver: bundles @@ -514,7 +533,7 @@ spec: - name: name value: sast-snyk-check - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.2@sha256:c1ea706405f9ae146e31baef4abfea49b1e855a75bfc44c33eb0eb29516831b3 + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.3@sha256:9fa8acbd4331e5f7c7ba39c6283a219b084e8b2332996e0988a7907a4a75feb4 - name: kind value: task resolver: bundles @@ -539,7 +558,7 @@ spec: - name: name value: clamav-scan - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:1e29eebe916b81b7100138d62db0e03e22d03657274d37041c59cbaca5fdbf7d + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:b4f450f1447b166da671f1d5819ab5a1485083e5c27ab91f7d8b7a2ff994c8c2 - name: kind value: task resolver: bundles @@ -559,7 +578,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:f485e250fb060060892b633c495a3d7e38de1ec105ae1be48608b0401530ab2c + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:87fd7fc0e937aad1a8db9b6e377d7e444f53394dafde512d68adbea6966a4702 - name: kind value: task resolver: bundles @@ -580,7 +599,7 @@ spec: - name: name value: push-dockerfile - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:674e70f7d724aaf1dd631ba9be2998ab0305fb3e0d9ec361351cc5e57bcdd3ec + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:48bb2ee92ea528b28c0814c9cc126021e499a081b69431987a774561e9ac8047 - name: kind value: task resolver: bundles diff --git a/package-lock.json b/package-lock.json index 36e1b33fa..3e120ec7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@redhat-cloud-services/frontend-components": "^4.2.14", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-pdf-generator": "^4.0.6", - "@redhat-cloud-services/frontend-components-translations": "^3.2.8", + "@redhat-cloud-services/frontend-components-translations": "^3.2.9", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/host-inventory-client": "^1.4.4", "@redhat-cloud-services/vulnerabilities-client": "^1.4.3", @@ -4477,9 +4477,10 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@redhat-cloud-services/frontend-components-translations": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-translations/-/frontend-components-translations-3.2.8.tgz", - "integrity": "sha512-7nnKpVc4zVv2TMdkHPCEr3qVsH0gtkYQGbW4Q5cgPdz3Qmcn8MYQLw+3biiFWQmImUwoDt8EWRssPG/Ilf85Yw==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-translations/-/frontend-components-translations-3.2.9.tgz", + "integrity": "sha512-hkIEV7BG5vT0CxwHiqgBkeuUGM93bZqeF6lvbq/DgOyMcevZ1eiFM0iQKPNrw8jS8UfDawaCiHhXOGGrD7T4Sw==", + "license": "Apache-2.0", "optionalDependencies": { "@redhat-cloud-services/frontend-components-utilities": "^4.0.13" }, @@ -26738,9 +26739,9 @@ } }, "@redhat-cloud-services/frontend-components-translations": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-translations/-/frontend-components-translations-3.2.8.tgz", - "integrity": "sha512-7nnKpVc4zVv2TMdkHPCEr3qVsH0gtkYQGbW4Q5cgPdz3Qmcn8MYQLw+3biiFWQmImUwoDt8EWRssPG/Ilf85Yw==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-translations/-/frontend-components-translations-3.2.9.tgz", + "integrity": "sha512-hkIEV7BG5vT0CxwHiqgBkeuUGM93bZqeF6lvbq/DgOyMcevZ1eiFM0iQKPNrw8jS8UfDawaCiHhXOGGrD7T4Sw==", "requires": { "@redhat-cloud-services/frontend-components-utilities": "^4.0.13" } diff --git a/package.json b/package.json index 717bd0cbe..3c0f4a247 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@redhat-cloud-services/frontend-components": "^4.2.14", "@redhat-cloud-services/frontend-components-notifications": "^4.1.0", "@redhat-cloud-services/frontend-components-pdf-generator": "^4.0.6", - "@redhat-cloud-services/frontend-components-translations": "^3.2.8", + "@redhat-cloud-services/frontend-components-translations": "^3.2.9", "@redhat-cloud-services/frontend-components-utilities": "^4.0.11", "@redhat-cloud-services/host-inventory-client": "^1.4.4", "@redhat-cloud-services/vulnerabilities-client": "^1.4.3", diff --git a/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.js b/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.js deleted file mode 100644 index a1d11f82e..000000000 --- a/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.js +++ /dev/null @@ -1,59 +0,0 @@ -import React, { useState } from 'react'; -import propTypes from 'prop-types'; -import { - Radio -} from '@patternfly/react-core'; -import { - Select, - SelectOption -} from '@patternfly/react-core/deprecated'; - -const RadioCustomFilter = ({ filterData, setFilterData, selectProps, options, filterId, filterName }) => { - const [isOpen, setOpen] = useState(false); - - const handleOnRadioChange = (filterId, optionName) => { - const optionValue = options.find(item => item.label === optionName).value; - setFilterData({ ...filterData, [filterId]: optionValue }); - }; - - return ( - - ); -}; - -RadioCustomFilter.propTypes = { - filterName: propTypes.string, - filterId: propTypes.string, - filterData: propTypes.object, - setFilterData: propTypes.func, - selectProps: propTypes.object, - options: propTypes.array -}; - -export default RadioCustomFilter; diff --git a/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.test.js b/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.test.js deleted file mode 100644 index 3e409217f..000000000 --- a/src/Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter.test.js +++ /dev/null @@ -1,42 +0,0 @@ -import RadioCustomFilter from './RadioCustomFilter'; -import { fireEvent, render, screen } from '@testing-library/react'; - -const selectProps = null -const options = [ - { value: "op1", label: "option 1" }, - { value: "op2", label: "option 2" }, - { value: "op3", label: "option 3" } -] -const filterName = "My filter" -const filterId = "my_filter" - -describe('RadioCustomFilter component', () => { - it('Should have selected first item by default.', () => { - let filterData = { my_filter: "op1" } - const setFilterData = newData => filterData = newData - - render( - - ); - - fireEvent.click(screen.getByLabelText('Options menu')); - - expect(screen.getByRole('radio', { name: /option 1/i }).checked).toBeTruthy(); - expect(screen.getByRole('radio', { name: /option 2/i }).checked).toBeFalsy(); - expect(screen.getByRole('radio', { name: /option 3/i }).checked).toBeFalsy(); - }); - - it('Should update filter data on radio change.', () => { - let filterData = { my_filter: "op1" } - const setFilterData = newData => filterData = newData - - render( - - ); - - fireEvent.click(screen.getByLabelText('Options menu')); - fireEvent.click(screen.getByRole('radio', { name: /option 2/i })); - - expect(filterData).toStrictEqual({ my_filter: "op2" }) - }); -}); diff --git a/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.js b/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.js new file mode 100644 index 000000000..b6d23e0b8 --- /dev/null +++ b/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.js @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import propTypes from 'prop-types'; +import { + MenuToggle, + Select, + SelectList, + SelectOption +} from '@patternfly/react-core'; + +const SelectCustomFilter = ({ filterData, setFilterData, selectProps, options, filterId, filterName }) => { + const [isOpen, setOpen] = useState(false); + + const handleOnRadioChange = (filterId, optionName) => { + const optionValue = options.find(item => item.label === optionName).value; + setFilterData({ ...filterData, [filterId]: optionValue }); + setOpen(false); + }; + + const selectedValue = options.find(item => item.value === filterData[filterId])?.label; + + const toggle = toggleRef => + setOpen(!isOpen)} + isExpanded={isOpen} + style={{ + width: 'auto' + }}> + { + filterName + ? `${filterName}: ${selectedValue}` + : `${selectedValue}` + } + ; + + return ( +
+ +
+ ); +}; + +SelectCustomFilter.propTypes = { + filterName: propTypes.string, + filterId: propTypes.string, + filterData: propTypes.object, + setFilterData: propTypes.func, + selectProps: propTypes.object, + options: propTypes.array +}; + +export default SelectCustomFilter; diff --git a/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.test.js b/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.test.js new file mode 100644 index 000000000..915864205 --- /dev/null +++ b/src/Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter.test.js @@ -0,0 +1,68 @@ +import userEvent from '@testing-library/user-event'; +import SelectCustomFilter from './SelectCustomFilter'; +import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; + +const selectProps = null +const options = [ + { value: "op1", label: "option 1" }, + { value: "op2", label: "option 2" }, + { value: "op3", label: "option 3" } +] +const filterName = "My filter" +const filterId = "my_filter" + +describe('SelectCustomFilter component', () => { + it('Should have selected first item by default.', async () => { + let filterData = { my_filter: "op1" } + const setFilterData = newData => filterData = newData + + render( + + ); + + await waitFor(() => userEvent.click(screen.getByRole('button', { + name: /my filter: option 1/i + }))); + + const option1 = screen.getByRole('option', { + name: /option 1/i + }); + const option2 = screen.getByRole('option', { + name: /option 2/i + }); + const option3 = screen.getByRole('option', { + name: /option 3/i + }); + + expect(within(option1).getByRole('img', { + hidden: true + })).toBeTruthy(); + expect(within(option2).queryByRole('img', { + hidden: true + })).toBeFalsy(); + expect(within(option3).queryByRole('img', { + hidden: true + })).toBeFalsy(); + }); + + it('Should update filter data on radio change.', async () => { + let filterData = { my_filter: "op1" } + const setFilterData = newData => filterData = newData + + render( + + ); + + await waitFor(() => userEvent.click(screen.getByRole('button', { + name: /my filter: option 1/i + }))); + + const option2 = screen.getByRole('option', { + name: /option 2/i + }); + + await waitFor(() => userEvent.click(option2)); + + expect(filterData).toStrictEqual({ my_filter: "op2" }) + }); +}); diff --git a/src/Components/PresentationalComponents/Filters/PrimaryToolbarFilters/ImpactFilter.js b/src/Components/PresentationalComponents/Filters/PrimaryToolbarFilters/ImpactFilter.js index 37e86fcce..e6de9271a 100644 --- a/src/Components/PresentationalComponents/Filters/PrimaryToolbarFilters/ImpactFilter.js +++ b/src/Components/PresentationalComponents/Filters/PrimaryToolbarFilters/ImpactFilter.js @@ -27,7 +27,7 @@ const impactFilter = (apply, currentFilter = {}) => { label: ( { item.hasIcon && - + diff --git a/src/Components/SmartComponents/Modals/BusinessRiskModal.js b/src/Components/SmartComponents/Modals/BusinessRiskModal.js index 09053ebea..529337ecc 100644 --- a/src/Components/SmartComponents/Modals/BusinessRiskModal.js +++ b/src/Components/SmartComponents/Modals/BusinessRiskModal.js @@ -11,7 +11,7 @@ import { CVETableContext } from '../CVEs/CVEs'; import { clearCVEsStore } from '../../../Store/Actions/Actions'; import { updateRef as updateRefHelper } from '../../../Helpers/MiscHelper'; -export const BusinessRiskModal = ({ cves, goToFirstPage, intl }) => { +export const BusinessRiskModal = ({ cves, goToFirstPage, intl, updateRef }) => { const { cves: { meta } = {}, params, @@ -19,7 +19,7 @@ export const BusinessRiskModal = ({ cves, goToFirstPage, intl }) => { } = useContext(CVETableContext); const dispatch = useDispatch(); - const updateRef = () => { + const handleUpdateRef = () => { dispatch(clearCVEsStore()); updateRefHelper(goToFirstPage ? { ...meta, page: 1 } : meta, params, apply); }; @@ -57,7 +57,7 @@ export const BusinessRiskModal = ({ cves, goToFirstPage, intl }) => { business_risk_id: parseInt(businessRiskId), cve: cveList.map(item => item.id), business_risk_text: label - }).then(updateRef).catch(error => { + }).then(updateRef ? () => updateRef() : () => handleUpdateRef()).catch(error => { throw error; // propagate error to BaseModal }); }; @@ -125,7 +125,8 @@ export const BusinessRiskModal = ({ cves, goToFirstPage, intl }) => { BusinessRiskModal.propTypes = { cves: propTypes.array, goToFirstPage: propTypes.bool, - intl: propTypes.any + intl: propTypes.any, + updateRef: propTypes.func }; export default injectIntl(BusinessRiskModal); diff --git a/src/Components/SmartComponents/Modals/CvePairStatusModal.js b/src/Components/SmartComponents/Modals/CvePairStatusModal.js index 10ea40e0d..4761e2006 100644 --- a/src/Components/SmartComponents/Modals/CvePairStatusModal.js +++ b/src/Components/SmartComponents/Modals/CvePairStatusModal.js @@ -212,9 +212,9 @@ export const CvePairStatusModal = ({ cveList, updateRef, inventoryList, intl, ty > diff --git a/src/Components/SmartComponents/Modals/CveStatusModal.js b/src/Components/SmartComponents/Modals/CveStatusModal.js index d76b1ce3a..b55b2e866 100644 --- a/src/Components/SmartComponents/Modals/CveStatusModal.js +++ b/src/Components/SmartComponents/Modals/CveStatusModal.js @@ -11,7 +11,7 @@ import { clearCVEsStore } from '../../../Store/Actions/Actions'; import { useDispatch } from 'react-redux'; import { updateRef as updateRefHelper } from '../../../Helpers/MiscHelper'; -export const CveStatusModal = ({ cves, intl, canEditPairStatus, goToFirstPage }) => { +export const CveStatusModal = ({ cves, intl, canEditPairStatus, goToFirstPage, updateRef }) => { const { cves: { meta } = {}, params, @@ -19,7 +19,7 @@ export const CveStatusModal = ({ cves, intl, canEditPairStatus, goToFirstPage }) } = useContext(CVETableContext); const dispatch = useDispatch(); - const updateRef = () => { + const handleUpdateRef = () => { dispatch(clearCVEsStore()); updateRefHelper(goToFirstPage ? { ...meta, page: 1 } : meta, params, apply); }; @@ -50,7 +50,7 @@ export const CveStatusModal = ({ cves, intl, canEditPairStatus, goToFirstPage }) }) ] ]) - .then(() => updateRef(!checkboxState)) + .then(updateRef ? () => updateRef(!checkboxState) : () => handleUpdateRef(!checkboxState)) .catch(error => { throw error; }); // propagate error to BaseModal }; @@ -156,7 +156,8 @@ CveStatusModal.propTypes = { cves: propTypes.array, intl: propTypes.any, canEditPairStatus: propTypes.bool.isRequired, - goToFirstPage: propTypes.bool + goToFirstPage: propTypes.bool, + updateRef: propTypes.func }; export default injectIntl(CveStatusModal); diff --git a/src/Components/SmartComponents/Reports/ReportsPage.js b/src/Components/SmartComponents/Reports/ReportsPage.js index 71cc3d756..0c473702c 100644 --- a/src/Components/SmartComponents/Reports/ReportsPage.js +++ b/src/Components/SmartComponents/Reports/ReportsPage.js @@ -36,7 +36,8 @@ const ReportsPage = () => { const [inheritGlobalTags, setInheritGlobalTags] = useState(true); const [cvesWithoutErrata, setCvesWithoutErrata] = useState(false); - const globalFilterTags = useSelector(({ ReportsPageStore }) => ReportsPageStore.parameters.tags) ?? []; + const globalFilterTags = useSelector(({ ReportsPageStore }) => + ReportsPageStore.parameters.tags?.length && ReportsPageStore.parameters.tags.split(',')) || []; const dispatch = useDispatch(); diff --git a/src/Components/SmartComponents/Reports/ReportsPage.test.js b/src/Components/SmartComponents/Reports/ReportsPage.test.js index e20c56b45..ff5854fe9 100644 --- a/src/Components/SmartComponents/Reports/ReportsPage.test.js +++ b/src/Components/SmartComponents/Reports/ReportsPage.test.js @@ -33,7 +33,7 @@ jest.mock("../../../Helpers/APIHelper.js", () => ({ getCveListByAccount: () => new Promise(() => {}, () => {}) })); -const state = { +let state = { parameters: {} } @@ -205,4 +205,22 @@ describe('Reports page component', () => { expect(screen.getByText(/systems: 1 or more conventional \(rpm\-dnf\), 1 or more immutable \(ostree\)/i)).toBeVisible(); }); + + it('Should apply global tags.', async () => { + state.parameters = { tags: "AAaNIKhDBt/LorNtSjoRt=WRTmPByfQ,BMCRfrl/kgWDqQYPT=KVdLiE" }; + render( + + + + ); + + await waitFor(() => { + fireEvent.click(screen.getByText(/create report/i)); + }); + + screen.logTestingPlaygroundURL(); + + expect(screen.getByText(/tags: aaanikhdbt: lorntsjort = wrtmpbyfq, bmcrfrl: kgwdqqypt = kvdlie/i)).toBeVisible(); + expect(screen.queryByText(/tags: all/i)).toBeFalsy(); + }); }); diff --git a/src/Helpers/constants.js b/src/Helpers/constants.js index c04b2e83c..db49831bf 100644 --- a/src/Helpers/constants.js +++ b/src/Helpers/constants.js @@ -6,7 +6,7 @@ import SystemNameColumn from '../Components/PresentationalComponents/TableColumn import RemediationColumn from '../Components/PresentationalComponents/TableColumns/RemediationColumn'; import CvssCustomFilter from '../Components/PresentationalComponents/Filters/CustomFilters/CvssCustomFilter'; import CheckboxCustomFilter from '../Components/PresentationalComponents/Filters/CustomFilters/CheckboxCustomFilter'; -import RadioCustomFilter from '../Components/PresentationalComponents/Filters/CustomFilters/RadioCustomFilter'; +import SelectCustomFilter from '../Components/PresentationalComponents/Filters/CustomFilters/SelectCustomFilter'; import messages from '../Messages'; import { intl } from '../Utilities/IntlProvider'; import { intlFormatWithBold } from './ReportsHelper'; @@ -444,7 +444,7 @@ export const getCveReportFilters = (shouldUseHybridSystemFilter = false) => ({ publish_date: { title: intl.formatMessage(messages.publishDate), items: PUBLIC_DATE_OPTIONS, - component: RadioCustomFilter + component: SelectCustomFilter }, status_id: { title: intl.formatMessage(messages.status), diff --git a/src/Messages.js b/src/Messages.js index 6d04eb0ac..940ee4b59 100644 --- a/src/Messages.js +++ b/src/Messages.js @@ -358,7 +358,7 @@ export default defineMessages({ businessRiskModalInfo: { id: 'businessRiskModal.info', description: 'Information about business risk for users', - defaultMessage: `Business risk can be used to identify, + defaultMessage: `Business risk can be used to identify, track, and address CVEs that have meaningful impact to your organization.` }, @@ -401,7 +401,7 @@ export default defineMessages({ cveStatusModalOverwriteTooltip: { id: 'cveStatusModal.overwriteTooltip', description: 'label for overwrite checkbox', - defaultMessage: `When checked, this setting does not change any pre-existing + defaultMessage: `When checked, this setting does not change any pre-existing statuses set on individual systems for this CVE.` }, cveStatusModalSelected: { @@ -412,13 +412,13 @@ export default defineMessages({ cveStatusModalInfo: { id: 'cveStatusModal.info', description: 'label for overwrite checkbox', - defaultMessage: `This status is applied to all existing systems affected by {count, plural, one {this CVE} other {these CVEs}}. + defaultMessage: `This status is applied to all existing systems affected by {count, plural, one {this CVE} other {these CVEs}}. Any new affected systems will have the status "Not reviewed"` }, cveStatusModalInfoTooltip: { id: 'cveStatusModal.infoTooltip', description: 'label for overwrite checkbox', - defaultMessage: `Example: If a new system is added and matches to this vulnerability, + defaultMessage: `Example: If a new system is added and matches to this vulnerability, it will be given a status "Not reviewed"` }, ansibleRemediationTooltip: { @@ -959,7 +959,7 @@ export default defineMessages({ cvssBaseScoreHighToLow: { id: 'cvssBaseScoreHighToLow', description: 'CVSS base score: High to Low sort default option', - defaultMessage: 'CVSS base score: High to Low (Default)' + defaultMessage: 'CVSS base score: High to Low' }, cvssBaseScoreLowToHigh: { id: 'cvssBaseScoreLowToHigh',