├── .commitlintrc.js ├── .dockerignore ├── .github ├── actions │ ├── cache │ │ └── action.yaml │ ├── cypress-cache │ │ └── action.yaml │ └── release │ │ └── action.yml └── workflows │ ├── ci.yaml │ └── reporter.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-push ├── .npmignore ├── .prettierignore ├── .prettierrc.json ├── .verdaccio └── config.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── Dockerfile.dev ├── LICENSE ├── README.md ├── babel.config.js ├── config ├── .gitignore └── setupTests.js ├── cypress.webpack.config.ts ├── deploy └── openshift.yaml ├── docker-compose.yml ├── docs ├── analytics │ └── index.md ├── chrome │ ├── chrome-api.md │ └── chrome-navigation.md ├── feature-flags │ ├── index.md │ └── managing-feature-flags.md ├── fed │ ├── consuming-module.md │ ├── index.md │ ├── plugin-sdk.md │ └── testing.md ├── frontend-components-config │ ├── hot-module-replacement.md │ ├── index.md │ └── use-cache.md ├── migrations │ ├── charts.md │ ├── frontend-components-config.md │ ├── frontend-coomponents-config-utilities.md │ ├── nx-workspace-manager.md │ └── pdf-generator.md ├── quickstarts │ ├── common-issues.md │ ├── help-topics.md │ ├── index.md │ └── setup.md ├── router-v6.md └── webpack-proxy.md ├── eslint.config.js ├── examples └── demo │ ├── .babelrc │ ├── CHANGELOG.md │ ├── eslint.config.js │ ├── project.json │ ├── src │ ├── app │ │ └── app.tsx │ ├── assets │ │ └── .gitkeep │ ├── favicon.ico │ ├── index.html │ ├── main.tsx │ └── styles.scss │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ ├── vite.config.ts │ └── webpack.config.js ├── jest.config.ts ├── jest.preset.js ├── locales ├── cs.json ├── data.json └── translations.json ├── navnotes.md ├── nx.json ├── package-lock.json ├── package.json ├── packages ├── advisor-components │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── cypres.config.ts │ ├── cypress │ │ ├── component │ │ │ ├── ReportDetails │ │ │ │ └── ReportDetails.spec.cy.tsx │ │ │ └── RuleDetail │ │ │ │ └── RuleDetails.spec.cy.tsx │ │ ├── fixtures │ │ │ ├── messages.json │ │ │ ├── report.json │ │ │ └── rule.json │ │ ├── overrideChrome.ts │ │ ├── plugins │ │ │ └── index.js │ │ ├── snapshots │ │ │ └── src │ │ │ │ └── ReportDetails │ │ │ │ └── ReportDetails.spec.ct.js │ │ │ │ └── report details kba loaded -- renders component and matches screenshot.snap.png │ │ └── support │ │ │ ├── commands.js │ │ │ ├── component-index.html │ │ │ ├── component.d.ts │ │ │ └── component.ts │ ├── doc │ │ ├── reportDetails.md │ │ └── ruleDetails.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── RebootRequired │ │ │ ├── RebootRequired.scss │ │ │ ├── RebootRequired.tsx │ │ │ └── index.ts │ │ ├── ReportDetails │ │ │ ├── ReportDetails.scss │ │ │ ├── ReportDetails.tsx │ │ │ ├── __image_snapshots__ │ │ │ │ └── report details kba loaded renders component and matches screenshot #0.png │ │ │ └── index.ts │ │ ├── RuleDescription │ │ │ ├── RuleDescription.scss │ │ │ ├── RuleDescription.tsx │ │ │ └── index.ts │ │ ├── RuleDetails │ │ │ ├── RuleDetails.scss │ │ │ ├── RuleDetails.tsx │ │ │ ├── RuleDetailsMessages.ts │ │ │ └── index.ts │ │ ├── RuleRating │ │ │ ├── RuleRating.scss │ │ │ ├── RuleRating.tsx │ │ │ └── index.ts │ │ ├── TemplateProcessor │ │ │ ├── TemplateProcessor.tsx │ │ │ └── index.ts │ │ ├── ViewAffectedLink │ │ │ ├── ViewAffectedLink.tsx │ │ │ └── index.ts │ │ ├── common.tsx │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── modules.d.ts │ │ └── types.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.cy.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── chrome │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── ChromeContext │ │ │ ├── ChromeContext.ts │ │ │ └── index.ts │ │ ├── ChromeProvider │ │ │ ├── ChromeProvider.test.tsx │ │ │ ├── ChromeProvider.tsx │ │ │ ├── __mocks__ │ │ │ │ └── @unleash │ │ │ │ │ └── proxy-client-react.js │ │ │ ├── chromeState.test.ts │ │ │ ├── chromeState.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── useFavoritePages │ │ │ ├── index.ts │ │ │ ├── useFavoritePages.test.tsx │ │ │ └── useFavoritePages.ts │ │ ├── useLastVisited │ │ │ ├── index.ts │ │ │ └── useLastVisited.ts │ │ ├── useVisitedBundles │ │ │ ├── index.ts │ │ │ ├── useVisitedBundles.test.tsx │ │ │ └── useVisitedBundles.ts │ │ └── utils │ │ │ ├── fetch.test.ts │ │ │ └── fetch.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── components │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── cypres.config.ts │ ├── cypress │ │ ├── component │ │ │ ├── Breadcrumbs │ │ │ │ └── Breadcrumbs.spec.cy.js │ │ │ ├── BulkSelect │ │ │ │ └── BulkSelect.spec.cy.js │ │ │ ├── ConditionalFilter │ │ │ │ ├── CheckboxFilter.spec.cy.tsx │ │ │ │ ├── ConditionalFilter.spec.cy.js │ │ │ │ ├── GroupFilter.spec.cy.js │ │ │ │ ├── RadioFilter.spec.cy.js │ │ │ │ └── TextFilter.spec.cy.js │ │ │ ├── DownloadButton │ │ │ │ └── DownloadButton.spec.cy.js │ │ │ └── PrimaryToolbar │ │ │ │ ├── Actions.spec.cy.tsx │ │ │ │ ├── PrimaryToolbar.spec.cy.tsx │ │ │ │ └── SortBy.spec.cy.tsx │ │ ├── fixtures │ │ │ └── example.json │ │ ├── plugins │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ └── support │ │ │ ├── commands.d.ts │ │ │ ├── commands.ts │ │ │ ├── component-index.html │ │ │ ├── component.d.ts │ │ │ └── component.ts │ ├── doc │ │ ├── ansible.md │ │ ├── battery.md │ │ ├── breadcrumbs.md │ │ ├── bulkd_select.md │ │ ├── conditionalFilter.md │ │ ├── dark.md │ │ ├── dropdown.md │ │ ├── emptyTable.md │ │ ├── filters.md │ │ ├── input.md │ │ ├── insights_link.md │ │ ├── maintenance.md │ │ ├── notAuthorized.md │ │ ├── openSourceBadge.md │ │ ├── page_header.md │ │ ├── pagination.md │ │ ├── primary_toolbar.md │ │ ├── reboot.md │ │ ├── sample.md │ │ ├── section.md │ │ ├── shield.md │ │ ├── spinner.md │ │ ├── tabLayout.md │ │ ├── table.md │ │ ├── tableToolbar.md │ │ ├── treeview-table.md │ │ ├── truncate.md │ │ └── useScreenSize.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── Ansible │ │ │ ├── Ansible.tsx │ │ │ └── index.ts │ │ ├── AsyncComponent │ │ │ └── index.tsx │ │ ├── Battery │ │ │ ├── Battery.tsx │ │ │ ├── CriticalBattery.tsx │ │ │ ├── HighBattery.tsx │ │ │ ├── LowBattery.tsx │ │ │ ├── MediumBattery.tsx │ │ │ ├── NullBattery.tsx │ │ │ └── index.ts │ │ ├── Breadcrumbs │ │ │ ├── Breadcrumbs.test.js │ │ │ ├── Breadcrumbs.tsx │ │ │ ├── ConnectedBreadcrumbs.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Breadcrumbs.test.js.snap │ │ │ └── index.ts │ │ ├── BulkSelect │ │ │ ├── BulkSelect.test.js │ │ │ ├── BulkSelect.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── BulkSelect.test.js.snap │ │ │ ├── bulk-select.scss │ │ │ └── index.ts │ │ ├── ConditionalFilter │ │ │ ├── CheckboxFilter.test.js │ │ │ ├── CheckboxFilter.tsx │ │ │ ├── ConditionalFilter.test.js │ │ │ ├── ConditionalFilter.tsx │ │ │ ├── GroupFilter.test.js │ │ │ ├── GroupFilter.tsx │ │ │ ├── RadioFilter.test.js │ │ │ ├── RadioFilter.tsx │ │ │ ├── SingleSelectFilter.tests.js │ │ │ ├── SingleSelectFilter.tsx │ │ │ ├── TextFilter.test.js │ │ │ ├── TextFilter.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── CheckboxFilter.test.js.snap │ │ │ │ ├── ConditionalFilter.test.js.snap │ │ │ │ ├── GroupFilter.test.js.snap │ │ │ │ ├── RadioFilter.test.js.snap │ │ │ │ └── TextFilter.test.js.snap │ │ │ ├── conditional-filter.scss │ │ │ ├── conditionalFilterConstants.test.js │ │ │ ├── conditionalFilterConstants.ts │ │ │ ├── group-filter.scss │ │ │ ├── groupFilterConstants.test.js │ │ │ ├── groupFilterConstants.ts │ │ │ ├── groupType.ts │ │ │ └── index.ts │ │ ├── CullingInfo │ │ │ ├── CullingInformation.scss │ │ │ ├── CullingInformation.test.js │ │ │ ├── CullingInformation.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── CullingInformation.test.js.snap │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ ├── Dark │ │ │ ├── Dark.tsx │ │ │ ├── DarkContext.test.js │ │ │ ├── DarkContext.ts │ │ │ ├── __snapshots__ │ │ │ │ └── DarkContext.test.js.snap │ │ │ └── index.ts │ │ ├── DateFormat │ │ │ ├── DateFormat.test.js │ │ │ ├── DateFormat.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── DateFormat.test.js.snap │ │ │ ├── helper.test.js │ │ │ ├── helper.tsx │ │ │ └── index.ts │ │ ├── DownloadButton │ │ │ ├── DownloadButton.test.js │ │ │ ├── DownloadButton.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── DownloadButton.test.js.snap │ │ │ └── index.ts │ │ ├── EmptyTable │ │ │ ├── EmptyTable.scss │ │ │ ├── EmptyTable.test.js │ │ │ ├── EmptyTable.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── EmptyTable.test.js.snap │ │ │ └── index.ts │ │ ├── ErrorBoundary │ │ │ ├── ErrorBoundary.tsx │ │ │ └── index.ts │ │ ├── ErrorState │ │ │ ├── DefaultErrorMessage.tsx │ │ │ ├── ErrorState.tsx │ │ │ └── index.ts │ │ ├── FilterChips │ │ │ ├── FilterChips.test.js │ │ │ ├── FilterChips.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── FilterChips.test.js.snap │ │ │ ├── filter-chips.scss │ │ │ └── index.ts │ │ ├── FilterHooks │ │ │ ├── __snapshots__ │ │ │ │ └── constants.test.js.snap │ │ │ ├── constants.test.js │ │ │ ├── constants.tsx │ │ │ ├── index.ts │ │ │ ├── tagFilterHook.scss │ │ │ └── tagFilterHook.tsx │ │ ├── Filters │ │ │ ├── FilterDropdown.test.js │ │ │ ├── FilterDropdown.tsx │ │ │ ├── FilterInput.test.js │ │ │ ├── FilterInput.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── FilterDropdown.test.js.snap │ │ │ │ └── FilterInput.test.js.snap │ │ │ ├── filter-dropdown.scss │ │ │ ├── filter-input.scss │ │ │ └── index.ts │ │ ├── InsightsLabel │ │ │ ├── InsightsLabel.test.js │ │ │ ├── InsightsLabel.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── InsightsLabel.test.js.snap │ │ │ └── index.ts │ │ ├── InsightsLink │ │ │ ├── InsightsLink.test.js │ │ │ ├── InsightsLink.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── InsightsLink.test.js.snap │ │ │ └── index.ts │ │ ├── InvalidObject │ │ │ ├── InvalidObject.tsx │ │ │ └── index.ts │ │ ├── Inventory │ │ │ ├── AppInfo.js │ │ │ ├── DetailWrapper.js │ │ │ ├── InventoryDetail.js │ │ │ ├── InventoryDetailHead.js │ │ │ ├── InventoryLoadError.tsx │ │ │ ├── InventoryTable.js │ │ │ ├── TagWithDialog.tsx │ │ │ ├── WithHistory.tsx │ │ │ └── index.ts │ │ ├── Main │ │ │ ├── Main.tsx │ │ │ ├── index.ts │ │ │ └── main.scss │ │ ├── Maintenance │ │ │ ├── Maintenance.test.js │ │ │ ├── Maintenance.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Maintenance.test.js.snap │ │ │ ├── index.ts │ │ │ └── maintenance.scss │ │ ├── NoRegisteredSystems │ │ │ ├── NoRegisteredSystems.test.js │ │ │ ├── NoRegisteredSystems.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── NoRegisteredSystems.test.js.snap │ │ │ └── index.ts │ │ ├── NotAuthorized │ │ │ ├── NotAuthorized.tsx │ │ │ └── index.ts │ │ ├── NotConnected │ │ │ ├── NotConnected.test.js │ │ │ ├── NotConnected.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── NotConnected.test.js.snap │ │ │ └── index.ts │ │ ├── OpenSourceBadge │ │ │ ├── OpenSourceBadge.test.js │ │ │ ├── OpenSourceBadge.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── OpenSourceBadge.test.js.snap │ │ │ └── index.ts │ │ ├── Ouia │ │ │ ├── Ouia.test.ts │ │ │ ├── Ouia.ts │ │ │ ├── WithOuia.test.tsx │ │ │ ├── WithOuia.tsx │ │ │ ├── index.ts │ │ │ ├── useOuia.test.ts │ │ │ └── useOuia.ts │ │ ├── PageHeader │ │ │ ├── PageHeader.test.js │ │ │ ├── PageHeader.tsx │ │ │ ├── PageHeaderTitle.test.js │ │ │ ├── PageHeaderTitle.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── PageHeader.test.js.snap │ │ │ │ └── PageHeaderTitle.test.js.snap │ │ │ ├── index.ts │ │ │ └── page-header.scss │ │ ├── PrimaryToolbar │ │ │ ├── Actions.test.js │ │ │ ├── Actions.tsx │ │ │ ├── PrimaryToolbar.test.js │ │ │ ├── PrimaryToolbar.tsx │ │ │ ├── SortBy.test.js │ │ │ ├── SortBy.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── Actions.test.js.snap │ │ │ │ ├── PrimaryToolbar.test.js.snap │ │ │ │ └── SortBy.test.js.snap │ │ │ ├── index.ts │ │ │ └── primary-toolbar.scss │ │ ├── RBACProvider │ │ │ ├── RBACProvider.tsx │ │ │ └── index.ts │ │ ├── Reboot │ │ │ ├── Reboot.test.js │ │ │ ├── Reboot.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Reboot.test.js.snap │ │ │ ├── index.ts │ │ │ └── reboot.scss │ │ ├── Section │ │ │ ├── Section.test.js │ │ │ ├── Section.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Section.test.js.snap │ │ │ ├── index.ts │ │ │ └── section.scss │ │ ├── SeverityLine │ │ │ ├── SeverityLine.tsx │ │ │ ├── index.ts │ │ │ └── severity-line.scss │ │ ├── Shield │ │ │ ├── Shield.test.js │ │ │ ├── Shield.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Shield.test.js.snap │ │ │ ├── consts.ts │ │ │ └── index.ts │ │ ├── SimpleTableFilter │ │ │ ├── SimpleTableFilter.test.tsx │ │ │ ├── SimpleTableFilter.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── SimpleTableFilter.test.tsx.snap │ │ │ ├── index.ts │ │ │ └── simple-table-filter.scss │ │ ├── Skeleton │ │ │ ├── Skeleton.test.js │ │ │ ├── Skeleton.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Skeleton.test.js.snap │ │ │ ├── index.ts │ │ │ └── skeleton.scss │ │ ├── SkeletonTable │ │ │ ├── SkeletonTable.tsx │ │ │ └── index.ts │ │ ├── Spinner │ │ │ ├── Spinner.test.js │ │ │ ├── Spinner.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Spinner.test.js.snap │ │ │ ├── index.ts │ │ │ └── spinner.scss │ │ ├── TabLayout │ │ │ ├── TabLayout.test.js │ │ │ ├── TabLayout.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── TabLayout.test.js.snap │ │ │ ├── index.ts │ │ │ └── tab-layout.scss │ │ ├── TableToolbar │ │ │ ├── TableToolbar.scss │ │ │ ├── TableToolbar.test.js │ │ │ ├── TableToolbar.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── TableToolbar.test.js.snap │ │ │ └── index.ts │ │ ├── TagCount │ │ │ ├── TagCount.tsx │ │ │ └── index.ts │ │ ├── TagModal │ │ │ ├── TableWithFilter.test.js │ │ │ ├── TableWithFilter.tsx │ │ │ ├── TagModal.test.js │ │ │ ├── TagModal.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── TableWithFilter.test.js.snap │ │ │ │ └── TagModal.test.js.snap │ │ │ ├── index.ts │ │ │ └── tagModal.scss │ │ ├── TreeTable │ │ │ ├── __snapshots__ │ │ │ │ ├── decorator.test.js.snap │ │ │ │ └── rowWrapper.test.js.snap │ │ │ ├── decorator.test.js │ │ │ ├── decorator.tsx │ │ │ ├── helpers.test.js │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ ├── rowWrapper.test.js │ │ │ ├── rowWrapper.tsx │ │ │ └── styles.scss │ │ ├── Truncate │ │ │ ├── Truncate.test.js │ │ │ ├── Truncate.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Truncate.test.js.snap │ │ │ ├── index.ts │ │ │ └── truncate.scss │ │ ├── Unavailable │ │ │ ├── Unavailable.tsx │ │ │ └── index.ts │ │ ├── index.scss │ │ ├── index.ts │ │ ├── useChrome │ │ │ ├── index.ts │ │ │ └── useChrome.ts │ │ ├── usePendoFeedback │ │ │ ├── index.ts │ │ │ └── usePendoFeedback.ts │ │ └── useScreenSize │ │ │ ├── breakpoints.ts │ │ │ ├── getVariant.ts │ │ │ ├── index.ts │ │ │ ├── isSmallScreen.ts │ │ │ ├── useScreenSize.test.js │ │ │ └── useScreenSize.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.cy.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── config-utils │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── babel-transform-imports.ts │ │ ├── cookieTransform.ts │ │ ├── extension-mapper.ts │ │ ├── extensions-plugin.ts │ │ ├── fec-logger.ts │ │ ├── federated-modules.ts │ │ ├── feo │ │ │ ├── check-outgoing-requests.ts │ │ │ ├── crd-check.ts │ │ │ ├── feo-types.ts │ │ │ ├── modify-response.ts │ │ │ ├── module-interceptor.test.ts │ │ │ ├── module-interceptor.ts │ │ │ ├── navigation-interceptor.test.ts │ │ │ ├── navigation-interceptor.ts │ │ │ ├── search-interceptor.test.ts │ │ │ ├── search-interceptor.ts │ │ │ ├── service-tiles-interceptor.test.ts │ │ │ ├── service-tiles-interceptor.ts │ │ │ ├── spec │ │ │ │ └── frontend-crd.schema.json │ │ │ ├── validate-frontend-crd.test.ts │ │ │ ├── validate-frontend-crd.ts │ │ │ ├── widget-registry-interceptor.test.ts │ │ │ └── widget-registry-interceptor.ts │ │ ├── generate-pf-shared-assets-list.ts │ │ ├── index.ts │ │ ├── jsVarName.ts │ │ ├── proxy.ts │ │ ├── search-ignored-styles.ts │ │ ├── serve-federated.ts │ │ └── serveLocalFile.ts │ ├── tsconfig.json │ └── tsconfig.spec.json ├── config │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── bin │ │ │ ├── build-script.ts │ │ │ ├── common.ts │ │ │ ├── csc-interceptor-server.ts │ │ │ ├── dev-script.ts │ │ │ ├── dev.webpack.config.ts │ │ │ ├── fec.ts │ │ │ ├── prod.webpack.config.ts │ │ │ ├── serve-chrome.ts │ │ │ ├── tsconfig.template.json │ │ │ └── webpack.plugins.ts │ │ └── lib │ │ │ ├── addPrefixToContent.test.ts │ │ │ ├── addPrefixToContent.ts │ │ │ ├── config.test.js │ │ │ ├── crd-mock.yaml │ │ │ ├── createConfig.ts │ │ │ ├── createPlugins.test.ts │ │ │ ├── createPlugins.ts │ │ │ ├── fec.config.ts │ │ │ └── index.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── create-crc-app │ ├── CHANGELOG.md │ ├── bin │ │ └── create-crc-app.js │ ├── eslint.config.js │ ├── package.json │ └── templates │ │ ├── .gitignore │ │ ├── .prettierrc.json │ │ ├── .stylelintrc.json │ │ ├── .travis.yml │ │ ├── ARCHITECTURE.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── config │ │ ├── empty.js │ │ └── jest.setup.js │ │ ├── deploy │ │ └── frontend.yaml │ │ ├── fec.config.js │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src │ │ ├── App.scss │ │ ├── App.tsx │ │ ├── AppEntry.tsx │ │ ├── Components │ │ │ └── SampleComponent │ │ │ │ ├── sample-component.scss │ │ │ │ ├── sample-component.test.tsx │ │ │ │ └── sample-component.tsx │ │ ├── Routes.tsx │ │ ├── Routes │ │ │ ├── NoPermissionsPage │ │ │ │ └── NoPermissionsPage.tsx │ │ │ ├── OopsPage │ │ │ │ └── OopsPage.tsx │ │ │ └── SamplePage │ │ │ │ └── SamplePage.tsx │ │ ├── bootstrap.tsx │ │ ├── entry.ts │ │ ├── index.html │ │ ├── store │ │ │ └── index.ts │ │ └── types │ │ │ └── index.d.ts │ │ ├── template.eslint.config.js │ │ └── tsconfig.json ├── eslint-config │ ├── CHANGELOG.md │ ├── README.md │ ├── docs │ │ └── eslint-9-migration.md │ ├── index.js │ ├── lib │ │ └── rules │ │ │ ├── deprecated-packages.js │ │ │ ├── disallow-fec-relative-imports.js │ │ │ ├── disallow-pf-migrated-components.js │ │ │ ├── insights-disallow-custom-axios.js │ │ │ └── no-chrome-api-call-from-window.js │ ├── package.json │ ├── prettier.config.js │ ├── project.json │ └── tsconfig.json ├── executors │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── executors.json │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── executors │ │ │ ├── build-packages │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ ├── build-styles │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ ├── builder │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ ├── check-circular-imports │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ ├── sync-dependencies │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ └── transform-scss │ │ │ │ ├── executor.spec.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json ├── notifications │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── doc │ │ ├── migration.md │ │ └── notifications.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── Notification │ │ │ ├── Notification.test.tsx │ │ │ ├── Notification.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── Notification.test.tsx.snap │ │ │ ├── index.ts │ │ │ └── notification.scss │ │ ├── NotificationPagination │ │ │ ├── NotificationPagination.test.tsx │ │ │ ├── NotificationPagination.tsx │ │ │ ├── __snapshots__ │ │ │ │ └── NotificationPagination.test.tsx.snap │ │ │ └── index.ts │ │ ├── NotificationPortal │ │ │ ├── NotificationPortal.tsx │ │ │ └── index.ts │ │ ├── NotificationsProvider │ │ │ ├── NotificationsProvider.test.tsx │ │ │ ├── NotificationsProvider.tsx │ │ │ └── index.ts │ │ ├── Portal │ │ │ ├── Portal.tsx │ │ │ ├── index.ts │ │ │ └── portal.scss │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useNotifications.test.tsx │ │ │ └── useNotifications.ts │ │ ├── index.scss │ │ ├── index.ts │ │ └── state │ │ │ ├── index.ts │ │ │ ├── notificationStore.test.ts │ │ │ └── notificationStore.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── remediations │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── doc │ │ └── remediations.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── RemediationButton │ │ │ └── index.js │ │ ├── RemediationWizard │ │ │ └── index.js │ │ ├── common │ │ │ └── RemediationLoadError.js │ │ └── index.js │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── rule-components │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── Markdown │ │ │ ├── Markdown.js │ │ │ └── index.js │ │ ├── ReportDetails │ │ │ ├── RiskDescription.js │ │ │ ├── RiskOfChangeIcon.js │ │ │ ├── RuleFeedback.js │ │ │ ├── constants.js │ │ │ ├── index.js │ │ │ └── index.scss │ │ ├── RuleFilters │ │ │ ├── ansibleSupport.js │ │ │ ├── category.js │ │ │ ├── description.js │ │ │ ├── impact.js │ │ │ ├── incidentRules.js │ │ │ ├── index.js │ │ │ ├── likelihood.js │ │ │ ├── riskOfChange.js │ │ │ ├── ruleStatus.js │ │ │ └── totalRisk.js │ │ ├── RuleTable │ │ │ ├── RuleTable.js │ │ │ ├── constants.js │ │ │ ├── helpers.js │ │ │ ├── index.js │ │ │ └── index.scss │ │ ├── index.js │ │ └── index.scss │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── testing │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── doc │ │ └── testing.md │ ├── eslint.config.js │ ├── package.json │ ├── project.json │ ├── src │ │ ├── OuiaSelectors │ │ │ ├── OuiaSelectors.test.tsx │ │ │ ├── OuiaSelectors.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── translations │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── pre-publish.js │ ├── project.json │ ├── src │ │ ├── Provider │ │ │ ├── Provider.js │ │ │ ├── Provider.test.js │ │ │ ├── __snapshots__ │ │ │ │ └── Provider.test.js.snap │ │ │ └── index.js │ │ ├── index.js │ │ ├── intlHelper │ │ │ ├── index.js │ │ │ └── intlHelper.js │ │ ├── locales │ │ ├── messages.js │ │ ├── messages.test.js │ │ ├── translatedMessages │ │ │ └── translatedMessages.js │ │ └── utils.js │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── tsc-transform-imports │ ├── .npmignore │ ├── CHANGELOG.md │ ├── eslint.config.js │ ├── package.json │ ├── project.json │ ├── src │ │ ├── directories.ts │ │ ├── guess-module.ts │ │ └── index.ts │ └── tsconfig.json ├── types │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.js │ ├── index.ts │ ├── package.json │ ├── project.json │ └── tsconfig.json └── utils │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── doc │ ├── Cypress.md │ ├── RBAC.md │ ├── debounce.md │ ├── rbac-flow.svg │ ├── redux.md │ ├── routerParams.md │ ├── useInsightsNavigate.md │ └── useInventory.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ ├── MiddlewareListener │ │ ├── MiddlewareListener.test.ts │ │ ├── MiddlewareListener.ts │ │ └── index.ts │ ├── RBAC │ │ ├── RBAC.test.js │ │ ├── RBAC.ts │ │ └── index.ts │ ├── RBACHook │ │ ├── RBACHook.ts │ │ └── index.ts │ ├── ReducerRegistry │ │ ├── ReducerRegistry.test.ts │ │ ├── ReducerRegistry.ts │ │ └── index.ts │ ├── Registry │ │ ├── Registry.test.tsx │ │ ├── Registry.ts │ │ └── index.ts │ ├── RouterParams │ │ ├── RouterParams.tsx │ │ └── index.ts │ ├── RowLoader │ │ ├── RowLoader.tsx │ │ └── index.ts │ ├── TestingUtils │ │ ├── CypressUtils │ │ │ ├── CustomCommands.js │ │ │ ├── PaginationUtils.js │ │ │ ├── TableUtils.js │ │ │ ├── UIFilters.js │ │ │ ├── index.js │ │ │ └── selectors.js │ │ └── JestUtils │ │ │ ├── TestWrapper.js │ │ │ └── index.js │ ├── debounce │ │ ├── debounce.test.js │ │ ├── debounce.ts │ │ └── index.ts │ ├── helpers │ │ ├── helpers.test.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── urlPathHelpers.test.js │ │ └── urlPathHelpers.ts │ ├── index.scss │ ├── index.ts │ ├── interceptors │ │ ├── index.ts │ │ ├── interceptors.test.js │ │ └── interceptors.ts │ ├── mergeMessages │ │ ├── index.js │ │ └── mergeMessages.js │ ├── parseCvssScore │ │ ├── __snapshots__ │ │ │ └── parseCvssScore.test.js.snap │ │ ├── index.ts │ │ ├── parseCvssScore.test.js │ │ └── parseCvssScore.tsx │ ├── styles │ │ ├── _all.scss │ │ ├── _helpers.scss │ │ ├── _mixins.scss │ │ └── _variables.scss │ ├── useExportPDF │ │ ├── index.ts │ │ ├── useExportPDF.test.js │ │ └── useExportPDF.ts │ ├── useFetchBatched │ │ ├── index.ts │ │ └── useFetchBatched.ts │ ├── useInsightsNavigate │ │ ├── index.ts │ │ ├── useInsightsNavigate.test.js │ │ └── useInsightsNavigate.ts │ ├── useInventory │ │ ├── index.js │ │ └── useInventory.js │ ├── usePromiseQueue │ │ ├── index.ts │ │ └── usePromiseQueue.ts │ └── useSuspenseLoader │ │ ├── index.ts │ │ ├── useSuspenseLoader.test.tsx │ │ └── useSuspenseLoader.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── plugins └── transform-scss-plugin.js ├── project.json ├── tsconfig.base.json └── vitest.workspace.ts /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports ={ 2 | extends: ['@commitlint/config-conventional'], 3 | // Ignore rules can be found here 4 | // https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/is-ignored/src/defaults.ts 5 | defaultIgnores: true, 6 | 'body-max-length': Infinity, 7 | 'body-max-line-length': Infinity, 8 | } 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | esm 4 | dist 5 | build 6 | -------------------------------------------------------------------------------- /.github/actions/cache/action.yaml: -------------------------------------------------------------------------------- 1 | name: Node modules cache 2 | description: Retrieve and cache project node_modules 3 | runs: 4 | using: "composite" 5 | steps: 6 | # cache node modules for all jobs to use 7 | - uses: actions/cache@v4 8 | id: node_modules-cache 9 | with: 10 | path: | 11 | **/node_modules 12 | key: install-cache-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 13 | -------------------------------------------------------------------------------- /.github/actions/cypress-cache/action.yaml: -------------------------------------------------------------------------------- 1 | name: Cypress runner cache 2 | description: Retrieve and cache the cypress runner 3 | runs: 4 | using: "composite" 5 | steps: 6 | # cache cypress runner 7 | - uses: actions/cache@v4 8 | id: cypress-cache 9 | with: 10 | path: ~/.cache/Cypress 11 | key: cypress-runner-cache-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # ide config 4 | .idea/ 5 | .editorconfig 6 | .vscode/ 7 | 8 | # devel 9 | *.js.map 10 | *.css.map 11 | 12 | # dependencies 13 | node_modules 14 | packages/config-utils/repos 15 | 16 | # production 17 | .env 18 | dist 19 | /demo/assets 20 | /**/build 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | /index.js 25 | /index.css 26 | /components/ 27 | /Utilities/ 28 | /charts/ 29 | coverage 30 | .storybook 31 | lerna-debug.log 32 | .DS_Store 33 | packages/**/package-lock.json 34 | packages/**/.cache 35 | *.tgz 36 | !/packages/*/cypress/ 37 | 38 | # Ibutsu test reports 39 | ibutsu-report 40 | 41 | 42 | 43 | .nx/cache 44 | .nx/workspace-data 45 | tmp 46 | 47 | packages/docs/pages/fec 48 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no-install commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | npx --no-install nx affected -t lint 2 | npx --no-install nx affected -t test:unit --exclude=demo 3 | npx --no-install nx affected -t test:component --exclude=demo --parallel=1 4 | npx --no-install nx affected -t build --exclude=demo 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .gitignore 4 | .config 5 | .vscode 6 | node_modules 7 | src 8 | static 9 | .babelrc 10 | .eslintrc 11 | .firebaserc 12 | .prettierignore 13 | .travis.yml 14 | yarn.lock -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | package.json -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "arrowParens": "always", 4 | "semi": true, 5 | "tabWidth": 2, 6 | "singleQuote": true, 7 | "jsxSingleQuote": false, 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /.verdaccio/config.yml: -------------------------------------------------------------------------------- 1 | # path to a directory with all packages 2 | storage: ../tmp/local-registry/storage 3 | 4 | # a list of other known repositories we can talk to 5 | uplinks: 6 | npmjs: 7 | url: https://registry.npmjs.org/ 8 | maxage: 60m 9 | 10 | packages: 11 | '**': 12 | # give all users (including non-authenticated users) full access 13 | # because it is a local registry 14 | access: $all 15 | publish: $all 16 | unpublish: $all 17 | 18 | # if package is not available locally, proxy requests to npm registry 19 | proxy: npmjs 20 | 21 | # log settings 22 | logs: 23 | type: stdout 24 | format: pretty 25 | level: warn 26 | 27 | publish: 28 | allow_offline: true # set offline to true to allow publish offline 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/ubi8/nodejs-16 2 | USER root 3 | WORKDIR /docs 4 | COPY ./packages /docs/packages 5 | COPY ./tsconfig.json /docs/tsconfig.json 6 | # Clear any modules from disk 7 | RUN rm -rf /docs/packages/*/node_modules 8 | WORKDIR /docs/packages/docs 9 | RUN npm i 10 | RUN npm run build 11 | RUN npm i puppeteer 12 | 13 | # install puppeteer/chromium dependencies 14 | RUN dnf install -y bzip2 fontconfig nss.x86_64 pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 libdrm libgbm libxshmfence GConf2 nss libXScrnSaver alsa-lib wget 15 | 16 | EXPOSE 3000 17 | USER 1001 18 | CMD node server.js 19 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM registry.redhat.io/ubi8/nodejs-16 2 | USER root 3 | WORKDIR /docs 4 | COPY ./packages/components /docs/packages/components 5 | COPY ./packages/docs /docs/packages/docs 6 | WORKDIR /docs/packages/docs 7 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/env', 5 | { 6 | targets: '> 0.25%, not dead', 7 | }, 8 | ], 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | # ignore everything in root that will be the destination of build output 2 | /* 3 | 4 | # white list allowed files 5 | !src 6 | !src/ 7 | !src/* 8 | !doc 9 | !doc/ 10 | !doc/* 11 | !config 12 | !config/ 13 | !config/* 14 | !.npmignore 15 | !.gitignore 16 | !babel.config.js 17 | !LICENSE 18 | !package.json 19 | !README.md 20 | !tsconfig.json 21 | !pre-publish.js 22 | 23 | # Incremental ts info 24 | tsconfig.tsbuildinfo 25 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | docs: 4 | build: 5 | context: ./ 6 | dockerfile: Dockerfile.dev 7 | command: sh -c "export CYPRESS_CACHE_FOLDER=/docs/packages/docs/.cache && npm i && npm run generate:components && npm run watch" 8 | ports: 9 | - '3000:3000' 10 | volumes: 11 | - .:/docs 12 | - /docs/packages/docs/node_modules 13 | -------------------------------------------------------------------------------- /docs/frontend-components-config/hot-module-replacement.md: -------------------------------------------------------------------------------- 1 | # HMR (Hot Module Replacement) 2 | 3 | Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways. 4 | 5 | [Read more at webpack documentation.](https://webpack.js.org/concepts/hot-module-replacement/) 6 | 7 | ## Enable HMR 8 | 9 | HMR **is disabled by default**. That is because HMR and module federation can be a bit flaky. Even though it worked in several applications during testing, we keep this feature opt-in, before the stability was validated on more projects. 10 | 11 | To enable the HRM, go to your `fec.config.js` or `dev.webpack.config.js` and add the `hotReload` flag. This flag replaces the deprecated `_unstableHotReload` flag. 12 | 13 | ```js 14 | // fec.config.js 15 | { 16 | // application config 17 | ... 18 | hotReload: true 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/migrations/charts.md: -------------------------------------------------------------------------------- 1 | # Charts 2 | 3 | `@redhat-cloud-services/frontend-components-charts` 4 | 5 | This package is deprecated and no longer used. Please use the official [Patternfly charts](https://www.patternfly.org/charts/about-charts/) package. 6 | 7 | ## SeverityLine 8 | 9 | This component does not have an equivalent PF replacement. The component was moved to the `@redhat-cloud-services/frontend-components` package. 10 | -------------------------------------------------------------------------------- /docs/migrations/frontend-components-config.md: -------------------------------------------------------------------------------- 1 | # Frontend components config migrations 2 | 3 | ## 6.3.x -> 6.4.x 4 | 5 | The configuration is now using data from the Frontend CRD. The Frontend CRD is now mandatory to use the shared build configuration. 6 | 7 | The default location of the CRD is **deploy/frontend.yaml**. If the CRD is not located at this path in your frontend repository, please use the `frontendCRDPath` configuration option in the `fec.config.js` or as an attribute of the create config function if you are using custom webpack configuration. 8 | -------------------------------------------------------------------------------- /docs/migrations/frontend-coomponents-config-utilities.md: -------------------------------------------------------------------------------- 1 | # Frontend components config utilities 2 | 3 | # 4.0.x -> 4.1.x 4 | 5 | The proxy configuration is now using data from the Frontend CRD. The Frontend CRD is now mandatory to use the development proxy. 6 | 7 | The default location of the CRD is **deploy/frontend.yaml**. If the CRD is not located at this path in your frontend repository, please use the `frontendCRDPath` as an attribute of the proxy function if you are using custom webpack configuration. 8 | -------------------------------------------------------------------------------- /docs/migrations/pdf-generator.md: -------------------------------------------------------------------------------- 1 | # PDF Generator 2 | 3 | `@redhat-cloud-services/frontend-components-pdf-generator` 4 | 5 | The pdf generator package is deprecated. Please contact the platform team to learn about the available alternative. 6 | -------------------------------------------------------------------------------- /examples/demo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@nx/react/babel", 5 | { 6 | "runtime": "automatic" 7 | } 8 | ] 9 | ], 10 | "plugins": [] 11 | } 12 | -------------------------------------------------------------------------------- /examples/demo/CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/examples/demo/CHANGELOG.md -------------------------------------------------------------------------------- /examples/demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("eslint/config"); 2 | const nxPlugin = require('@nx/eslint-plugin'); 3 | const fecConfig = require('../../eslint.config'); 4 | const tsPlugin = require('@typescript-eslint/eslint-plugin'); 5 | 6 | module.exports = defineConfig( 7 | // fecConfig, 8 | { 9 | plugins: { 10 | '@nx': nxPlugin, 11 | 'typescript-eslint': tsPlugin, 12 | }, 13 | // "extends": ["@nx/react"], 14 | ignores: ["!**/*"], 15 | } 16 | // { 17 | // "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 18 | // "rules": {} 19 | // }, 20 | // { 21 | // "files": ["*.ts", "*.tsx"], 22 | // "rules": {} 23 | // }, 24 | // { 25 | // "files": ["*.js", "*.jsx"], 26 | // "rules": {} 27 | // } 28 | ) 29 | -------------------------------------------------------------------------------- /examples/demo/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "examples/demo/src", 5 | "projectType": "application", 6 | "tags": ["scope:private"], 7 | "// targets": "to see all targets run: nx show project demo --web", 8 | "targets": {} 9 | } 10 | -------------------------------------------------------------------------------- /examples/demo/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/examples/demo/src/assets/.gitkeep -------------------------------------------------------------------------------- /examples/demo/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/examples/demo/src/favicon.ico -------------------------------------------------------------------------------- /examples/demo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Demo 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import * as ReactDOM from 'react-dom/client'; 3 | import '@patternfly/react-core/dist/styles/base.css'; 4 | 5 | import App from './app/app'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/demo/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] 6 | }, 7 | "exclude": [ 8 | "jest.config.ts", 9 | "src/**/*.spec.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.tsx", 12 | "src/**/*.test.tsx", 13 | "src/**/*.spec.js", 14 | "src/**/*.test.js", 15 | "src/**/*.spec.jsx", 16 | "src/**/*.test.jsx", 17 | "vite.config.ts", 18 | "vitest.config.ts" 19 | ], 20 | "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] 21 | } 22 | -------------------------------------------------------------------------------- /examples/demo/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest", 11 | "@nx/react/typings/cssmodule.d.ts", 12 | "@nx/react/typings/image.d.ts" 13 | ] 14 | }, 15 | "include": [ 16 | "vite.config.ts", 17 | "vitest.config.ts", 18 | "src/**/*.test.ts", 19 | "src/**/*.spec.ts", 20 | "src/**/*.test.tsx", 21 | "src/**/*.spec.tsx", 22 | "src/**/*.test.js", 23 | "src/**/*.spec.js", 24 | "src/**/*.test.jsx", 25 | "src/**/*.spec.jsx", 26 | "src/**/*.d.ts" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /examples/demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; 4 | import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; 5 | 6 | export default defineConfig({ 7 | root: __dirname, 8 | cacheDir: '../../node_modules/.vite/examples/demo', 9 | plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], 10 | // Uncomment this if you are using workers. 11 | // worker: { 12 | // plugins: [ nxViteTsPaths() ], 13 | // }, 14 | test: { 15 | watch: false, 16 | globals: true, 17 | environment: 'jsdom', 18 | include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], 19 | reporters: ['default'], 20 | coverage: { reportsDirectory: '../../coverage/examples/demo', provider: 'v8' }, 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjectsAsync } from '@nx/jest'; 2 | import path from 'path'; 3 | 4 | 5 | console.log({cp: path.resolve(__dirname, '/config/setupTests.js')}) 6 | 7 | export default async () => ({ 8 | projects: [ 9 | ...(await getJestProjectsAsync()), 10 | ], 11 | setupFilesAfterEnv: [path.resolve(__dirname, './config/setupTests.js'), 'jest-canvas-mock'] 12 | }); 13 | 14 | // export default { 15 | // projects: getJestProjectsAsync(), 16 | // setupFilesAfterEnv: ['/config/setupTests.js', 'jest-canvas-mock'], 17 | // global: { 18 | // fetch: global.fetch, 19 | // insights: { 20 | // chrome: { 21 | // foobar: 'baz' 22 | // } 23 | // } 24 | // } 25 | // }; 26 | -------------------------------------------------------------------------------- /locales/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "default.cancel": "Zrušit", 3 | "default.save": "Uložit", 4 | "default.delete": "Smazat", 5 | "default.remove": "Odstranit" 6 | } 7 | -------------------------------------------------------------------------------- /locales/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "en": { 3 | "default.cancel": "Cancel", 4 | "default.save": "Save", 5 | "default.delete": "Delete", 6 | "default.remove": "Remove" 7 | }, 8 | "cs": { 9 | "default.cancel": "Zrušit", 10 | "default.save": "Save", 11 | "default.delete": "Smazat", 12 | "default.remove": "Odstranit" 13 | } 14 | } -------------------------------------------------------------------------------- /locales/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "default.cancel": "Cancel", 3 | "default.save": "Save", 4 | "default.delete": "Delete", 5 | "default.remove": "Remove" 6 | } -------------------------------------------------------------------------------- /packages/advisor-components/.npmignore: -------------------------------------------------------------------------------- 1 | !components 2 | !index.js 3 | !index.css 4 | src/ 5 | .babelrc 6 | babel.config.js 7 | doc/ 8 | config/ 9 | tsconfig.json 10 | tsconfig.cjs.json 11 | tsconfig.esm.json 12 | .cypress-cache 13 | pre-publish.js 14 | -------------------------------------------------------------------------------- /packages/advisor-components/cypress/fixtures/rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "rule_id": "external.rules.rule|ERROR_KEY", 3 | "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 4 | "generic": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 5 | "reason": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 6 | "resolution": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", 7 | "more_info": "", 8 | "total_risk": 2, 9 | "risk_of_change": 1, 10 | "impact": { "impact": 2 }, 11 | "likelihood": 3, 12 | "publish_date": "2021-11-01T14:00:00Z", 13 | "tags": ["fault_tolerance", "openshift", "sap"], 14 | "rating": 1, 15 | "impacted_clusters_count": 0, 16 | "disabled": false, 17 | "reboot_required": true 18 | } 19 | -------------------------------------------------------------------------------- /packages/advisor-components/cypress/overrideChrome.ts: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | updateDocumentTitle: () => undefined, 3 | isBeta: () => false, 4 | isProd: () => true, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/advisor-components/cypress/snapshots/src/ReportDetails/ReportDetails.spec.ct.js/report details kba loaded -- renders component and matches screenshot.snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/advisor-components/cypress/snapshots/src/ReportDetails/ReportDetails.spec.ct.js/report details kba loaded -- renders component and matches screenshot.snap.png -------------------------------------------------------------------------------- /packages/advisor-components/cypress/support/component-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Components App 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /packages/advisor-components/cypress/support/component.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace Cypress { 3 | interface Chainable { 4 | mount: typeof mount; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/advisor-components/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ["!**/*", "**/*.scss", "**/*.png"] 6 | }) 7 | -------------------------------------------------------------------------------- /packages/advisor-components/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-advisor-components', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/advisor-components', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RebootRequired/RebootRequired.scss: -------------------------------------------------------------------------------- 1 | .system-reboot-message { 2 | display: inline-flex; 3 | 4 | .system-reboot-message__content { 5 | position: relative; 6 | } 7 | 8 | .reboot-required-icon { 9 | margin-top: 5px; 10 | margin-right: var(--pf-t--global--spacer--sm); 11 | color: var(--pf-t--global--color--status--danger--default); 12 | } 13 | 14 | .no-reboot-required-icon { 15 | margin-top: 5px; 16 | margin-right: var(--pf-t--global--spacer--sm); 17 | color: var(--pf-t--global--color--nonstatus--gray--default); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RebootRequired/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RebootRequired'; 2 | export { default as RebootRequired } from './RebootRequired'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/ReportDetails/__image_snapshots__/report details kba loaded renders component and matches screenshot #0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/advisor-components/src/ReportDetails/__image_snapshots__/report details kba loaded renders component and matches screenshot #0.png -------------------------------------------------------------------------------- /packages/advisor-components/src/ReportDetails/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ReportDetails'; 2 | export { default as ReportDetails } from './ReportDetails'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleDescription/RuleDescription.scss: -------------------------------------------------------------------------------- 1 | .ins-c-generic__override { 2 | p { 3 | margin-top: 0; 4 | margin-bottom: var(--pf-t--global--spacer--md); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleDescription/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RuleDescription'; 2 | export { default as RuleDescription } from './RuleDescription'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleDetails/RuleDetails.scss: -------------------------------------------------------------------------------- 1 | .ins-c-line { 2 | border: 0.01rem solid var(--pf-t--global--border--color--100); 3 | } 4 | 5 | .ins-c-rule-details__stack { 6 | width: 600px; 7 | .pf-v6-c-content { 8 | font-size: var(--pf-t--global--font--size--sm); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleDetails/RuleDetailsMessages.ts: -------------------------------------------------------------------------------- 1 | export type Message = React.ReactNode; 2 | export type RuleDetailsMessages = { 3 | systemReboot: Message; 4 | knowledgebaseArticle: Message; 5 | totalRisk: Message; 6 | rulesDetailsTotalRiskBody: Message; 7 | likelihoodLevel: string; 8 | likelihoodDescription: Message; 9 | impactLevel: string; 10 | impactDescription: Message; 11 | riskOfChange: Message; 12 | riskOfChangeText: Message; 13 | riskOfChangeLabel: Message; 14 | ruleHelpful: Message; 15 | feedbackThankYou: Message; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleDetails/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RuleDetails'; 2 | export { default as RuleDetails } from './RuleDetails'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleRating/RuleRating.scss: -------------------------------------------------------------------------------- 1 | .ins-c-like { 2 | color: var(--pf-t--global--color--status--success--default); 3 | } 4 | 5 | .ins-c-dislike { 6 | color: var(--pf-t--global--text--color--regular); 7 | } 8 | 9 | .ratingSpanOverride { 10 | font-size: var(--pf-t--global--font--size--sm) !important; 11 | button { 12 | padding: 8px; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/advisor-components/src/RuleRating/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RuleRating'; 2 | export { default as RuleRating } from './RuleRating'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/TemplateProcessor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TemplateProcessor'; 2 | export { default as TemplateProcessor } from './TemplateProcessor'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/ViewAffectedLink/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ViewAffectedLink'; 2 | export { default as ViewAffectedLink } from './ViewAffectedLink'; 3 | -------------------------------------------------------------------------------- /packages/advisor-components/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RuleDetails'; 2 | export * from './RebootRequired'; 3 | export * from './RuleRating'; 4 | export * from './types'; 5 | export * from './common'; 6 | export * from './constants'; 7 | export * from './ReportDetails'; 8 | -------------------------------------------------------------------------------- /packages/advisor-components/src/modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@redhat-cloud-services/frontend-components-charts/SeverityLine'; 2 | -------------------------------------------------------------------------------- /packages/advisor-components/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/advisor-components/tsconfig.cy.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["cypress", "node", "./cypress/support/component.d.ts"], 5 | "resolveJsonModule": true 6 | }, 7 | "include": [ 8 | "./cypress/**/*.tsx", 9 | "./cypress/**/*.ts", 10 | "./cypress/**/*.js", 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/advisor-components/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts", "./src/**/*.js"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.js", "src/**/*.test.js", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/advisor-components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | }, 20 | { 21 | "path": "./tsconfig.cy.json" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/advisor-components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/chrome/.npmignore: -------------------------------------------------------------------------------- 1 | !components 2 | !index.js 3 | !index.css 4 | src/ 5 | .babelrc 6 | babel.config.js 7 | doc/ 8 | config/ 9 | tsconfig.json 10 | pre-publish.js 11 | */**/__mocks__ 12 | tsconfig.* 13 | -------------------------------------------------------------------------------- /packages/chrome/README.md: -------------------------------------------------------------------------------- 1 | # Chrome package 2 | 3 | This package is intended to be used as a public interface to all shared data or functions exposed by chrome to its modules 4 | 5 | ## Installation: TDB 6 | 7 | ## Development: TDB 8 | -------------------------------------------------------------------------------- /packages/chrome/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ["!**/*"] 6 | }) 7 | -------------------------------------------------------------------------------- /packages/chrome/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/chrome', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/chrome', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/chrome/src/ChromeContext/ChromeContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import chromeState from '../ChromeProvider/chromeState'; 3 | 4 | const ChromeContext = createContext>({ 5 | update: () => undefined, 6 | setLastVisited: () => undefined, 7 | setFavoritePages: () => undefined, 8 | subscribe: () => Symbol(0), 9 | unsubscribe: () => undefined, 10 | setIdentity: () => undefined, 11 | setVisitedBundles: () => undefined, 12 | getState: () => ({ 13 | lastVisitedPages: [], 14 | subscribtions: {}, 15 | favoritePages: [], 16 | visitedBundles: {}, 17 | initialized: false, 18 | }), 19 | }); 20 | 21 | export default ChromeContext; 22 | -------------------------------------------------------------------------------- /packages/chrome/src/ChromeContext/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ChromeContext'; 2 | export { default as ChromeContext } from './ChromeContext'; 3 | -------------------------------------------------------------------------------- /packages/chrome/src/ChromeProvider/__mocks__/@unleash/proxy-client-react.js: -------------------------------------------------------------------------------- 1 | function useFlag() { 2 | // platform.chrome.chrome-service flag 3 | return true; 4 | } 5 | module.exports.useFlag = useFlag; 6 | -------------------------------------------------------------------------------- /packages/chrome/src/ChromeProvider/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ChromeProvider } from './ChromeProvider'; 2 | export { default } from './ChromeProvider'; 3 | export { UserIdentity, UpdateEvents, LastVisitedPage, FavoritePage, VisitedBundles } from './chromeState'; 4 | -------------------------------------------------------------------------------- /packages/chrome/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ChromeProvider'; 2 | export * from './ChromeContext'; 3 | export * from './useLastVisited'; 4 | export * from './useFavoritePages'; 5 | export * from './useVisitedBundles'; 6 | -------------------------------------------------------------------------------- /packages/chrome/src/useFavoritePages/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useFavoritePages'; 2 | export { default as useFavoritePages } from './useFavoritePages'; 3 | -------------------------------------------------------------------------------- /packages/chrome/src/useLastVisited/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useLastVisited'; 2 | export { default as useLastVisited } from './useLastVisited'; 3 | -------------------------------------------------------------------------------- /packages/chrome/src/useLastVisited/useLastVisited.ts: -------------------------------------------------------------------------------- 1 | import { useContext, useEffect, useReducer } from 'react'; 2 | 3 | import { ChromeContext } from '../ChromeContext'; 4 | import { UpdateEvents } from '../ChromeProvider'; 5 | 6 | const useLastVisited = () => { 7 | const { subscribe, unsubscribe, getState } = useContext(ChromeContext); 8 | const [, forceRender] = useReducer((count) => count + 1, 0); 9 | 10 | useEffect(() => { 11 | const subsId = subscribe(UpdateEvents.lastVisited, forceRender); 12 | return () => { 13 | unsubscribe(subsId, UpdateEvents.lastVisited); 14 | }; 15 | }, []); 16 | return getState().lastVisitedPages ?? []; 17 | }; 18 | 19 | export default useLastVisited; 20 | -------------------------------------------------------------------------------- /packages/chrome/src/useVisitedBundles/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useVisitedBundles'; 2 | export { default as useVisitedBundles } from './useVisitedBundles'; 3 | -------------------------------------------------------------------------------- /packages/chrome/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/chrome/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/chrome/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/chrome/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/components/.npmignore: -------------------------------------------------------------------------------- 1 | !components 2 | !index.js 3 | !index.css 4 | src/ 5 | .babelrc 6 | babel.config.js 7 | doc/ 8 | config/ 9 | tsconfig.json 10 | pre-publish.js 11 | .cypress-cache/ 12 | cypress/ 13 | tsconfig* 14 | -------------------------------------------------------------------------------- /packages/components/cypres.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress'; 2 | import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing'; 3 | import webpackConfig from '../../cypress.webpack.config'; 4 | 5 | const presets = nxComponentTestingPreset(__filename, { 6 | bundler: 'webpack', 7 | }); 8 | 9 | export default defineConfig({ 10 | component: { 11 | ...presets, 12 | specPattern: 'cypress/**/*.cy.{js,jsx,ts,tsx}', 13 | devServer: { 14 | ...presets.devServer, 15 | webpackConfig, 16 | }, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /packages/components/cypress/component/ConditionalFilter/TextFilter.spec.cy.js: -------------------------------------------------------------------------------- 1 | import Text from '../../../src/ConditionalFilter/TextFilter'; 2 | 3 | describe('TextFilter component', () => { 4 | it('renders empty', () => { 5 | cy.mount(); 6 | cy.get('.ins-c-conditional-filter'); 7 | }); 8 | 9 | it('renders disabled with placeholder', () => { 10 | cy.mount(); 11 | cy.get('.ins-c-conditional-filter input').should('be.disabled'); 12 | cy.get('.ins-c-conditional-filter input').invoke('attr', 'placeholder').should('contain', 'foo'); 13 | }); 14 | 15 | it('onChange called', () => { 16 | const ocSpy = cy.spy().as('cSpy'); 17 | cy.mount(); 18 | cy.get('.ins-c-conditional-filter').type('foo'); 19 | cy.get('@cSpy').should('have.been.called'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/components/cypress/component/PrimaryToolbar/SortBy.spec.cy.tsx: -------------------------------------------------------------------------------- 1 | import { SortByDirection } from '@patternfly/react-table'; 2 | import { SortBy } from '../../../src/PrimaryToolbar'; 3 | 4 | describe('SortBy component', () => { 5 | it('renders empty component', () => { 6 | cy.mount(); 7 | cy.get('.pf-v6-c-button'); 8 | }); 9 | 10 | it('renders with direction set', () => { 11 | cy.mount(); 12 | cy.get('.pf-v6-c-button'); 13 | }); 14 | 15 | it('onSortChange is called', () => { 16 | const sortSpy = cy.spy().as('sortSpy'); 17 | cy.mount(); 18 | cy.get('.pf-v6-c-button').click(); 19 | cy.get('@sortSpy').should('have.been.called'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/components/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/cypress/plugins/index.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/components/cypress/plugins/index.d.ts -------------------------------------------------------------------------------- /packages/components/cypress/plugins/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/components/cypress/plugins/index.js -------------------------------------------------------------------------------- /packages/components/cypress/support/commands.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/components/cypress/support/commands.d.ts -------------------------------------------------------------------------------- /packages/components/cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /packages/components/cypress/support/component-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Components App 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /packages/components/cypress/support/component.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace Cypress { 3 | interface Chainable { 4 | mount: typeof mount; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/components/doc/ansible.md: -------------------------------------------------------------------------------- 1 | # Ansible Icon 2 | 3 | Implementation of 'ansible' icon that represent levels of severity. 4 | 5 | ## Usage 6 | 7 | Import Ansible and styles from this package. 8 | 9 | ```JSX 10 | import React from 'react'; 11 | import { Ansible } from '@redhat-cloud-services/frontend-components'; 12 | 13 | class YourCmp extends React.Component { 14 | render() { 15 | return ( 16 | { /* Default is true*/ } 17 | 18 | 19 | { /* Unsupported */ } 20 | 21 | ) 22 | } 23 | } 24 | ``` 25 | 26 | ## Props 27 | 28 | Ansible 29 | 30 | ```javascript 31 | { 32 | unsupported: propTypes.bool 33 | }; 34 | ``` 35 | -------------------------------------------------------------------------------- /packages/components/doc/dark.md: -------------------------------------------------------------------------------- 1 | # Dark Theme 2 | 3 | Switch the theme to Dark 4 | 5 | ## Usage 6 | 7 | Import Dark Component and wrap your page with it. 8 | 9 | Supports `
` and `` 10 | 11 | ```JSX 12 | import React from 'react'; 13 | import { Dark } from '@redhat-cloud-services/frontend-components'; 14 | 15 | class YourCmp extends React.Component { 16 | render() { 17 | return ( 18 | 19 | 20 | 21 | 22 |
23 | . . . 24 |
25 | 26 |
27 | ) 28 | } 29 | } 30 | ``` 31 | 32 | ## Props 33 | 34 | Dark 35 | 36 | ```javascript 37 | { 38 | children: propTypes.node 39 | }; 40 | ``` 41 | -------------------------------------------------------------------------------- /packages/components/doc/input.md: -------------------------------------------------------------------------------- 1 | # Input 2 | This component will help when using input with any type you want. You don't have to worry about applied classes, just 3 | pass prop `type` and this component will decide which classes to apply. 4 | 5 | ### Usage 6 | Import Input component and it's styles, pass which type you want to use (defaults to `text`) and use as you'd use basic 7 | HTML `input`. 8 | ```javascript 9 | import { Input } from '@redhat-cloud-services/frontend-components'; 10 | import '@redhat-cloud-services/frontend-components/components/Input.css' 11 | import React from 'react'; 12 | 13 | const MyCmp = () => ( 14 |
15 | 16 | 17 | 18 |
19 | ) 20 | 21 | ``` 22 | 23 | ### Props 24 | -------------------------------------------------------------------------------- /packages/components/doc/maintenance.md: -------------------------------------------------------------------------------- 1 | # Maintenance 2 | 3 | ## Props 4 | 5 | |name|type|required|default| 6 | |---|---|---|---| 7 | |utcStartTime|string|`false`|10am| 8 | |utcEndTime|string|`false`|12am| 9 | |startTime|string|`false`|6am| 10 | |endTime|string|`false`|8am| 11 | |timeZone|string|`false`|EST| 12 | |description|node|`false`|`Description`| 13 | |redirectLink|string|`false`|https://status.redhat.com/incidents| 14 | |title|node|`false`|Maintenance in progress| 15 | |className|string|`false`|`undefined`| 16 | -------------------------------------------------------------------------------- /packages/components/doc/openSourceBadge.md: -------------------------------------------------------------------------------- 1 | # Open Source Badge 2 | 3 | The open source badge serves two purposes: 4 | 1. Informs our users that the service they are using is open source. 5 | 2. Guides developers to the project's repositories for the purposes of code inspection or contribution. 6 | 7 | ## Usage 8 | 9 | Import OpenSourceBadge from this package and display it in a prominent location on your application's landing page. 10 | 11 | ## Props 12 | 13 | OpenSourceBadge 14 | ```javascript 15 | { 16 | repositoriesURL: PropTypes.string 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/components/doc/page_header.md: -------------------------------------------------------------------------------- 1 | # Page Header -------------------------------------------------------------------------------- /packages/components/doc/reboot.md: -------------------------------------------------------------------------------- 1 | # Reboot 2 | 3 | Implementation of 'reboot' icon with a label 4 | 5 | ## Usage 6 | 7 | Import Reboot and styles from this package. 8 | 9 | ```JSX 10 | import React from 'react'; 11 | import { Reboot } from '@redhat-cloud-services/frontend-components'; 12 | 13 | class YourCmp extends React.Component { 14 | render() { 15 | return ( 16 | 17 | 18 | // if you want it to be red: 19 | 20 | ) 21 | } 22 | } 23 | ``` 24 | 25 | ## Props 26 | 27 | Reboot 28 | 29 | ```javascript 30 | { 31 | className: propTypes.string 32 | red: propTypes.string 33 | }; 34 | ``` 35 | -------------------------------------------------------------------------------- /packages/components/doc/sample.md: -------------------------------------------------------------------------------- 1 | # Sample Component -------------------------------------------------------------------------------- /packages/components/doc/section.md: -------------------------------------------------------------------------------- 1 | # Section -------------------------------------------------------------------------------- /packages/components/doc/spinner.md: -------------------------------------------------------------------------------- 1 | # Spinner 2 | 3 | This component is a loading state 4 | 5 | ## Usage 6 | 7 | Import Spinner from this package. 8 | 9 | ```JSX 10 | import React from 'react'; 11 | import { Spinner } from '@redhat-cloud-services/frontend-components'; 12 | 13 | class YourCmp extends React.Component { 14 | render() { 15 | return ( 16 | 17 | 18 | ) 19 | } 20 | } 21 | ``` 22 | 23 | ## Props 24 | 25 | ```javascript 26 | { 27 | className: propTypes.string, 28 | centered: propTypes.bool 29 | }; 30 | ``` 31 | -------------------------------------------------------------------------------- /packages/components/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config'); 2 | const fecConfig = require('../../eslint.config'); 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ['!**/*', '**/*.scss'], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/components/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/components', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/components/src/Ansible/Ansible.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AnsiblePF, { AnsibleProps } from '@patternfly/react-component-groups/dist/dynamic/Ansible'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated Ansible import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const Ansible: React.FunctionComponent = (props) => ; 9 | 10 | export default Ansible; 11 | -------------------------------------------------------------------------------- /packages/components/src/Ansible/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/Ansible'; 2 | export { default } from './Ansible'; 3 | export { default as Ansible } from './Ansible'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Battery/Battery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity, { SeverityProps } from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated Battery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const Battery: React.FunctionComponent = Severity; 9 | 10 | export default Battery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/CriticalBattery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity, { SeverityProps } from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated CriticalBattery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const CriticalBattery: React.FunctionComponent = (props) => ; 9 | 10 | export default CriticalBattery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/HighBattery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity, { SeverityProps } from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated HighBattery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const HighBattery: React.FunctionComponent = (props) => ; 9 | 10 | export default HighBattery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/LowBattery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity, { SeverityProps } from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated LowBattery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const LowBattery: React.FunctionComponent = (props) => ; 9 | 10 | export default LowBattery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/MediumBattery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity, { SeverityProps } from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated MediumBattery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const MediumBattery: React.FunctionComponent = (props) => ; 9 | 10 | export default MediumBattery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/NullBattery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Severity from '@patternfly/react-component-groups/dist/dynamic/Severity'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated NullBattery import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const NullBattery: React.FunctionComponent = (props) => ; 9 | 10 | export default NullBattery; 11 | -------------------------------------------------------------------------------- /packages/components/src/Battery/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/Severity'; 2 | export { default } from './Battery'; 3 | export { default as Battery } from './Battery'; 4 | export { default as CriticalBattery } from './CriticalBattery'; 5 | export { default as HighBattery } from './HighBattery'; 6 | export { default as MediumBattery } from './MediumBattery'; 7 | export { default as LowBattery } from './LowBattery'; 8 | export { default as NullBattery } from './NullBattery'; 9 | -------------------------------------------------------------------------------- /packages/components/src/Breadcrumbs/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Breadcrumbs'; 2 | export { default as Breadcrumbs } from './Breadcrumbs'; 3 | export { default as ConnectedBreadcrumbs } from './ConnectedBreadcrumbs'; 4 | -------------------------------------------------------------------------------- /packages/components/src/BulkSelect/bulk-select.scss: -------------------------------------------------------------------------------- 1 | .ins-c-bulk-select { 2 | .pf-v6-c-dropdown__toggle-check span.pf-v6-c-dropdown__toggle-text { 3 | display: initial; 4 | } 5 | .ins-c-bulk-select__selected { 6 | display: none; 7 | } 8 | } 9 | 10 | @media only screen and (max-width: 768px) { 11 | .ins-c-bulk-select { 12 | .pf-v6-c-dropdown__toggle-check span.pf-v6-c-dropdown__toggle-text { 13 | display: none; 14 | } 15 | .ins-c-bulk-select__selected { 16 | display: initial; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/components/src/BulkSelect/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './BulkSelect'; 2 | export { default as BulkSelect } from './BulkSelect'; 3 | export * from './BulkSelect'; 4 | -------------------------------------------------------------------------------- /packages/components/src/ConditionalFilter/conditionalFilterConstants.test.js: -------------------------------------------------------------------------------- 1 | import { conditionalFilterType, typeMapper } from './conditionalFilterConstants'; 2 | 3 | it('should have correct types', () => { 4 | expect(Object.values(conditionalFilterType).length).toBe(6); 5 | }); 6 | 7 | it('should return correct type', () => { 8 | expect(typeMapper.checkbox.name).toBe('CheckboxFilter'); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/components/src/ConditionalFilter/groupType.ts: -------------------------------------------------------------------------------- 1 | enum GroupType { 2 | treeView = 'treeView', 3 | checkbox = 'checkbox', 4 | radio = 'radio', 5 | button = 'button', 6 | plain = 'plain', 7 | } 8 | 9 | export default GroupType; 10 | -------------------------------------------------------------------------------- /packages/components/src/CullingInfo/CullingInformation.scss: -------------------------------------------------------------------------------- 1 | .ins-c-inventory__culling-warning { color: var(--pf-t--global--color--status--warning--default); } 2 | 3 | .ins-c-inventory__culling-danger { color: var(--pf-t--global--color--status--danger--default); } 4 | 5 | .ins-c-inventory__culling-danger, .ins-c-inventory__culling-warning { 6 | font-weight: var(--pf-t--global--font--weight--body--bold); 7 | svg { 8 | margin-right: var(--pf-t--global--spacer--sm); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/components/src/CullingInfo/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CullingInformation'; 2 | export { default as CullingInformation } from './CullingInformation'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Dark/Dark.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ThemeContext from './DarkContext'; 3 | 4 | const DarkContext: React.FunctionComponent = ({ children, ...props }) => ( 5 | 6 | {children} 7 | 8 | ); 9 | 10 | export default DarkContext; 11 | -------------------------------------------------------------------------------- /packages/components/src/Dark/DarkContext.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import Dark from './Dark'; 4 | import DarkContext from './DarkContext'; 5 | 6 | describe('DarkContext', () => { 7 | it('should render children', () => { 8 | const { container } = render( 9 | 10 |
11 | , 12 | ); 13 | 14 | expect(container).toMatchSnapshot(); 15 | expect(container.querySelector('#isPresent')).toBeDefined(); 16 | }); 17 | 18 | it('should pass props', () => { 19 | const { container } = render( 20 | 21 | {(value) =>
} 22 | , 23 | ); 24 | expect(container).toMatchSnapshot(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/components/src/Dark/DarkContext.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export type IDarkContext = 'light' | 'dark'; 4 | 5 | const DarkContext = React.createContext('light'); 6 | export default DarkContext; 7 | -------------------------------------------------------------------------------- /packages/components/src/Dark/__snapshots__/DarkContext.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`DarkContext should pass props 1`] = ` 4 |
5 |
9 |
10 | `; 11 | 12 | exports[`DarkContext should render children 1`] = ` 13 |
14 |
17 |
18 | `; 19 | -------------------------------------------------------------------------------- /packages/components/src/Dark/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Dark'; 2 | export { default as Dark } from './Dark'; 3 | export { default as DarkContext } from './DarkContext'; 4 | -------------------------------------------------------------------------------- /packages/components/src/DateFormat/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DateFormat'; 2 | export { default as DateFormat } from './DateFormat'; 3 | export * from './DateFormat'; 4 | export * from './helper'; 5 | -------------------------------------------------------------------------------- /packages/components/src/DownloadButton/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DownloadButton'; 2 | export { default as DownloadButton } from './DownloadButton'; 3 | export * from './DownloadButton'; 4 | -------------------------------------------------------------------------------- /packages/components/src/EmptyTable/EmptyTable.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | .ins-c-table__empty { 4 | background: var(--pf-t--global--background--color--primary--default); 5 | border-bottom: 1px solid var(--pf-t--global--background--color--secondary--default); 6 | @include m.rem('padding', 20px); 7 | &.is-centered { 8 | display: flex; 9 | justify-content: center; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/src/EmptyTable/EmptyTable.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import EmptyTable from './EmptyTable'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('EmptyTable component', () => { 6 | it('should render', () => { 7 | const { container } = render(Some); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | 11 | it('should render with centered children', () => { 12 | const { container } = render(Centered); 13 | expect(container).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/components/src/EmptyTable/EmptyTable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import classNames from 'classnames'; 4 | 5 | import './EmptyTable.scss'; 6 | 7 | export interface EmptyTableProps extends React.DetailedHTMLProps, HTMLDivElement> { 8 | centered?: boolean; 9 | className?: string; 10 | } 11 | 12 | const EmptyTable: React.FunctionComponent = ({ centered, className, children, ...props }) => { 13 | const emptyTableClasses = classNames('ins-c-table__empty', { [`is-centered`]: centered }, className); 14 | 15 | return ( 16 |
17 | {' '} 18 | {children} 19 |
20 | ); 21 | }; 22 | 23 | export default EmptyTable; 24 | -------------------------------------------------------------------------------- /packages/components/src/EmptyTable/__snapshots__/EmptyTable.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`EmptyTable component should render 1`] = ` 4 |
5 |
8 | 9 | Some 10 |
11 |
12 | `; 13 | 14 | exports[`EmptyTable component should render with centered children 1`] = ` 15 |
16 |
19 | 20 | Centered 21 |
22 |
23 | `; 24 | -------------------------------------------------------------------------------- /packages/components/src/EmptyTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EmptyTable'; 2 | export { default as EmptyTable } from './EmptyTable'; 3 | -------------------------------------------------------------------------------- /packages/components/src/ErrorBoundary/ErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ErrorBoundaryPF, { ErrorBoundaryProps } from '@patternfly/react-component-groups/dist/dynamic/ErrorBoundary'; 3 | import { DefaultErrorMessage } from '../ErrorState'; 4 | 5 | /** 6 | * @deprecated Do not use deprecated ErrorBoundary import, the component has been moved to @patternfly/react-component-groups 7 | */ 8 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 9 | const ErrorBoundary: React.FunctionComponent = (props) => ( 10 | } {...props} /> 11 | ); 12 | 13 | export default ErrorBoundary; 14 | -------------------------------------------------------------------------------- /packages/components/src/ErrorBoundary/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/ErrorBoundary'; 2 | export { default } from './ErrorBoundary'; 3 | export { default as ErrorBoundary } from './ErrorBoundary'; 4 | -------------------------------------------------------------------------------- /packages/components/src/ErrorState/DefaultErrorMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const DefaultErrorMessage: React.FunctionComponent = () => { 4 | const redirectLink = 'https://access.redhat.com/support'; 5 | const statusLink = 'https://status.redhat.com'; 6 | 7 | return ( 8 | <> 9 | If the problem persists, contact Red Hat Support or check our status page for known 10 | outages. 11 | 12 | ); 13 | }; 14 | 15 | export default DefaultErrorMessage; 16 | -------------------------------------------------------------------------------- /packages/components/src/ErrorState/ErrorState.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ErrorStatePF, { ErrorStateProps } from '@patternfly/react-component-groups/dist/dynamic/ErrorState'; 3 | import DefaultErrorMessage from './DefaultErrorMessage'; 4 | 5 | /** 6 | * @deprecated Do not use deprecated ErrorState import, the component has been moved to @patternfly/react-component-groups 7 | */ 8 | const ErrorState: React.FunctionComponent = (props) => } {...props} />; 9 | 10 | export default ErrorState; 11 | -------------------------------------------------------------------------------- /packages/components/src/ErrorState/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/ErrorState'; 2 | export { default } from './ErrorState'; 3 | export { default as ErrorState } from './ErrorState'; 4 | export { default as DefaultErrorMessage } from './DefaultErrorMessage'; 5 | -------------------------------------------------------------------------------- /packages/components/src/FilterChips/filter-chips.scss: -------------------------------------------------------------------------------- 1 | .ins-c-chip-filters .ins-c-chip-group__plain.pf-m-toolbar > li:not(.pf-m-overflow) { 2 | background: none; 3 | padding: 0; 4 | background-color: initial; 5 | h4 { 6 | display: none; 7 | } 8 | } 9 | 10 | .ins-c-chip-filters { 11 | .pf-v6-c-chip-group:not(:last-child) { 12 | margin-right: var(--pf-t--global--spacer--sm); 13 | } 14 | } 15 | 16 | .ins-c-chip-filters .pf-v6-c-chip .pf-v6-c-badge { 17 | margin-left: var(--pf-t--global--spacer--xs); 18 | } 19 | -------------------------------------------------------------------------------- /packages/components/src/FilterChips/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './FilterChips'; 2 | export { default as FilterChips } from './FilterChips'; 3 | export * from './FilterChips'; 4 | -------------------------------------------------------------------------------- /packages/components/src/FilterHooks/index.ts: -------------------------------------------------------------------------------- 1 | export { useTagsFilter as default } from './tagFilterHook'; 2 | export * from './tagFilterHook'; 3 | export * from './constants'; 4 | -------------------------------------------------------------------------------- /packages/components/src/FilterHooks/tagFilterHook.scss: -------------------------------------------------------------------------------- 1 | .ins-c-tagfilter { 2 | .ins-c-tagfilter__option label { 3 | display: flex; 4 | width: 100%; 5 | .ins-c-tagfilter__option-value { 6 | max-width: 12.5rem; 7 | overflow: hidden; 8 | text-overflow: ellipsis; 9 | } 10 | .pf-v6-c-badge { 11 | margin-left: auto; 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | } 16 | } 17 | .pf-v6-c-select__menu-group-title:empty { display: none; } 18 | 19 | .pf-v6-c-select__menu > div { padding-top: 0; } 20 | 21 | &.pf-m-expanded { width: 18.75rem !important; } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/Filters/FilterDropdown.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import FilterDropdown from './FilterDropdown'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('FilterDropdown component', () => { 6 | const defaultProps = { 7 | filters: {}, 8 | addFilter: jest.fn(), 9 | removeFilter: jest.fn(), 10 | filterCategories: [{ title: '', type: '', urlParam: '', values: [{ label: '', value: '' }] }], 11 | }; 12 | 13 | it('should render', () => { 14 | const { container } = render(); 15 | expect(container).toMatchSnapshot(); 16 | }); 17 | 18 | it('should render with a component as label', () => { 19 | const { container } = render(} />); 20 | expect(container).toMatchSnapshot(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/components/src/Filters/FilterInput.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import FilterInput from './FilterInput'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('FilterInput component', () => { 6 | it('should render a radio input', () => { 7 | const { container } = render( 8 | , 18 | ); 19 | expect(container).toMatchSnapshot(); 20 | }); 21 | it('should render a checkbox input', () => { 22 | const { container } = render( 23 | , 24 | ); 25 | expect(container).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/components/src/Filters/filter-dropdown.scss: -------------------------------------------------------------------------------- 1 | .ins-c-filter__dropdown .pf-v6-c-dropdown__menu-item { 2 | &:hover { 3 | background-color: inherit !important; 4 | outline: inherit !important; 5 | } 6 | &:focus { 7 | background-color: inherit !important; 8 | outline: inherit !important; 9 | } 10 | } -------------------------------------------------------------------------------- /packages/components/src/Filters/filter-input.scss: -------------------------------------------------------------------------------- 1 | .ins-c-filter-input__checkbox { 2 | // ensure the entire item is clickable 3 | display: flex !important; 4 | > label { 5 | flex: 1; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/components/src/Filters/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FilterDropdown } from './FilterDropdown'; 2 | export { default as FilterInput } from './FilterInput'; 3 | -------------------------------------------------------------------------------- /packages/components/src/InsightsLabel/InsightsLabel.test.js: -------------------------------------------------------------------------------- 1 | import InsightsLabel from './InsightsLabel'; 2 | import React from 'react'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('InsightsLabel component', () => { 6 | it('should render with icon', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | it('should render without icon', () => { 11 | const { container } = render(); 12 | expect(container).toMatchSnapshot(); 13 | }); 14 | it('should render defaults', () => { 15 | const { container } = render(); 16 | expect(container).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/components/src/InsightsLabel/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InsightsLabel'; 2 | export { default as InsightsLabel } from './InsightsLabel'; 3 | -------------------------------------------------------------------------------- /packages/components/src/InsightsLink/InsightsLink.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link, LinkProps } from 'react-router-dom'; 3 | import useChrome from '../useChrome'; 4 | import { buildInsightsPath } from '@redhat-cloud-services/frontend-components-utilities/helpers/urlPathHelpers'; 5 | interface InsightsLinkProps { 6 | to: LinkProps['to']; 7 | app: string; 8 | preview: boolean; 9 | } 10 | 11 | const InsightsLink: React.FC> = ({ to, app, preview, ...props }) => { 12 | const chrome = useChrome(); 13 | const toPath = buildInsightsPath(chrome, app, to, preview); 14 | 15 | return ( 16 | 17 | {props.children} 18 | 19 | ); 20 | }; 21 | 22 | export default InsightsLink; 23 | -------------------------------------------------------------------------------- /packages/components/src/InsightsLink/__snapshots__/InsightsLink.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`InsightsLink component under / should render a link to /preview with a given path 1`] = ` 4 |
5 | Mocked Link 6 |
7 | `; 8 | 9 | exports[`InsightsLink component under / should render a link to a different app in preview when given 1`] = ` 10 |
11 | Mocked Link 12 |
13 | `; 14 | 15 | exports[`InsightsLink component under / should render a link with a given path 1`] = ` 16 |
17 | Mocked Link 18 |
19 | `; 20 | 21 | exports[`InsightsLink component under /preview should render a /preview link 1`] = ` 22 |
23 | Mocked Link 24 |
25 | `; 26 | 27 | exports[`InsightsLink component under /preview should render a link to non /preview 1`] = ` 28 |
29 | Mocked Link 30 |
31 | `; 32 | -------------------------------------------------------------------------------- /packages/components/src/InsightsLink/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InsightsLink'; 2 | export { default as InsightsLink } from './InsightsLink'; 3 | -------------------------------------------------------------------------------- /packages/components/src/InvalidObject/InvalidObject.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MissingPage, { MissingPageProps } from '@patternfly/react-component-groups/dist/dynamic/MissingPage'; 3 | 4 | // Don't use chrome here because the 404 page on landing does not use chrome 5 | const isBeta = () => (window.location.pathname.split('/')[1] === 'beta' ? '/beta' : ''); 6 | 7 | /** 8 | * @deprecated Do not use deprecated InvalidObject import, the component has been moved to @patternfly/react-component-groups 9 | */ 10 | const InvalidObject: React.FunctionComponent = (props) => ( 11 | 12 | ); 13 | 14 | export default InvalidObject; 15 | -------------------------------------------------------------------------------- /packages/components/src/InvalidObject/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/MissingPage'; 2 | export { default } from './InvalidObject'; 3 | export { default as InvalidObject } from './InvalidObject'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Inventory/InventoryLoadError.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | export interface InventoryLoadErrorProps { 4 | component?: string; 5 | } 6 | 7 | const InventoryLoadError: React.FunctionComponent = ({ component, ...props }) => { 8 | useEffect(() => { 9 | console.error(`Unable to load inventory component. Failed to load ${component}.`, props); 10 | }, []); 11 | return ( 12 |
13 |

Unable to load inventory component

14 |

Failed to load {component}

15 | More info can be found in browser console output. 16 |
17 | ); 18 | }; 19 | 20 | export default InventoryLoadError; 21 | -------------------------------------------------------------------------------- /packages/components/src/Inventory/WithHistory.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import React, { useMemo } from 'react'; 3 | import * as reactRouter from 'react-router-dom'; 4 | import useChrome from '../useChrome'; 5 | 6 | const WithReactRouterHistory = ({ Component, ...props }) => { 7 | const history = reactRouter.useHistory(); 8 | 9 | return ; 10 | }; 11 | 12 | const WithChromeHistory = ({ Component, ...props }) => { 13 | const { chromeHistory } = useChrome(); 14 | 15 | return ; 16 | }; 17 | 18 | const WithHistory = ({ Component, ...props }, ref) => { 19 | const HistoryComponent = useMemo( 20 | () => (typeof reactRouter.useHistory === 'function' ? WithReactRouterHistory : WithChromeHistory), 21 | [Component, props] 22 | ); 23 | 24 | return ; 25 | }; 26 | 27 | export default React.forwardRef(WithHistory); 28 | -------------------------------------------------------------------------------- /packages/components/src/Inventory/index.ts: -------------------------------------------------------------------------------- 1 | export { default as InventoryTable } from './InventoryTable'; 2 | export { default as AppInfo } from './AppInfo'; 3 | export { default as DetailWrapper } from './DetailWrapper'; 4 | export { default as InventoryDetail } from './InventoryDetail'; 5 | export { default as InventoryDetailHead } from './InventoryDetailHead'; 6 | export { default as TagWithDialog } from './TagWithDialog'; 7 | export * from './TagWithDialog'; 8 | export { default as InventoryLoadError } from './InventoryLoadError'; 9 | -------------------------------------------------------------------------------- /packages/components/src/Main/Main.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import classNames from 'classnames'; 3 | import './main.scss'; 4 | 5 | export type MainProps = React.DetailedHTMLProps, HTMLElement>; 6 | export type InternalMainProps = MainProps; 7 | 8 | /** 9 | * @deprecated Do not use this component, use HTML section tag 10 | */ 11 | export const Main: React.FC = ({ children, className, ...props }) => { 12 | useEffect(() => { 13 | console.error(`Using deprecated "Main" component. Do not use it. Either remove it from your JSX or replace it by "section" HTML element.`); 14 | }, []); 15 | return ( 16 |
17 | {children} 18 |
19 | ); 20 | }; 21 | 22 | export const InternalMain = Main; 23 | 24 | export default Main; 25 | -------------------------------------------------------------------------------- /packages/components/src/Main/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Main'; 2 | export { default as Main } from './Main'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Main/main.scss: -------------------------------------------------------------------------------- 1 | .pf-v6-l-page__main .pf-v6-l-page__main-section.pf-m-dark:not(:first-child) { 2 | background: var(--pf-t--global--background--color--inverse--default); 3 | } -------------------------------------------------------------------------------- /packages/components/src/Maintenance/Maintenance.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Maintenance from './Maintenance'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Maintenance component', () => { 6 | it('should render with default props', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | 11 | it('should render with times', () => { 12 | const { container } = render(); 13 | expect(container).toMatchSnapshot(); 14 | }); 15 | 16 | it('should render with new description', () => { 17 | const { container } = render( test } />); 18 | expect(container).toMatchSnapshot(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/components/src/Maintenance/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Maintenance'; 2 | export { default as Maintenance } from './Maintenance'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Maintenance/maintenance.scss: -------------------------------------------------------------------------------- 1 | .ins-c-empty-state__maintenance { 2 | .pf-v6-c-empty-state__body { 3 | color: var(--pf-t--color--gray--95); 4 | } 5 | .pf-v6-c-empty-state__icon svg { fill: #EE0000; } // This is Red Hat's red, not Patternfly's red. 6 | .pf-v6-c-title { font-weight: 500; } 7 | } 8 | -------------------------------------------------------------------------------- /packages/components/src/NoRegisteredSystems/NoRegisteredSystems.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NoRegisteredSystems from './NoRegisteredSystems'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Not connected component', () => { 6 | it('should render', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/src/NoRegisteredSystems/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NoRegisteredSystems'; 2 | export { default as NoRegisteredSystems } from './NoRegisteredSystems'; 3 | -------------------------------------------------------------------------------- /packages/components/src/NotAuthorized/NotAuthorized.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import UnauthorizedAccess, { UnauthorizedAccessProps } from '@patternfly/react-component-groups/dist/dynamic/UnauthorizedAccess'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated NotAuthorized import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | const NotAuthorized: React.FunctionComponent = ({ 8 | bodyText = ( 9 | <> 10 | Contact your organization administrator(s) for more information or visit My User Access to learn 11 | more about your permissions. 12 | 13 | ), 14 | ...props 15 | }) => ; 16 | 17 | export default NotAuthorized; 18 | -------------------------------------------------------------------------------- /packages/components/src/NotAuthorized/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/UnauthorizedAccess'; 2 | export { default } from './NotAuthorized'; 3 | export { default as NotAuthorized } from './NotAuthorized'; 4 | -------------------------------------------------------------------------------- /packages/components/src/NotConnected/NotConnected.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import NotConnected from './NotConnected'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Not connected component', () => { 6 | it('should render', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/src/NotConnected/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NotConnected'; 2 | export { default as NotConnected } from './NotConnected'; 3 | export * from './NotConnected'; 4 | -------------------------------------------------------------------------------- /packages/components/src/OpenSourceBadge/OpenSourceBadge.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import OpenSourceBadge from './OpenSourceBadge'; 4 | import userEvent from '@testing-library/user-event'; 5 | 6 | describe('OpenSourceBadge component', () => { 7 | describe('should render', () => { 8 | it('badge', () => { 9 | const { container } = render(); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | 13 | it('popover', async () => { 14 | render(); 15 | userEvent.click( 16 | screen.getByRole('button', { 17 | name: /about open services/i, 18 | }), 19 | ); 20 | await screen.findByRole('dialog', { 21 | name: /about open source/i, 22 | }); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/components/src/OpenSourceBadge/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './OpenSourceBadge'; 2 | export { default as OpenSourceBadge } from './OpenSourceBadge'; 3 | export * from './OpenSourceBadge'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Ouia/Ouia.test.ts: -------------------------------------------------------------------------------- 1 | import { OuiaProps, withoutOuiaProps } from './Ouia'; 2 | 3 | describe('Ouia', () => { 4 | it('withoutOuiaProps removes ouiaParams', () => { 5 | const stuff: OuiaProps & { 6 | foo: number; 7 | bar: string; 8 | } = { 9 | ouiaId: 'foobar', 10 | ouiaSafe: true, 11 | foo: 1, 12 | bar: 'baz', 13 | }; 14 | 15 | expect(withoutOuiaProps(stuff)).toEqual({ 16 | foo: 1, 17 | bar: 'baz', 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/components/src/Ouia/index.ts: -------------------------------------------------------------------------------- 1 | export { withoutOuiaProps } from './Ouia'; 2 | export type { OuiaProps, OuiaDataAttributes } from './Ouia'; 3 | export { default as WithOuia } from './WithOuia'; 4 | export type { WithOuiaParams } from './WithOuia'; 5 | export { default as useOuia } from './useOuia'; 6 | export type { UseOuiaParams } from './useOuia'; 7 | -------------------------------------------------------------------------------- /packages/components/src/Ouia/useOuia.ts: -------------------------------------------------------------------------------- 1 | import { OuiaDataAttributes, OuiaProps, makeOuiaAttributes } from './Ouia'; 2 | 3 | /** 4 | * Parameters to configure the attributes of the Ouia component. 5 | */ 6 | export interface UseOuiaParams extends OuiaProps { 7 | type: string; 8 | module?: string; 9 | } 10 | 11 | /** 12 | * Hook to help to configure a Ouia component. 13 | * @param ouiaParams configuration 14 | * @returns an object with the OuiaDataProperties to be set to the Ouia component container. 15 | */ 16 | const useOuia = (ouiaParams: UseOuiaParams): OuiaDataAttributes => { 17 | const type = ouiaParams.module !== undefined ? `${ouiaParams.module}/${ouiaParams.type}` : ouiaParams.type; 18 | 19 | return makeOuiaAttributes({ 20 | fullType: type, 21 | ouiaId: ouiaParams.ouiaId, 22 | ouiaSafe: ouiaParams.ouiaSafe, 23 | }); 24 | }; 25 | 26 | export default useOuia; 27 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/PageHeader.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PageHeader from './PageHeader'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('PageHeader component', () => { 6 | it('should render', () => { 7 | const { container } = render(Something); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/PageHeaderTitle.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import '@testing-library/jest-dom'; 4 | import PageHeaderTitle from './PageHeaderTitle'; 5 | 6 | describe('PageHeader component', () => { 7 | it('should render', () => { 8 | const { container } = render(); 9 | expect(container).toMatchSnapshot(); 10 | }); 11 | 12 | it('renders children correctly', () => { 13 | const title = 'Test Title'; 14 | const actionsContent = 'Actions content'; 15 | render(); 16 | expect(screen.getByText(actionsContent)).toBeInTheDocument(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/__snapshots__/PageHeader.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`PageHeader component should render 1`] = ` 4 |
5 |
12 | Something 13 |
14 |
15 | `; 16 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/__snapshots__/PageHeaderTitle.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`PageHeader component should render 1`] = ` 4 |
5 |
8 |
11 |

18 | Something 19 |

20 |
21 |
22 |
23 | `; 24 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PageHeader'; 2 | export { default as PageHeader } from './PageHeader'; 3 | export { default as PageHeaderTitle } from './PageHeaderTitle'; 4 | -------------------------------------------------------------------------------- /packages/components/src/PageHeader/page-header.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | .pf-v6-l-page__main-section.pf-v6-l-page-header.pf-m-dark-200 { 4 | h1.pf-v6-c-title.pf-m-2xl, * { color: #fff; } 5 | } 6 | 7 | .pf-v6-l-page__main-section.pf-v6-l-page-header { 8 | .pf-v6-c-breadcrumb { 9 | display: block; 10 | @include m.rem('margin-bottom', 15px); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/src/PrimaryToolbar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PrimaryToolbar'; 2 | export { default as PrimaryToolbar } from './PrimaryToolbar'; 3 | export { default as Actions } from './Actions'; 4 | export { default as SortBy } from './SortBy'; 5 | export * from './SortBy'; 6 | export * from './PrimaryToolbar'; 7 | -------------------------------------------------------------------------------- /packages/components/src/RBACProvider/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RBACProvider'; 2 | -------------------------------------------------------------------------------- /packages/components/src/Reboot/Reboot.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Reboot from './Reboot'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Reboot component', () => { 6 | it('should render correctly', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | 11 | it('should render correctly with red', () => { 12 | const { container } = render(); 13 | expect(container).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/components/src/Reboot/Reboot.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | import RebootingIcon from '@patternfly/react-icons/dist/dynamic/icons/rebooting-icon'; 4 | 5 | import './reboot.scss'; 6 | 7 | export interface RebootProps extends React.DetailedHTMLProps, HTMLSpanElement> { 8 | className?: string; 9 | red?: boolean; 10 | } 11 | 12 | const Reboot: React.FC = ({ red, className, ...props }) => { 13 | const rebootIconClasses = classNames('ins-c-reboot', { [`ins-m-red`]: red }, className); 14 | 15 | return ( 16 | 17 | 18 | Reboot required 19 | 20 | ); 21 | }; 22 | 23 | export default Reboot; 24 | -------------------------------------------------------------------------------- /packages/components/src/Reboot/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Reboot'; 2 | export { default as Reboot } from './Reboot'; 3 | export * from './Reboot'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Reboot/reboot.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | .ins-c-reboot { 4 | span { 5 | // 4px because the battery icon is 1px bigger than the reboot icon 6 | @include m.rem('margin-left', 4px); 7 | } 8 | 9 | &.ins-m-red { 10 | span, svg { color: var(--pf-t--global--color--status--danger--default); } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/src/Section/Section.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Section from './Section'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Section component', () => { 6 | it('should render correctly', () => { 7 | const { container } = render(
Test
); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/src/Section/Section.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | 4 | import './section.scss'; 5 | 6 | export interface SectionProps extends React.DetailedHTMLProps, HTMLElement> { 7 | type?: string; 8 | } 9 | 10 | const Section: React.FunctionComponent = ({ type, children, className, ...props }) => { 11 | const sectionClasses = classNames(className, { [`ins-l-${type}`]: type !== undefined }); 12 | 13 | return ( 14 |
15 | {' '} 16 | {children}{' '} 17 |
18 | ); 19 | }; 20 | 21 | export default Section; 22 | -------------------------------------------------------------------------------- /packages/components/src/Section/__snapshots__/Section.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Section component should render correctly 1`] = ` 4 |
5 |
8 | 9 | Test 10 | 11 |
12 |
13 | `; 14 | -------------------------------------------------------------------------------- /packages/components/src/Section/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Section'; 2 | export { default as Section } from './Section'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Section/section.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | section.ins-l-content { 4 | padding: var(--pf-t--global--spacer--lg); 5 | } 6 | 7 | section.ins-l-button-group { 8 | > * { display: inline; } 9 | * + * { @include m.rem('margin-left', 5px); } 10 | @include m.rem('margin', 24px 0); 11 | } 12 | 13 | section.ins-l-icon-group { 14 | * + * { margin-left: 10px; } 15 | } 16 | 17 | section.ins-l-icon-group__with-major { 18 | * + * { margin-left: 7.5px; } 19 | .ins-battery:last-of-type { 20 | padding-left: 15px; 21 | border-left: 2px solid #eaeaea; 22 | span.label{ 23 | font-weight: 500; 24 | margin: 0 10px; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/components/src/SeverityLine/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SeverityLine'; 2 | export { default as SeverityLine } from './SeverityLine'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Shield/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Shield'; 2 | export { default as Shield } from './Shield'; 3 | export * from './consts'; 4 | -------------------------------------------------------------------------------- /packages/components/src/SimpleTableFilter/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SimpleTableFilter'; 2 | export { default as SimpleTableFilter } from './SimpleTableFilter'; 3 | export * from './SimpleTableFilter'; 4 | -------------------------------------------------------------------------------- /packages/components/src/SimpleTableFilter/simple-table-filter.scss: -------------------------------------------------------------------------------- 1 | 2 | @forward '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss'; 3 | @forward '~@patternfly/patternfly/sass-utilities/_index'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Skeleton/Skeleton.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Skeleton, { SkeletonSize } from './Skeleton'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Skeleton component', () => { 6 | Object.values(SkeletonSize).forEach((size) => { 7 | it(`should render correctly - ${size}`, () => { 8 | const { container } = render(); 9 | expect(container).toMatchSnapshot(); 10 | }); 11 | }); 12 | 13 | it('should render correctly without size', () => { 14 | const { container } = render(); 15 | expect(container).toMatchSnapshot(); 16 | }); 17 | 18 | it('should render correctly as dark', () => { 19 | const { container } = render(); 20 | expect(container).toMatchSnapshot(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/components/src/Skeleton/Skeleton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Skeleton as PFSkeleton, SkeletonProps as PFSkeletonProps } from '@patternfly/react-core/dist/dynamic/components/Skeleton'; 3 | import classNames from 'classnames'; 4 | 5 | import './skeleton.scss'; 6 | 7 | type SkeletonSizeType = { xs: 'xs'; sm: 'sm'; md: 'md'; lg: 'lg' }; 8 | export const SkeletonSize: SkeletonSizeType = { xs: 'xs', sm: 'sm', md: 'md', lg: 'lg' }; 9 | 10 | export interface SkeletonProps extends Omit { 11 | size?: keyof SkeletonSizeType; 12 | isDark?: boolean; 13 | } 14 | 15 | const Skeleton: React.FunctionComponent = ({ size = SkeletonSize.md, isDark = false, className, ...props }) => ( 16 | 17 | ); 18 | 19 | export default Skeleton; 20 | -------------------------------------------------------------------------------- /packages/components/src/Skeleton/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Skeleton'; 2 | export { default as Skeleton, SkeletonSize } from './Skeleton'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Skeleton/skeleton.scss: -------------------------------------------------------------------------------- 1 | .ins-c-skeleton { 2 | &__xs { 3 | width: 16% !important; 4 | } 5 | 6 | &__sm { 7 | width: 33% !important; 8 | } 9 | 10 | &__md { 11 | width: 66% !important; 12 | } 13 | 14 | &__lg { 15 | width: 100% !important; 16 | } 17 | 18 | &.ins-m-dark { 19 | --pf-v6-c-skeleton--BackgroundColor: var(--pf-t--color--black); 20 | --pf-v6-c-skeleton--after--LinearGradientColorStop1: var(--pf-t--color--black); 21 | --pf-v6-c-skeleton--after--LinearGradientColorStop2: var(--pf-t--color--gray--90); 22 | --pf-v6-c-skeleton--after--LinearGradientColorStop3: var(--pf-t--color--black); 23 | } 24 | } -------------------------------------------------------------------------------- /packages/components/src/SkeletonTable/SkeletonTable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SkeletonTablePF, { SkeletonTableProps } from '@patternfly/react-component-groups/dist/dynamic/SkeletonTable'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated SkeletonTable import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const SkeletonTable: React.FunctionComponent = (props) => ; 9 | 10 | export default SkeletonTable; 11 | -------------------------------------------------------------------------------- /packages/components/src/SkeletonTable/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/SkeletonTable'; 2 | export { default } from './SkeletonTable'; 3 | export { default as SkeletonTable } from './SkeletonTable'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Spinner/Spinner.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Spinner from './Spinner'; 3 | import { render } from '@testing-library/react'; 4 | 5 | describe('Spinner component', () => { 6 | it('should render', () => { 7 | const { container } = render(); 8 | expect(container).toMatchSnapshot(); 9 | }); 10 | 11 | it('should render center Spinner', () => { 12 | const { container } = render(); 13 | expect(container).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/components/src/Spinner/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | 4 | import './spinner.scss'; 5 | 6 | export interface SpinnerProps { 7 | centered?: boolean; 8 | className?: string; 9 | } 10 | 11 | const Spinner: React.FunctionComponent = ({ centered, className, ...props }) => { 12 | const spinnerClasses = classNames('ins-c-spinner', { [`ins-m-center`]: centered }, className); 13 | 14 | return ( 15 |
16 | Loading... 17 |
18 | ); 19 | }; 20 | 21 | export default Spinner; 22 | -------------------------------------------------------------------------------- /packages/components/src/Spinner/__snapshots__/Spinner.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Spinner component should render 1`] = ` 4 |
5 |
9 | 12 | Loading... 13 | 14 |
15 |
16 | `; 17 | 18 | exports[`Spinner component should render center Spinner 1`] = ` 19 |
20 |
24 | 27 | Loading... 28 | 29 |
30 |
31 | `; 32 | -------------------------------------------------------------------------------- /packages/components/src/Spinner/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Spinner'; 2 | export { default as Spinner } from './Spinner'; 3 | -------------------------------------------------------------------------------- /packages/components/src/Spinner/spinner.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | @keyframes spinner { 4 | to { transform: rotate(360deg); } 5 | } 6 | 7 | .ins-c-spinner { 8 | display: inline-flex; 9 | &.ins-m-center { 10 | display: flex; 11 | justify-content: center; 12 | } 13 | &:before { 14 | content: ''; 15 | @include m.rem('width', 30px); 16 | @include m.rem('height', 30px); 17 | border-radius: 50%; 18 | border: 3px solid var(--pf-t--global--color--brand--hover); 19 | border-top-color: var(--pf-t--global--color--brand--default); 20 | animation: spinner 1s cubic-bezier(0.4, 0, 0.2, 1) infinite; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/TabLayout/TabLayout.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TabLayout from './TabLayout'; 3 | import { render } from '@testing-library/react'; 4 | 5 | const items = [ 6 | { 7 | name: 'one', 8 | title:
one
, 9 | }, 10 | { 11 | name: 'two', 12 | title: 'two', 13 | }, 14 | ]; 15 | 16 | describe('TabLayout component', () => { 17 | describe('should render', () => { 18 | it('without items', () => { 19 | const { container } = render(); 20 | expect(container).toMatchSnapshot(); 21 | }); 22 | 23 | it('with items', () => { 24 | const { container } = render(); 25 | expect(container).toMatchSnapshot(); 26 | }); 27 | 28 | it('with active item', () => { 29 | const { container } = render(); 30 | expect(container).toMatchSnapshot(); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/components/src/TabLayout/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TabLayout'; 2 | export { default as TabLayout } from './TabLayout'; 3 | -------------------------------------------------------------------------------- /packages/components/src/TabLayout/tab-layout.scss: -------------------------------------------------------------------------------- 1 | .ins-tab-layout { 2 | > .ins-tabs { 3 | 4 | div { 5 | display: inline-block; 6 | margin-right: 30px; 7 | text-align: center; 8 | cursor: pointer; 9 | color: var(--pf-t--global--text--color--link--default); 10 | 11 | &.active { 12 | border-bottom: 3px var(--pf-t--global--text--color--link--default) solid; 13 | } 14 | 15 | &:hover { 16 | color: var(--pf-t--global--text--color--link--default--hover); 17 | border-bottom: 3px var(--pf-t--global--text--color--link--default--hover) solid; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/components/src/TableToolbar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TableToolbar'; 2 | export { default as TableToolbar } from './TableToolbar'; 3 | -------------------------------------------------------------------------------- /packages/components/src/TagCount/TagCount.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TagCountPF from '@patternfly/react-component-groups/dist/dynamic/TagCount'; 3 | import { ButtonProps } from '@patternfly/react-core/dist/dynamic/components/Button'; 4 | export interface TagCountProps extends ButtonProps { 5 | count?: number; 6 | onTagClick?: React.MouseEventHandler; 7 | className?: string; 8 | } 9 | 10 | /** 11 | * @deprecated Do not use deprecated TagCount import, the component has been moved to @patternfly/react-component-groups 12 | */ 13 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 14 | const TagCount: React.FunctionComponent = ({ onTagClick, ...props }) => ; 15 | 16 | export default TagCount; 17 | -------------------------------------------------------------------------------- /packages/components/src/TagCount/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TagCount'; 2 | export { default } from './TagCount'; 3 | export { default as TagCount } from './TagCount'; 4 | -------------------------------------------------------------------------------- /packages/components/src/TagModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TagModal'; 2 | export { default as TagModal } from './TagModal'; 3 | export { default as TableWithFilter } from './TableWithFilter'; 4 | -------------------------------------------------------------------------------- /packages/components/src/TagModal/tagModal.scss: -------------------------------------------------------------------------------- 1 | .ins-c-tag-modal { 2 | height: calc(var(--pf-t--global--spacer--4xl) + var(--pf-t--global--breakpoint--md)); 3 | } 4 | -------------------------------------------------------------------------------- /packages/components/src/TreeTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './decorator'; 2 | export { default as treeTable } from './decorator'; 3 | export { default as TreeRowWrapper } from './rowWrapper'; 4 | export * from './helpers'; 5 | -------------------------------------------------------------------------------- /packages/components/src/Truncate/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Truncate'; 2 | export { default as Truncate } from './Truncate'; 3 | export * from './Truncate'; 4 | -------------------------------------------------------------------------------- /packages/components/src/Truncate/truncate.scss: -------------------------------------------------------------------------------- 1 | @use '~@redhat-cloud-services/frontend-components-utilities/styles/_mixins.scss' as m; 2 | 3 | .ins-c-truncate button, .ins-c-truncate + button { padding: 0; } 4 | 5 | .ins-c-truncate.is-inline { @include m.rem('margin-right', 10px); } 6 | -------------------------------------------------------------------------------- /packages/components/src/Unavailable/Unavailable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import UnavailableContent, { UnavailableContentProps } from '@patternfly/react-component-groups/dist/dynamic/UnavailableContent'; 3 | 4 | /** 5 | * @deprecated Do not use deprecated UnavailableContent import, the component has been moved to @patternfly/react-component-groups 6 | */ 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | const Unavailable: React.FunctionComponent = (props) => ( 9 | 10 | ); 11 | 12 | export default Unavailable; 13 | -------------------------------------------------------------------------------- /packages/components/src/Unavailable/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@patternfly/react-component-groups/dist/dynamic/UnavailableContent'; 2 | export { UnavailableContentProps as UnavailableProps } from '@patternfly/react-component-groups/dist/dynamic/UnavailableContent'; 3 | export { default } from './Unavailable'; 4 | export { default as Unavailable } from './Unavailable'; 5 | -------------------------------------------------------------------------------- /packages/components/src/useChrome/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useChrome'; 2 | export { default as useChrome } from './useChrome'; 3 | -------------------------------------------------------------------------------- /packages/components/src/useChrome/useChrome.ts: -------------------------------------------------------------------------------- 1 | import { ChromeAPI } from '@redhat-cloud-services/types'; 2 | import { useScalprum } from '@scalprum/react-core'; 3 | 4 | export type UseChromeSelector = (chromeState: ChromeAPI) => T; 5 | 6 | const useChrome = (selector?: UseChromeSelector): ChromeAPI | T => { 7 | const state = useScalprum<{ initialized: boolean; api: { chrome: ChromeAPI } }>(); 8 | let chrome: ChromeAPI = state.api?.chrome || ({} as ChromeAPI); 9 | chrome = { 10 | ...chrome, 11 | initialized: state.initialized, 12 | }; 13 | if (typeof selector === 'function') { 14 | return selector(chrome); 15 | } 16 | 17 | return chrome; 18 | }; 19 | 20 | export default useChrome; 21 | -------------------------------------------------------------------------------- /packages/components/src/usePendoFeedback/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './usePendoFeedback'; 2 | export { default as usePendoFeedback } from './usePendoFeedback'; 3 | -------------------------------------------------------------------------------- /packages/components/src/usePendoFeedback/usePendoFeedback.ts: -------------------------------------------------------------------------------- 1 | import { ChromeAPI } from '@redhat-cloud-services/types'; 2 | import useChrome from '../useChrome'; 3 | 4 | const usePendoFeedback = () => { 5 | const { usePendoFeedback: usePendoFeedbackInternal } = useChrome(); 6 | /** 7 | * Return no-op in case the chrome changes are not avaiable in current env. 8 | */ 9 | if (typeof usePendoFeedbackInternal !== 'function') { 10 | console.warn('The "usePendoFeedback" hook is not available in this enviroment. Default feedback form will be used. Wait for chrome updates.'); 11 | return; 12 | } 13 | return usePendoFeedbackInternal(); 14 | }; 15 | 16 | export default usePendoFeedback; 17 | -------------------------------------------------------------------------------- /packages/components/src/useScreenSize/getVariant.ts: -------------------------------------------------------------------------------- 1 | import breakpoints from './breakpoints'; 2 | 3 | const getVariant = () => { 4 | const width = window.innerWidth; 5 | 6 | let result; 7 | 8 | for (const [variant, size] of Object.entries(breakpoints)) { 9 | if (size >= width) { 10 | break; 11 | } 12 | 13 | result = variant; 14 | } 15 | 16 | return result; 17 | }; 18 | 19 | export default getVariant; 20 | -------------------------------------------------------------------------------- /packages/components/src/useScreenSize/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useScreenSize'; 2 | export { default as useScreenSize } from './useScreenSize'; 3 | export { default as getVariant } from './getVariant'; 4 | export { default as isSmallScreen } from './isSmallScreen'; 5 | export { default as breakpoints } from './breakpoints'; 6 | -------------------------------------------------------------------------------- /packages/components/src/useScreenSize/isSmallScreen.ts: -------------------------------------------------------------------------------- 1 | import breakpoints from './breakpoints'; 2 | 3 | const isSmallScreen = (screenSize: keyof typeof breakpoints) => breakpoints?.[screenSize] <= breakpoints.sm; 4 | 5 | export default isSmallScreen; 6 | -------------------------------------------------------------------------------- /packages/components/src/useScreenSize/useScreenSize.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | 3 | import getVariant from './getVariant'; 4 | 5 | const useScreen = () => { 6 | const [variant, setVariant] = useState(() => getVariant()); 7 | const prev = useRef(variant); 8 | 9 | useEffect(() => { 10 | function handleResize() { 11 | const newVariant = getVariant(); 12 | if (newVariant !== prev.current) { 13 | prev.current = newVariant; 14 | setVariant(newVariant); 15 | } 16 | } 17 | 18 | window.addEventListener('resize', handleResize); 19 | 20 | return () => window.removeEventListener('resize', handleResize); 21 | }, []); 22 | 23 | return variant; 24 | }; 25 | 26 | export default useScreen; 27 | -------------------------------------------------------------------------------- /packages/components/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/tsconfig.cy.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["cypress", "node", "./support/component.d.ts", "@simonsmith/cypress-image-snapshot/types"], 5 | }, 6 | "include": [ 7 | "./cypress/**/*.tsx", 8 | "./cypress/**/*.ts", 9 | "./cypress/**/*.js", 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true, 10 | "noImplicitAny": false 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.esm.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | }, 21 | { 22 | "path": "./tsconfig.cy.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "paths": { 8 | "@redhat-cloud-services/frontend-components-utilities": ["packages/utils/src"], 9 | "@redhat-cloud-services/frontend-components-utilities/*": ["packages/utils/src/*"] 10 | } 11 | }, 12 | "include": [ 13 | "jest.config.ts", 14 | "src/**/*.test.ts", 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/config-utils/.npmignore: -------------------------------------------------------------------------------- 1 | .eslintrc 2 | src/**/*.ts 3 | src/**/*.tsx 4 | tsconfig.json 5 | -------------------------------------------------------------------------------- /packages/config-utils/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ["!**/*"], 6 | "rules": { 7 | "@typescript-eslint/no-var-requires": "off" 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /packages/config-utils/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-config-utilities', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/config-utils', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/config-utils/src/feo/check-outgoing-requests.ts: -------------------------------------------------------------------------------- 1 | export function matchNavigationRequest(url: string): boolean { 2 | return !!url.match(/\/api\/chrome-service\/v1\/static\/bundles-generated\.json/); 3 | } 4 | 5 | export function matchSearchIndexRequest(url: string): boolean { 6 | return !!url.match(/\/api\/chrome-service\/v1\/static\/search-index-generated\.json/); 7 | } 8 | 9 | export function matchServiceTilesRequest(url: string): boolean { 10 | return !!url.match(/\/api\/chrome-service\/v1\/static\/service-tiles-generated\.json/); 11 | } 12 | 13 | export function matchModulesRequest(url: string): boolean { 14 | return !!url.match(/\/api\/chrome-service\/v1\/static\/fed-modules-generated\.json/); 15 | } 16 | 17 | export function isInterceptAbleRequest(url: string): boolean { 18 | const checks = [matchNavigationRequest, matchSearchIndexRequest, matchServiceTilesRequest, matchModulesRequest]; 19 | return checks.some((check) => check(url)); 20 | } 21 | -------------------------------------------------------------------------------- /packages/config-utils/src/feo/crd-check.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import { load } from 'js-yaml'; 3 | import { FrontendCRD } from './feo-types'; 4 | import validateFrontendCrd from './validate-frontend-crd'; 5 | import fecLogger, { LogType } from '../fec-logger'; 6 | 7 | export function readFrontendCRD(crdPath: string): FrontendCRD { 8 | try { 9 | const file = readFileSync(crdPath, 'utf8'); 10 | const crd = load(file) as FrontendCRD; 11 | try { 12 | validateFrontendCrd(crd); 13 | } catch (error) { 14 | // log only warning for dev server 15 | fecLogger(LogType.warn, error); 16 | } 17 | return crd; 18 | } catch (error) { 19 | throw new Error(`Error reading frontend CRD at ${crdPath}: ${error}`); 20 | } 21 | } 22 | 23 | export function hasFEOFeaturesEnabled(crd: FrontendCRD): boolean { 24 | return crd.objects?.[0].spec.feoConfigEnabled || false; 25 | } 26 | -------------------------------------------------------------------------------- /packages/config-utils/src/feo/module-interceptor.ts: -------------------------------------------------------------------------------- 1 | import jsVarName from '../jsVarName'; 2 | import { ChromeModuleRegistry, FrontendCRD } from './feo-types'; 3 | 4 | function moduleInterceptor(moduleRegistry: ChromeModuleRegistry, frontendCRD: FrontendCRD): ChromeModuleRegistry { 5 | const moduleName = jsVarName(frontendCRD.objects[0].metadata.name); 6 | const cdnPath = frontendCRD.objects[0].spec.frontend.paths[0]; 7 | return { 8 | ...moduleRegistry, 9 | [moduleName]: { 10 | ...frontendCRD.objects[0].spec.module, 11 | cdnPath, 12 | }, 13 | }; 14 | } 15 | 16 | export default moduleInterceptor; 17 | -------------------------------------------------------------------------------- /packages/config-utils/src/feo/search-interceptor.ts: -------------------------------------------------------------------------------- 1 | import { ChromeStaticSearchEntry, FrontendCRD } from './feo-types'; 2 | 3 | function searchInterceptor(staticSearchIndex: ChromeStaticSearchEntry[], frontendCRD: FrontendCRD): ChromeStaticSearchEntry[] { 4 | const frontendRef = frontendCRD.objects[0].metadata.name; 5 | const result = staticSearchIndex.filter((entry) => entry.frontendRef !== frontendRef); 6 | return [...result, ...(frontendCRD.objects[0].spec.searchEntries ?? [])]; 7 | } 8 | 9 | export default searchInterceptor; 10 | -------------------------------------------------------------------------------- /packages/config-utils/src/feo/widget-registry-interceptor.ts: -------------------------------------------------------------------------------- 1 | import { ChromeWidgetEntry, FrontendCRD } from './feo-types'; 2 | 3 | function widgetRegistryInterceptor(widgetEntries: ChromeWidgetEntry[], frontendCrd: FrontendCRD): ChromeWidgetEntry[] { 4 | const frontendName = frontendCrd.objects[0].metadata.name; 5 | const result = widgetEntries.filter((entry) => entry.frontendRef !== frontendName); 6 | 7 | return [...result, ...(frontendCrd.objects[0].spec.widgetRegistry ?? [])]; 8 | } 9 | 10 | export default widgetRegistryInterceptor; 11 | -------------------------------------------------------------------------------- /packages/config-utils/src/jsVarName.ts: -------------------------------------------------------------------------------- 1 | function jsVarName(s: string) { 2 | return ( 3 | s 4 | // Camel case dashes 5 | .replace(/-(\w)/g, (_, match) => match.toUpperCase()) 6 | // Remove leading digits 7 | .replace(/^[0-9]+/, '') 8 | // Remove all non alphanumeric chars 9 | .replace(/[^A-Za-z0-9]+/g, '') 10 | ); 11 | } 12 | 13 | export default jsVarName; 14 | module.exports = jsVarName; 15 | -------------------------------------------------------------------------------- /packages/config-utils/src/serveLocalFile.ts: -------------------------------------------------------------------------------- 1 | import { Response } from 'express'; 2 | 3 | function serveLocalFile(url: string, path: string, target = 'https://ci.cloud.redhat.com') { 4 | console.warn("\x1b[33mserveLocalFile is deprecated in favor of hooking into webpack-dev-server's express app."); 5 | console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md#standalone'); 6 | return { 7 | context: (path: string) => path.includes(url), 8 | target, 9 | secure: false, 10 | changeOrigin: true, 11 | autoRewrite: true, 12 | selfHandleResponse: true, 13 | onProxyReq: (_pr: unknown, _req: unknown, res: Response) => { 14 | res.sendFile(path); 15 | }, 16 | }; 17 | } 18 | 19 | export default serveLocalFile; 20 | module.exports = serveLocalFile; 21 | -------------------------------------------------------------------------------- /packages/config-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "ES5", 6 | "allowJs": true, 7 | "resolveJsonModule": true, 8 | "isolatedModules": true, 9 | "plugins": [], 10 | }, 11 | "include": [ 12 | "src/" 13 | ], 14 | "exclude": [ 15 | "./src/**/*.test.js", 16 | "./src/**/*.spec.js", 17 | "./src/**/*.test.ts", 18 | "./src/**/*.test.tsx" 19 | ], 20 | "references": [ 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/config-utils/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "composite": true, 8 | }, 9 | 10 | "include": [ 11 | "jest.config.ts", 12 | "src/**/*.test.ts", 13 | "src/**/*.spec.ts", 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/config/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | lib 3 | !src/bin 4 | !src/bin/* 5 | !src/lib 6 | !src/lib/* 7 | -------------------------------------------------------------------------------- /packages/config/.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | babel.config.js 3 | doc/ 4 | config/ 5 | .eslintrc 6 | tsconfig.json 7 | src 8 | 9 | !lib/ 10 | !lib/* 11 | !bin/ 12 | !bin/* 13 | -------------------------------------------------------------------------------- /packages/config/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ["!**/*", "**/*.yaml"], 6 | "rules": { 7 | "@typescript-eslint/no-var-requires": "off" 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /packages/config/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-config', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/config', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/config/src/bin/tsconfig.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "esnext", 7 | "target": "esnext", 8 | "jsx": "react", 9 | "allowJs": true, 10 | "moduleResolution": "node", 11 | "removeComments": false, 12 | "strict": true, 13 | "skipLibCheck": true, 14 | "allowSyntheticDefaultImports": true, 15 | "esModuleInterop": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "resolveJsonModule": true 18 | }, 19 | "include": [ 20 | "src/**/*.ts", 21 | "src/**/*.tsx", 22 | "src/**/*.js", 23 | "src/**/*.jsx" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/config/src/lib/crd-mock.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Template 4 | metadata: 5 | name: mock-frontend 6 | objects: 7 | - apiVersion: cloud.redhat.com/v1alpha1 8 | kind: Frontend 9 | metadata: 10 | name: mock-frontend 11 | spec: 12 | API: 13 | versions: 14 | - v1 15 | envName: ${ENV_NAME} 16 | title: Mock app 17 | deploymentRepo: https://github.com/RedHatInsights/mock 18 | frontend: 19 | paths: 20 | - /apps/mock-app 21 | image: ${IMAGE}:${IMAGE_TAG} 22 | module: 23 | manifestLocation: '/apps/mock/fed-mods.json' 24 | modules: [] 25 | 26 | parameters: 27 | - name: ENV_NAME 28 | required: true 29 | - name: IMAGE_TAG 30 | required: true 31 | - name: IMAGE 32 | value: quay.io/cloudservices/foo 33 | -------------------------------------------------------------------------------- /packages/config/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "commonjs", 8 | "target": "ES5", 9 | "rootDir": "src", 10 | "resolveJsonModule": true, 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx", "src/**/*.spec.js", "src/**/*.test.js"] 14 | } 15 | -------------------------------------------------------------------------------- /packages/config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.build.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | }, 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/config/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "paths": { 8 | "@redhat-cloud-services/frontend-components-config-utilities": ["packages/config-utils/src"], 9 | "@redhat-cloud-services/frontend-components-config-utilities/*": ["packages/config-utils/src/*"], 10 | }, 11 | }, 12 | "include": [ 13 | "jest.config.ts", 14 | "src/**/*.test.ts", 15 | "src/**/*.spec.ts", 16 | "src/**/*.test.js", 17 | "src/**/*.spec.js", 18 | "src/**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-crc-app/CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/create-crc-app/CHANGELOG.md -------------------------------------------------------------------------------- /packages/create-crc-app/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config'); 2 | const fecConfig = require('../../eslint.config'); 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ['./templates/**/*'], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # vscode config 4 | .vscode/ 5 | 6 | # ide config 7 | .idea/ 8 | 9 | # dependencies 10 | node_modules 11 | 12 | # production 13 | dist 14 | 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | .DS_Store 20 | coverage 21 | 22 | # cache folder 23 | .cache 24 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "arrowParens": "always", 4 | "semi": true, 5 | "tabWidth": 2, 6 | "singleQuote": true, 7 | "jsxSingleQuote": false, 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-recommended-scss" 3 | } 4 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/create-crc-app/templates/CHANGELOG.md -------------------------------------------------------------------------------- /packages/create-crc-app/templates/config/empty.js: -------------------------------------------------------------------------------- 1 | // Used as an empty module to save bundle size 2 | module.exports = {}; 3 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/config/jest.setup.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/extend-expect'; 2 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/deploy/frontend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Template 3 | metadata: 4 | name: {{name}} 5 | objects: 6 | - apiVersion: cloud.redhat.com/v1alpha1 7 | kind: Frontend 8 | metadata: 9 | name: {{appname}} 10 | spec: 11 | envName: ${ENV_NAME} 12 | title: {{title}} 13 | deploymentRepo: TBD 14 | frontend: 15 | paths: 16 | - /apps/{{appname}} 17 | image: ${IMAGE}:${IMAGE_TAG} 18 | navItems: {{{yamlNavItems}}} 19 | module: 20 | manifestLocation: "/apps/{{appname}}/fed-mods.json" 21 | modules: 22 | - id: "{{appname}}" 23 | module: "./RootApp" 24 | routes: {{{ymlRoutes}}} 25 | 26 | parameters: 27 | - name: ENV_NAME 28 | required: true 29 | - name: IMAGE_TAG 30 | required: true 31 | - name: IMAGE 32 | value: TBD 33 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/fec.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | appUrl: {{{parsedAppUrl}}}, 4 | debug: true, 5 | useProxy: true, 6 | proxyVerbose: true, 7 | /** 8 | * Change to false after your app is registered in configuration files 9 | */ 10 | interceptChromeConfig: {{{interceptChromeConfig}}}, 11 | /** 12 | * Add additional webpack plugins 13 | */ 14 | plugins: [], 15 | _unstableHotReload: process.env.HOT === 'true', 16 | }; 17 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | collectCoverage: true, 3 | collectCoverageFrom: ['src/**/*.js', '!src/**/stories/*'], 4 | coverageDirectory: './coverage/', 5 | moduleNameMapper: { 6 | '\\.(css|scss)$': 'identity-obj-proxy', 7 | }, 8 | roots: ['/src/'], 9 | transformIgnorePatterns: ['/node_modules/(?!@patternfly/react-tokens|uuid)'], 10 | testEnvironment: 'jest-environment-jsdom', 11 | moduleDirectories: [ 12 | 'node_modules', 13 | './src', //the root directory 14 | ], 15 | setupFilesAfterEnv: ['/config/jest.setup.js'], 16 | }; 17 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/App.scss: -------------------------------------------------------------------------------- 1 | // Importing Global Variables 2 | @import "~@redhat-cloud-services/frontend-components-utilities/styles/_all"; 3 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/AppEntry.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router } from 'react-router-dom'; 3 | import { Provider } from 'react-redux'; 4 | import { init } from './store'; 5 | import App from './App'; 6 | import { getBaseName } from '@redhat-cloud-services/frontend-components-utilities/helpers'; 7 | import logger from 'redux-logger'; 8 | 9 | const AppEntry = () => ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | export default AppEntry; 18 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/Components/SampleComponent/sample-component.scss: -------------------------------------------------------------------------------- 1 | @import "~@redhat-cloud-services/frontend-components-utilities/styles/variables"; 2 | 3 | .sample-component { 4 | font-size: $ins-fontSize; 5 | margin: $ins-margin; 6 | display: block; 7 | } 8 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/Components/SampleComponent/sample-component.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import SampleComponent from './sample-component'; 4 | import '@testing-library/jest-dom'; 5 | 6 | test('expect sample-component to render children', () => { 7 | const children =

Hello

; 8 | 9 | render({children}); 10 | expect(screen.getByRole('heading')).toHaveTextContent('Hello'); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/Components/SampleComponent/sample-component.tsx: -------------------------------------------------------------------------------- 1 | import './sample-component.scss'; 2 | import React from 'react'; 3 | 4 | /** 5 | * This is a dumb component that only recieves properties from a smart component. 6 | * Dumb components are usually functions and not classes. 7 | * 8 | * @param props the props given by the smart component. 9 | */ 10 | const SampleComponent: React.FC = (props) => { 11 | return {props.children} ; 12 | }; 13 | 14 | SampleComponent.displayName = 'SampleComponent'; 15 | 16 | export default SampleComponent; 17 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/Routes/NoPermissionsPage/NoPermissionsPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | import { Main } from '@redhat-cloud-services/frontend-components/Main'; 4 | import { NotAuthorized } from '@redhat-cloud-services/frontend-components/NotAuthorized'; 5 | 6 | const NoPermissionsPage = () => { 7 | useEffect(() => { 8 | insights?.chrome?.appAction?.('no-permissions'); 9 | }, []); 10 | 11 | return ( 12 |
13 | 14 |
15 | ); 16 | }; 17 | 18 | export default NoPermissionsPage; 19 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/Routes/OopsPage/OopsPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | import { Main } from '@redhat-cloud-services/frontend-components/Main'; 4 | import { Unavailable } from '@redhat-cloud-services/frontend-components/Unavailable'; 5 | 6 | const OopsPage = () => { 7 | useEffect(() => { 8 | insights?.chrome?.appAction?.('oops-page'); 9 | }, []); 10 | return ( 11 |
12 | 13 |
14 | ); 15 | }; 16 | 17 | export default OopsPage; 18 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import AppEntry from './AppEntry'; 4 | 5 | const root = document.getElementById('root'); 6 | if (root) { 7 | const reactRoot = createRoot(root); 8 | reactRoot.render(); 9 | } 10 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/entry.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Starter App 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { getRegistry } from '@redhat-cloud-services/frontend-components-utilities/Registry'; 2 | import promiseMiddleware from 'redux-promise-middleware'; 3 | import notificationsMiddleware from '@redhat-cloud-services/frontend-components-notifications/notificationsMiddleware'; 4 | import ReducerRegistry from '@redhat-cloud-services/frontend-components-utilities/ReducerRegistry'; 5 | import { Middleware } from 'redux'; 6 | 7 | export let registry: ReducerRegistry; 8 | 9 | export function init(...middleware: Middleware[]) { 10 | registry = getRegistry({}, [promiseMiddleware, notificationsMiddleware({ errorDescriptionKey: ['detail', 'stack'] }), ...middleware]); 11 | return registry; 12 | } 13 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-var */ 2 | declare global { 3 | var insights: ChromeApi; 4 | } 5 | 6 | export {}; 7 | -------------------------------------------------------------------------------- /packages/create-crc-app/templates/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "sourceMap": true, 5 | "moduleResolution": "node", 6 | "target": "es5", 7 | "allowSyntheticDefaultImports": true, 8 | "noErrorTruncation": true, 9 | "strict": true, 10 | "rootDir": ".", 11 | "skipLibCheck": true, 12 | "lib": [ 13 | "dom", 14 | "esnext" 15 | ], 16 | "module": "esnext", 17 | "esModuleInterop": true, 18 | "resolveJsonModule": true, 19 | "isolatedModules": true 20 | }, 21 | "include": [ 22 | "./src/**/*.ts", 23 | "./src/**/*.tsx" 24 | ], 25 | "exclude": [ 26 | "./src/entry.ts", 27 | "./*.js", 28 | "./*.d.ts" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/eslint-config/docs/eslint-9-migration.md: -------------------------------------------------------------------------------- 1 | # Eslint 9 migration guide 2 | 3 | Official Eslint migration guide: https://eslint.org/docs/latest/use/migrate-to-9.0.0 4 | 5 | ## HCC UI module migration 6 | 7 | ### Upgrade eslint packages 8 | 9 | Upgrade the `@redhat-cloud-services/eslint-config-redhat-cloud-services` package to v `^3.0.0`. 10 | 11 | Upgrade any locally installed eslint-related packages in your repository to version compatible with eslint@9. 12 | 13 | ### Update your eslint config 14 | 15 | Eslint 9 changes its configuration schema quite significantly. Composite configurations can now be composed, instead of referenced by a string. To use the FEC configuration you can compose it: 16 | 17 | ```js 18 | import { defineConfig } from "eslint/config"; 19 | import fecPlugin from '@redhat-cloud-services/eslint-config-redhat-cloud-services' 20 | 21 | export default defineConfig( 22 | fecConfig, 23 | { 24 | // custom configuration 25 | } 26 | ) 27 | ``` 28 | -------------------------------------------------------------------------------- /packages/eslint-config/lib/rules/no-chrome-api-call-from-window.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | meta: { 3 | type: 'suggestion', 4 | messages: { 5 | deprecateChromeApiCallFromWindow: 'Calling chrome API from the window object is deprecated.', 6 | }, 7 | fixable: 'code', 8 | schema: [], 9 | }, 10 | create: function (context) { 11 | return { 12 | Identifier(node) { 13 | if (node?.name === 'window' && node?.parent?.property?.name === 'insights' && node?.parent?.parent?.property?.name === 'chrome') { 14 | context.report({ node, messageId: 'deprecateChromeApiCallFromWindow' }); 15 | } 16 | }, 17 | }; 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@redhat-cloud-services/eslint-config-redhat-cloud-services", 3 | "version": "3.0.0", 4 | "description": "Recommended eslint configuration used in cloud.redhat.com frontend apps.", 5 | "keywords": [ 6 | "eslint", 7 | "eslintplugin", 8 | "eslint-plugin" 9 | ], 10 | "scripts": {}, 11 | "dependencies": { 12 | "@babel/eslint-parser": "^7.27.0", 13 | "@babel/preset-react": "^7.26.3", 14 | "eslint-config-prettier": "^10.1.2", 15 | "eslint-plugin-prettier": "^5.2.6", 16 | "eslint-plugin-react": "^7.37.5", 17 | "eslint-plugin-rulesdir": "^0.2.2", 18 | "globals": "^16.0.0", 19 | "prettier": "^3.5.3" 20 | }, 21 | "peerDependencies": { 22 | "@babel/core": "^7.14.0", 23 | "eslint": "^9.24.0" 24 | }, 25 | "license": "Apache", 26 | "publishConfig": { 27 | "access": "public" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/eslint-config/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 150, 3 | arrowParens: 'always', 4 | semi: true, 5 | tabWidth: 2, 6 | singleQuote: true, 7 | jsxSingleQuote: false, 8 | bracketSpacing: true, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/eslint-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["index.js", "lib/**/*.js"], 4 | "rootDir": "./src", 5 | "compilerOptions": { 6 | "declaration": false, 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/executors/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). 4 | 5 | ## 0.0.1 (2024-11-19) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * **executors:** invalid module relative path ([95a8241](https://github.com/RedHatInsights/frontend-components/commit/95a82418a328d825545de9542973d9c57fd6260e)) 11 | * **executors:** scss importer for inner dependencies ([3c62308](https://github.com/RedHatInsights/frontend-components/commit/3c623083e0c098ba1dfbdd6e9df0bb5ec4e1a2c6)) 12 | 13 | ## 0.0.1 (2024-11-19) 14 | 15 | 16 | ### Bug Fixes 17 | 18 | * **executors:** invalid module relative path ([95a8241](https://github.com/Hyperkid123/frontend-components/commit/95a82418a328d825545de9542973d9c57fd6260e)) 19 | * **executors:** scss importer for inner dependencies ([3c62308](https://github.com/Hyperkid123/frontend-components/commit/3c623083e0c098ba1dfbdd6e9df0bb5ec4e1a2c6)) 20 | -------------------------------------------------------------------------------- /packages/executors/README.md: -------------------------------------------------------------------------------- 1 | # build-utils 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build build-utils` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test build-utils` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /packages/executors/eslint.config.js: -------------------------------------------------------------------------------- 1 | 2 | const { defineConfig } = require('eslint/config') 3 | const fecConfig = require('../../eslint.config') 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ["!**/*"] 6 | }) 7 | -------------------------------------------------------------------------------- /packages/executors/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'build-utils', 4 | preset: '../../jest.preset.js', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../coverage/packages/build-utils', 10 | }; 11 | -------------------------------------------------------------------------------- /packages/executors/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@redhat-cloud-services/frontend-components-executors", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "@nx/devkit": "17.1.3", 6 | "fs-extra": "^11.2.0", 7 | "semver": "^7.5.4", 8 | "tslib": "^2.0.0", 9 | "typescript": "^5.6.3", 10 | "zod": "^3.22.4" 11 | }, 12 | "type": "commonjs", 13 | "main": "./src/index.js", 14 | "typings": "./src/index.d.ts", 15 | "executors": "./executors.json", 16 | "devDependencies": { 17 | "@types/fs-extra": "^11.0.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-packages/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-packages/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { BuilderExecutorSchemaType } from './executor'; 2 | 3 | export type BuilderExecutorSchema = BuilderExecutorSchemaType; 4 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-packages/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "Builder executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": {}, 8 | "required": [] 9 | } 10 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-styles/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-styles/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { BuilderExecutorSchemaType } from './executor'; 2 | 3 | export type BuilderExecutorSchema = BuilderExecutorSchemaType; 4 | -------------------------------------------------------------------------------- /packages/executors/src/executors/build-styles/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "Builder executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": {}, 8 | "required": [] 9 | } 10 | -------------------------------------------------------------------------------- /packages/executors/src/executors/builder/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/builder/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { BuilderExecutorSchemaType } from './executor'; 2 | 3 | export type BuilderExecutorSchema = BuilderExecutorSchemaType; 4 | -------------------------------------------------------------------------------- /packages/executors/src/executors/builder/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "Builder executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": {}, 8 | "required": [] 9 | } 10 | -------------------------------------------------------------------------------- /packages/executors/src/executors/check-circular-imports/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/check-circular-imports/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { BuilderExecutorSchemaType } from './executor'; 2 | 3 | export type BuilderExecutorSchema = BuilderExecutorSchemaType; 4 | -------------------------------------------------------------------------------- /packages/executors/src/executors/check-circular-imports/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "Builder executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": {}, 8 | "required": [] 9 | } 10 | -------------------------------------------------------------------------------- /packages/executors/src/executors/sync-dependencies/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/sync-dependencies/schema.d.ts: -------------------------------------------------------------------------------- 1 | export interface SyncDependenciesExecutorSchema { 2 | remote?: string; 3 | baseBranch?: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/executors/src/executors/sync-dependencies/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "SyncDependencies executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": { 8 | "textToEcho": { 9 | "type": "string", 10 | "description": "Text To Echo" 11 | } 12 | }, 13 | "required": [] 14 | } 15 | -------------------------------------------------------------------------------- /packages/executors/src/executors/transform-scss/executor.spec.ts: -------------------------------------------------------------------------------- 1 | describe('Builder Executor', () => { 2 | it('can run', async () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/executors/src/executors/transform-scss/schema.d.ts: -------------------------------------------------------------------------------- 1 | import { BuilderExecutorSchemaType } from './executor'; 2 | 3 | export type BuilderExecutorSchema = BuilderExecutorSchemaType; 4 | -------------------------------------------------------------------------------- /packages/executors/src/executors/transform-scss/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "version": 2, 4 | "title": "Builder executor", 5 | "description": "", 6 | "type": "object", 7 | "properties": {}, 8 | "required": [] 9 | } 10 | -------------------------------------------------------------------------------- /packages/executors/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/executors/src/index.ts -------------------------------------------------------------------------------- /packages/executors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "lib": ["es2021"], 6 | "esModuleInterop": true 7 | }, 8 | "files": [], 9 | "include": [], 10 | "references": [ 11 | { 12 | "path": "./tsconfig.lib.json" 13 | }, 14 | { 15 | "path": "./tsconfig.spec.json" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/executors/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/executors/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/notifications/.npmignore: -------------------------------------------------------------------------------- 1 | !/index.js 2 | !/index.css 3 | !/actions.js 4 | !/notifications.js 5 | !/notificationsReducer.js 6 | !/NotificationPortal.js 7 | src/ 8 | .babelrc 9 | babel.config.js 10 | doc/ 11 | config/ 12 | tsconfig* 13 | -------------------------------------------------------------------------------- /packages/notifications/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ["!**/*", "**/*.scss"] 5 | }) 6 | -------------------------------------------------------------------------------- /packages/notifications/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-notifications', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.tsx?$': [ 6 | 'ts-jest', 7 | { 8 | tsconfig: '/tsconfig.spec.json', 9 | }, 10 | ], 11 | }, 12 | moduleFileExtensions: ['ts', 'js', 'html', 'tsx'], 13 | coverageDirectory: '../../coverage/packages/notifications', 14 | }; 15 | -------------------------------------------------------------------------------- /packages/notifications/src/Notification/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Notification'; 2 | export * from './Notification'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/Notification/notification.scss: -------------------------------------------------------------------------------- 1 | .notification-item { 2 | position: relative; 3 | margin: 10px; 4 | word-break: break-word; 5 | } 6 | -------------------------------------------------------------------------------- /packages/notifications/src/NotificationPagination/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NotificationPagination'; 2 | export * from './NotificationPagination'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/NotificationPortal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NotificationPortal'; 2 | export * from './NotificationPortal'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/NotificationsProvider/index.ts: -------------------------------------------------------------------------------- 1 | export * from './NotificationsProvider'; 2 | export { default } from './NotificationsProvider'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/Portal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Portal'; 2 | export * from './Portal'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/Portal/portal.scss: -------------------------------------------------------------------------------- 1 | .notifications-portal { 2 | position: fixed; 3 | top: 0; 4 | right: 0; 5 | z-index: 2000; 6 | } 7 | 8 | @media only screen and (max-width: 600px) { 9 | .notifications-portal{ 10 | margin: 0; 11 | width: initial; 12 | } 13 | } 14 | 15 | @media only screen and (min-width: 768px) { 16 | .notifications-portal { 17 | margin: 30px; 18 | width: 708px; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/notifications/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useNotifications'; 2 | -------------------------------------------------------------------------------- /packages/notifications/src/index.scss: -------------------------------------------------------------------------------- 1 | @import './Notification/notification.scss'; 2 | @import './Portal/portal.scss'; 3 | -------------------------------------------------------------------------------- /packages/notifications/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as NotificationsPortal } from './NotificationPortal'; 2 | export * from './NotificationPortal'; 3 | export { default as NotificationsProvider } from './NotificationsProvider'; 4 | export * from './NotificationsProvider'; 5 | export * from './hooks'; 6 | export * from './state'; 7 | export { default as NotificationPagination } from './NotificationPagination'; 8 | export * from './NotificationPagination'; 9 | export { default as Notification } from './Notification'; 10 | export * from './Notification'; 11 | -------------------------------------------------------------------------------- /packages/notifications/src/state/index.ts: -------------------------------------------------------------------------------- 1 | export * from './notificationStore'; 2 | -------------------------------------------------------------------------------- /packages/notifications/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/notifications/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/notifications/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/notifications/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node", "@testing-library/jest-dom"], 7 | "paths": { 8 | "@redhat-cloud-services/frontend-components-utilities": ["packages/utils/src"], 9 | "@redhat-cloud-services/frontend-components-utilities/*": ["packages/utils/src/*"], 10 | "@redhat-cloud-services/frontend-components": ["packages/components/src"], 11 | "@redhat-cloud-services/frontend-components/*": ["packages/components/src/*"] 12 | } 13 | }, 14 | "include": [ 15 | "jest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.d.ts" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/remediations/.npmignore: -------------------------------------------------------------------------------- 1 | !/index.js 2 | !/RemediationButton.js 3 | !/RemediationButton.css 4 | !/remediationsApi.js 5 | !/remediationsApi.css 6 | !/index.css 7 | src/ 8 | .babelrc 9 | babel.config.js 10 | doc/ 11 | config/ 12 | !/RemediationButton.css 13 | !/esm 14 | !/cjs 15 | !/*.css 16 | -------------------------------------------------------------------------------- /packages/remediations/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config'); 2 | const fecConfig = require('../../eslint.config'); 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ['!**/*'], 5 | }); 6 | -------------------------------------------------------------------------------- /packages/remediations/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-remediations', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/remediations', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/remediations/src/common/RemediationLoadError.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const RemediationLoadError = ({ component, ...props }) => { 5 | useEffect(() => { 6 | console.error(`Unable to load remedaitions component. Failed to load ${component}.`, props); 7 | }, []); 8 | return ( 9 |
10 |

Unable to load remedaitions component

11 |

Failed to load {component}

12 | More info can be found in browser console output. 13 |
14 | ); 15 | }; 16 | 17 | RemediationLoadError.propTypes = { 18 | component: PropTypes.string, 19 | }; 20 | 21 | export default RemediationLoadError; 22 | -------------------------------------------------------------------------------- /packages/remediations/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as RemediationButton } from './RemediationButton'; 2 | export { default as RemediationWizard } from './RemediationWizard'; 3 | export { default as RemediationLoadError } from './common/RemediationLoadError'; 4 | -------------------------------------------------------------------------------- /packages/remediations/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/remediations/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts", "./src/**/*.js"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.js", "src/**/*.test.js", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/remediations/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/remediations/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/rule-components/.npmignore: -------------------------------------------------------------------------------- 1 | !dist 2 | !index.js 3 | !index.css 4 | src/ 5 | .babelrc 6 | babel.config.js 7 | config/ 8 | dist/size-snapshot.json 9 | rollup.config.js 10 | -------------------------------------------------------------------------------- /packages/rule-components/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config'); 2 | const fecConfig = require('../../eslint.config'); 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ['!**/*', '**/*.scss'], 5 | }); 6 | -------------------------------------------------------------------------------- /packages/rule-components/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-rule-components', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/rule-components', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/rule-components/src/Markdown/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Markdown'; 2 | export { default as Markdown } from './Markdown'; 3 | -------------------------------------------------------------------------------- /packages/rule-components/src/ReportDetails/RiskDescription.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Content, ContentVariants } from '@patternfly/react-core/dist/dynamic/components/Content'; 3 | import PropTypes from 'prop-types'; 4 | 5 | const RiskDescription = ({ riskValue, riskMeta, showDescription }) => { 6 | // riskValue ranges from 1 to ∞ 7 | const { IconComponent, description } = riskMeta[riskValue - 1]; 8 | 9 | return ( 10 |
11 | 12 | {showDescription && ( 13 | 14 | {description} 15 | 16 | )} 17 |
18 | ); 19 | }; 20 | 21 | RiskDescription.propTypes = { 22 | riskValue: PropTypes.number, 23 | riskMeta: PropTypes.array, 24 | showDescription: PropTypes.bool, 25 | }; 26 | 27 | export default RiskDescription; 28 | -------------------------------------------------------------------------------- /packages/rule-components/src/ReportDetails/constants.js: -------------------------------------------------------------------------------- 1 | import { InsightsLabel } from '@redhat-cloud-services/frontend-components/InsightsLabel'; 2 | 3 | export const totalRiskMeta = [ 4 | { 5 | label: 'Low', 6 | description: 'Low severity desc for total risk', 7 | IconComponent: InsightsLabel, 8 | }, 9 | { 10 | label: 'Moderate', 11 | description: 'Moderate severity desc for total risk', 12 | IconComponent: InsightsLabel, 13 | }, 14 | { 15 | label: 'Important', 16 | description: 'Important severity desc for total risk', 17 | IconComponent: InsightsLabel, 18 | }, 19 | { 20 | label: 'Critical', 21 | description: 'Critical severity desc for total risk', 22 | IconComponent: InsightsLabel, 23 | }, 24 | ]; 25 | 26 | export default totalRiskMeta; 27 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/ansibleSupport.js: -------------------------------------------------------------------------------- 1 | import { ansibleSupport } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Ansible support', 5 | value: 'ansible_support', 6 | type: 'checkbox', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(ansibleSupport).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/category.js: -------------------------------------------------------------------------------- 1 | import { category } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Category', 5 | value: 'category', 6 | type: 'checkbox', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(category).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/description.js: -------------------------------------------------------------------------------- 1 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 2 | ...props, 3 | label: 'Description', 4 | value: 'description', 5 | filterValues: { 6 | 'aria-label': 'Description Filter Input', 7 | value, 8 | onChange, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/impact.js: -------------------------------------------------------------------------------- 1 | import { impact } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Impact', 5 | value: 'impact', 6 | type: 'checkbox', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(impact).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/incidentRules.js: -------------------------------------------------------------------------------- 1 | import { incidentRules } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Incident rules', 5 | value: 'incident_rules', 6 | type: 'checkbox', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(incidentRules).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/index.js: -------------------------------------------------------------------------------- 1 | export { default as descriptionFilter } from './description'; 2 | export { default as totalRiskFilter } from './totalRisk'; 3 | export { default as ansibleSupportFilter } from './ansibleSupport'; 4 | export { default as categoryFilter } from './category'; 5 | export { default as incidentRulesFilter } from './incidentRules'; 6 | export { default as likelihoodFilter } from './likelihood'; 7 | export { default as riskOfChangeFilter } from './riskOfChange'; 8 | export { default as ruleStatusFilter } from './ruleStatus'; 9 | export { default as impactFilter } from './impact'; 10 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/likelihood.js: -------------------------------------------------------------------------------- 1 | import { impact } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Likelihood', 5 | value: 'likelihood', 6 | type: 'checkbox', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(impact).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/riskOfChange.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Shield } from '@redhat-cloud-services/frontend-components/Shield'; 3 | import { riskOfChange } from '../RuleTable/constants'; 4 | 5 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 6 | ...props, 7 | label: 'Risk of change', 8 | value: 'risk_of_change', 9 | type: 'checkbox', 10 | filterValues: { 11 | value, 12 | onChange, 13 | items: Object.entries(riskOfChange) 14 | .map(([key, label], index) => ({ 15 | label: ( 16 | 17 | 18 | {label} 19 | 20 | ), 21 | textual: label, 22 | value: key, 23 | })) 24 | .reverse(), 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/ruleStatus.js: -------------------------------------------------------------------------------- 1 | import { ruleStatus } from '../RuleTable/constants'; 2 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 3 | ...props, 4 | label: 'Rule status', 5 | value: 'rule_status', 6 | type: 'radio', 7 | filterValues: { 8 | value, 9 | onChange, 10 | items: Object.entries(ruleStatus).map(([key, label]) => ({ 11 | label: label, 12 | textual: label, 13 | value: key, 14 | })), 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleFilters/totalRisk.js: -------------------------------------------------------------------------------- 1 | import { severity } from '../RuleTable/constants'; 2 | 3 | export default ({ onChange, value, ...props } = { onChange: () => undefined }) => ({ 4 | ...props, 5 | label: 'Total risk', 6 | value: 'total_risk', 7 | type: 'checkbox', 8 | filterValues: { 9 | value, 10 | onChange, 11 | items: Object.entries(severity).map(([key, label]) => ({ 12 | label: label, 13 | textual: label, 14 | value: key, 15 | })), 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/rule-components/src/RuleTable/index.js: -------------------------------------------------------------------------------- 1 | export { default as default, style } from './RuleTable'; 2 | export * from './constants'; 3 | -------------------------------------------------------------------------------- /packages/rule-components/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as RuleTable } from './RuleTable'; 2 | export { default as ReportDetails } from './ReportDetails'; 3 | export { default as Markdown } from './Markdown'; 4 | export * from './RuleFilters'; 5 | export * from './RuleTable/constants'; 6 | -------------------------------------------------------------------------------- /packages/rule-components/src/index.scss: -------------------------------------------------------------------------------- 1 | @import './ReportDetails/index.scss'; 2 | -------------------------------------------------------------------------------- /packages/rule-components/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/rule-components/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts", "./src/**/*.js"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.js", "src/**/*.test.js", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/rule-components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/rule-components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/testing/.npmignore: -------------------------------------------------------------------------------- 1 | !components 2 | !index.js 3 | !index.css 4 | src/ 5 | .babelrc 6 | babel.config.js 7 | doc/ 8 | config/ 9 | tsconfig.* 10 | pre-publish.js 11 | -------------------------------------------------------------------------------- /packages/testing/README.md: -------------------------------------------------------------------------------- 1 | # RedHat Cloud Services frontend components - testing 2 | 3 | [![npm version](https://badge.fury.io/js/%40redhat-cloud-services%2Ffrontend-components-testing.svg)](https://badge.fury.io/js/%40redhat-cloud-services%2Ffrontend-components-testing) 4 | 5 | 6 | This package exports utilities to use in tests. 7 | 8 | ## Installation 9 | With NPM 10 | ```bash 11 | npm i --save-dev @redhat-cloud-services/frontend-components-testing 12 | ``` 13 | 14 | With yarn 15 | ```bash 16 | yarn add --dev @redhat-cloud-services/frontend-components-testing 17 | ``` 18 | 19 | ## Documentation Links 20 | 21 | * Usage 22 | * [Testing](doc/testing.md) 23 | -------------------------------------------------------------------------------- /packages/testing/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ["!**/*"] 5 | }) 6 | -------------------------------------------------------------------------------- /packages/testing/src/OuiaSelectors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './OuiaSelectors'; 2 | -------------------------------------------------------------------------------- /packages/testing/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './OuiaSelectors'; 2 | -------------------------------------------------------------------------------- /packages/testing/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/testing/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | }, 11 | "include": ["./src/**/*.ts"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/testing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/testing/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/translations/.npmignore: -------------------------------------------------------------------------------- 1 | !/index.js 2 | !/index.css 3 | !/esm 4 | !/cjs 5 | src/ 6 | .babelrc 7 | babel.config.js 8 | doc/ 9 | config/ 10 | -------------------------------------------------------------------------------- /packages/translations/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ["!**/*"] 5 | }) 6 | -------------------------------------------------------------------------------- /packages/translations/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-translations', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/translations', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/translations/pre-publish.js: -------------------------------------------------------------------------------- 1 | const fse = require('fs-extra'); 2 | const path = require('path'); 3 | 4 | async function copyLocales() { 5 | try { 6 | await fse.copy(path.resolve(__dirname, '../../locales'), path.resolve(__dirname, './locales')); 7 | await fse.copy(path.resolve(__dirname, '../../locales'), path.resolve(__dirname, './esm/locales')); 8 | } catch (error) { 9 | console.error(error); 10 | process.exit(1); 11 | } 12 | 13 | } 14 | 15 | copyLocales(); 16 | -------------------------------------------------------------------------------- /packages/translations/src/Provider/__snapshots__/Provider.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`provider messages multiple Languages cs-locale 1`] = ` 4 |
5 |
6 | Test 7 |
8 |
9 | `; 10 | 11 | exports[`provider messages multiple Languages no locale 1`] = ` 12 |
13 |
14 | Test 15 |
16 |
17 | `; 18 | 19 | exports[`provider messages no langauge 1`] = ` 20 |
21 |
22 | Test 23 |
24 |
25 | `; 26 | 27 | exports[`provider should render correctly 1`] = ` 28 |
29 |
30 | Test 31 |
32 |
33 | `; 34 | -------------------------------------------------------------------------------- /packages/translations/src/Provider/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Provider'; 2 | -------------------------------------------------------------------------------- /packages/translations/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as IntlProvider } from './Provider'; 2 | export { default as defaultMessages } from './messages'; 3 | export * from './utils'; 4 | export { default as intlHelper } from './intlHelper'; 5 | -------------------------------------------------------------------------------- /packages/translations/src/intlHelper/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './intlHelper'; 2 | -------------------------------------------------------------------------------- /packages/translations/src/intlHelper/intlHelper.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import IntlProvider from '../Provider'; 3 | 4 | const intlHelper = (message, settings) => {message}; 5 | 6 | export default intlHelper; 7 | -------------------------------------------------------------------------------- /packages/translations/src/locales: -------------------------------------------------------------------------------- 1 | ../../../locales -------------------------------------------------------------------------------- /packages/translations/src/messages.js: -------------------------------------------------------------------------------- 1 | import { defineMessages } from 'react-intl'; 2 | 3 | export default defineMessages({ 4 | cancel: { 5 | id: 'default.cancel', 6 | description: 'Default cancel string', 7 | defaultMessage: 'Cancel', 8 | }, 9 | save: { 10 | id: 'default.save', 11 | description: 'Default save string', 12 | defaultMessage: 'Save', 13 | }, 14 | delete: { 15 | id: 'default.delete', 16 | description: 'Default delete string', 17 | defaultMessage: 'Delete', 18 | }, 19 | remove: { 20 | id: 'default.remove', 21 | description: 'Default remove string', 22 | defaultMessage: 'Remove', 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /packages/translations/src/messages.test.js: -------------------------------------------------------------------------------- 1 | import messages from './messages'; 2 | 3 | const mockedMessages = { 4 | cancel: { 5 | id: 'default.cancel', 6 | description: 'Default cancel string', 7 | defaultMessage: 'Cancel', 8 | }, 9 | save: { 10 | id: 'default.save', 11 | description: 'Default save string', 12 | defaultMessage: 'Save', 13 | }, 14 | }; 15 | 16 | describe('default messages', () => { 17 | Object.keys(mockedMessages).map((oneMsg) => { 18 | test(`${oneMsg}`, () => { 19 | expect(mockedMessages[oneMsg]).toEqual(messages[oneMsg]); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/translations/src/translatedMessages/translatedMessages.js: -------------------------------------------------------------------------------- 1 | export { default as translatedMessages } from '../locales/data.json'; 2 | -------------------------------------------------------------------------------- /packages/translations/src/utils.js: -------------------------------------------------------------------------------- 1 | export const LOCALSTORAGE_KEY = 'rhcs-language'; 2 | -------------------------------------------------------------------------------- /packages/translations/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/translations/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "./src", 10 | "resolveJsonModule": true, 11 | }, 12 | "include": ["./src/**/*.ts", "./src/**/*.js"], 13 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.spec.js", "src/**/*.test.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 14 | } 15 | -------------------------------------------------------------------------------- /packages/translations/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noPropertyAccessFromIndexSignature": false, 8 | "noFallthroughCasesInSwitch": true, 9 | "allowJs": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/translations/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/tsc-transform-imports/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /packages/tsc-transform-imports/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ["!**/*"] 5 | }) 6 | -------------------------------------------------------------------------------- /packages/tsc-transform-imports/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@redhat-cloud-services/tsc-transform-imports", 3 | "version": "1.0.24", 4 | "main": "index.js", 5 | "types": "index.d.ts", 6 | "dependencies": { 7 | "glob": "10.3.3" 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5.0.0" 11 | }, 12 | "scripts": {} 13 | } 14 | -------------------------------------------------------------------------------- /packages/tsc-transform-imports/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": ".", 5 | "plugins": [] 6 | }, 7 | "include": ["src/index.ts"] 8 | } -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # Types package 2 | 3 | This package is intended to expose the common types when using the chrome API 4 | -------------------------------------------------------------------------------- /packages/types/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config') 2 | const fecConfig = require('../../eslint.config') 3 | module.exports = defineConfig(fecConfig, { 4 | ignores: ["!**/*"] 5 | }) 6 | -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@redhat-cloud-services/types", 3 | "description": "TypeScript definitions for @redhat-cloud-services common typings.", 4 | "version": "2.0.3", 5 | "main": "index.d.ts", 6 | "types": "index.d.ts", 7 | "publishConfig": { 8 | "access": "public" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/RedHatInsights/frontend-components.git", 13 | "directory": "packages/types" 14 | }, 15 | "scripts": {}, 16 | "devDependencies": { 17 | "@patternfly/quickstarts": "^6.0.0", 18 | "@redhat-cloud-services/rbac-client": "^1.0.111 || 2.x", 19 | "history": "^4.10.1", 20 | "glob": "10.3.3", 21 | "@segment/analytics-next": "^1.43.2" 22 | }, 23 | "author": "", 24 | "license": "Apache-2.0" 25 | } 26 | -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["index.ts"], 4 | "compilerOptions": { 5 | "declaration": true, 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/utils/.npmignore: -------------------------------------------------------------------------------- 1 | !files 2 | src/ 3 | .babelrc 4 | babel.config.js 5 | doc/ 6 | config/ 7 | !Styles.css 8 | !helpers.css 9 | !postinstall.js 10 | tsconfig* 11 | -------------------------------------------------------------------------------- /packages/utils/doc/routerParams.md: -------------------------------------------------------------------------------- 1 | # Router parameters 2 | If you want to record where user is located you should use utility which will take care of this and stores it into redux. 3 | 4 | Do not use `withRouter` from `react-router-dom` anymore, but use this utility instead. 5 | 6 | This utility is just wrapper over `withRouter` so anything which you want to use from such decorator can be used as well. 7 | ### Usage 8 | ```JSX 9 | import React from 'react' 10 | import routerParams from '@redhat-cloud-services/frontend-components-utilities/RouterParams'; 11 | 12 | const yourCmp = ({ match, location }) => { 13 | // do something with match and location 14 | return ( 15 |
Some text
16 | ) 17 | } 18 | 19 | export default routerParams(yourCmp); 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/utils/eslint.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('eslint/config'); 2 | const fecConfig = require('../../eslint.config'); 3 | 4 | module.exports = defineConfig(fecConfig, { 5 | ignores: ['!**/*', '**/*.scss'], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/utils/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: '@redhat-cloud-services/frontend-components-utilities', 3 | preset: '../../jest.preset.js', 4 | transform: { 5 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 6 | }, 7 | moduleFileExtensions: ['ts', 'js', 'html'], 8 | coverageDirectory: '../../coverage/packages/utils', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/utils/src/MiddlewareListener/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './MiddlewareListener'; 2 | export * from './MiddlewareListener'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/RBAC/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RBAC'; 2 | export * from './RBAC'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/RBACHook/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RBACHook'; 2 | export * from './RBACHook'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/ReducerRegistry/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ReducerRegistry'; 2 | export * from './ReducerRegistry'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/Registry/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Registry'; 2 | export * from './Registry'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/RouterParams/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RouterParams'; 2 | export * from './RouterParams'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/RowLoader/RowLoader.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader, { IContentLoaderProps } from 'react-content-loader'; 2 | 3 | /** 4 | * @deprecated Use the Patternfly skeleton components instead 5 | */ 6 | const RowLoader = (props: IContentLoaderProps) => ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | 18 | export default RowLoader; 19 | -------------------------------------------------------------------------------- /packages/utils/src/RowLoader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RowLoader'; 2 | export * from './RowLoader'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/TestingUtils/CypressUtils/index.js: -------------------------------------------------------------------------------- 1 | export * from './selectors'; 2 | export * from './UIFilters'; 3 | export * from './TableUtils'; 4 | export * from './PaginationUtils'; 5 | export * from './CustomCommands'; 6 | -------------------------------------------------------------------------------- /packages/utils/src/TestingUtils/JestUtils/index.js: -------------------------------------------------------------------------------- 1 | export * from './TestWrapper'; 2 | -------------------------------------------------------------------------------- /packages/utils/src/debounce/debounce.ts: -------------------------------------------------------------------------------- 1 | import awesomeDebouncePromise from 'awesome-debounce-promise'; 2 | 3 | /** 4 | * Async debounce factory functions. 5 | * @param {Function} asyncFunction async function to be debounced 6 | * @param {number} [time = 800] delay in ms 7 | * @param {Object} [config = {onlyResolvesLast: true}] more details 8 | */ 9 | export const debounceFunction = (asyncFunction: (...args: unknown[]) => Promise, time = 800, config = { onlyResolvesLast: true }) => 10 | awesomeDebouncePromise(asyncFunction, time, config); 11 | 12 | export default debounceFunction; 13 | -------------------------------------------------------------------------------- /packages/utils/src/debounce/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './debounce'; 2 | export * from './debounce'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * as default from './helpers'; 2 | export * from './helpers'; 3 | export * from './urlPathHelpers'; 4 | -------------------------------------------------------------------------------- /packages/utils/src/helpers/urlPathHelpers.ts: -------------------------------------------------------------------------------- 1 | import { LinkProps } from 'react-router-dom'; 2 | import { ChromeAPI } from '@redhat-cloud-services/types'; 3 | 4 | export const buildInsightsPath = (chrome: ChromeAPI, app: string, toProp: LinkProps['to'], forcePreview?: boolean): LinkProps['to'] => { 5 | const inAppPath = (typeof toProp === 'object' ? toProp.pathname : toProp) || ''; 6 | const isAbsolutePath = /^\//.test(inAppPath as string); 7 | const environmentPath = forcePreview ? '/preview' : ''; 8 | const appPath = app || chrome.getApp(); 9 | const pathname = isAbsolutePath ? [environmentPath, chrome.getBundle(), appPath, (inAppPath as string).replace(/^\//, '')].join('/') : inAppPath; 10 | 11 | // @ts-ignore 12 | return typeof toProp === 'object' 13 | ? { 14 | ...toProp, 15 | pathname, 16 | } 17 | : pathname; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/utils/src/index.scss: -------------------------------------------------------------------------------- 1 | @import './styles/all'; 2 | @import './styles/helpers'; 3 | @import './styles/mixins'; 4 | @import './styles/variables'; 5 | -------------------------------------------------------------------------------- /packages/utils/src/interceptors/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './interceptors'; 2 | export * from './interceptors'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/mergeMessages/index.js: -------------------------------------------------------------------------------- 1 | require('./mergeMessages'); 2 | -------------------------------------------------------------------------------- /packages/utils/src/parseCvssScore/__snapshots__/parseCvssScore.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`parseCvssScore cvssV2 should render v2 cvss 1`] = `
`; 4 | 5 | exports[`parseCvssScore cvssV2 with labels should render correct tooltip content 1`] = `
`; 6 | 7 | exports[`parseCvssScore cvssV2 with labels should render v2 cvss with label 1`] = `
`; 8 | 9 | exports[`parseCvssScore cvssV3 1`] = ` 10 |
11 | 2.0 12 |
13 | `; 14 | 15 | exports[`parseCvssScore no cvss render 1`] = ` 16 |
17 |
20 | 21 | N/A 22 | 23 |
24 |
25 | `; 26 | -------------------------------------------------------------------------------- /packages/utils/src/parseCvssScore/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './parseCvssScore'; 2 | export * from './parseCvssScore'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/parseCvssScore/parseCvssScore.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Tooltip } from '@patternfly/react-core'; 3 | 4 | function parseCvssScore(cvssV2?: string | number, cvssV3?: string | number, withLabels = false) { 5 | const v2Tooltip = 'Prior to 2016 (approximately), CVEs were scored with Common Vulnerability Scoring System v2.'; 6 | const naTooltip = 'CVEs published before 2005 (approximately) did not have a CVSS Base Score.'; 7 | return ( 8 | (cvssV3 && parseFloat(cvssV3 as string).toFixed(1)) || 9 | (cvssV2 && ( 10 | 11 | 12 | {`${parseFloat(cvssV2 as string).toFixed(1)}`} {withLabels && '(CVSSv2)'} 13 | 14 | 15 | )) || ( 16 | 17 | N/A 18 | 19 | ) 20 | ); 21 | } 22 | 23 | export default parseCvssScore; 24 | -------------------------------------------------------------------------------- /packages/utils/src/styles/_all.scss: -------------------------------------------------------------------------------- 1 | // Sass Imports 2 | @forward './_variables.scss'; 3 | @forward './_helpers.scss'; 4 | @forward './_mixins.scss'; 5 | -------------------------------------------------------------------------------- /packages/utils/src/styles/_helpers.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatInsights/frontend-components/d3323f27093fa7c5b38ba35936e2f2af9699aa98/packages/utils/src/styles/_helpers.scss -------------------------------------------------------------------------------- /packages/utils/src/useExportPDF/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useExportPDF'; 2 | export * from './useExportPDF'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/useExportPDF/useExportPDF.test.js: -------------------------------------------------------------------------------- 1 | import useExportPDF from './useExportPDF'; 2 | import { pdfGeneratorURL } from './useExportPDF'; 3 | 4 | window.URL.createObjectURL = jest.fn(); 5 | global.fetch = jest.fn(); 6 | const dispatch = jest.fn(); 7 | 8 | describe('useExportPDF', () => { 9 | it('Should download PDF', async () => { 10 | global.fetch.mockReturnValueOnce(Promise.resolve({ blob: jest.fn() })); 11 | const exportPDF = useExportPDF('vulnerability', dispatch); 12 | await exportPDF('executiveReport', 'vulnerability-test-export', { someRequestPayload: 'some value' }); 13 | expect(fetch).toHaveBeenCalledWith(pdfGeneratorURL, { 14 | body: '{"service":"vulnerability","template":"executiveReport","params":{"someRequestPayload":"some value"}}', 15 | headers: { 'Content-Type': 'application/json' }, 16 | method: 'POST', 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/utils/src/useFetchBatched/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useFetchBatched'; 2 | -------------------------------------------------------------------------------- /packages/utils/src/useInsightsNavigate/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './useInsightsNavigate'; 2 | export * from './useInsightsNavigate'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/useInsightsNavigate/useInsightsNavigate.ts: -------------------------------------------------------------------------------- 1 | import { LinkProps, useNavigate } from 'react-router-dom'; 2 | import { buildInsightsPath } from '../helpers/urlPathHelpers'; 3 | 4 | const useInsightsNavigate = (app: string, forcePreview?: boolean) => { 5 | // FIXME: These are circular dependencies and have to be removed 6 | // FIXME: The hooks should be moved to a different package! 7 | const navigate = useNavigate(); 8 | // eslint-disable-next-line rulesdir/no-chrome-api-call-from-window 9 | const chrome = window.insights.chrome; 10 | 11 | return (to: LinkProps['to'], preview?: boolean) => navigate(buildInsightsPath(chrome, app, to, preview || forcePreview)); 12 | }; 13 | 14 | export default useInsightsNavigate; 15 | -------------------------------------------------------------------------------- /packages/utils/src/useInventory/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './useInventory'; 2 | export * from './useInventory'; 3 | -------------------------------------------------------------------------------- /packages/utils/src/usePromiseQueue/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './usePromiseQueue'; 2 | -------------------------------------------------------------------------------- /packages/utils/src/useSuspenseLoader/index.ts: -------------------------------------------------------------------------------- 1 | export { default as suspenseLoader } from './useSuspenseLoader'; 2 | export * from './useSuspenseLoader'; 3 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.esm.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "module": "ES2015", 8 | "target": "ES5", 9 | "rootDir": "src", 10 | }, 11 | "include": ["src/**/*.ts"], 12 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.jsx"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": false, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "allowJs": true 12 | }, 13 | "files": [], 14 | "include": [], 15 | "references": [ 16 | { 17 | "path": "./tsconfig.esm.json" 18 | }, 19 | { 20 | "path": "./tsconfig.spec.json" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@redhat-cloud-services/source", 3 | "$schema": "node_modules/nx/schemas/project-schema.json", 4 | "targets": { 5 | "local-registry": { 6 | "executor": "@nx/js:verdaccio", 7 | "options": { 8 | "port": 4873, 9 | "config": ".verdaccio/config.yml", 10 | "storage": "tmp/local-registry/storage" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /vitest.workspace.ts: -------------------------------------------------------------------------------- 1 | export default ['**/*/vite.config.ts', '**/*/vitest.config.ts']; 2 | --------------------------------------------------------------------------------