A React-based frontend application for Red Hat Console notification management.
This application provides a user interface for managing notifications in the Red Hat Hybrid Cloud Console. Built with PatternFly React components and TypeScript.
- Framework: React 18 with TypeScript (strict mode)
- UI Components: PatternFly 6 (v6.4.0)
- State Management: React Context + Redux (minimal - one reducer)
- Build Tool: Webpack with Module Federation (micro-frontend)
- Testing: Jest + React Testing Library, Cypress, Playwright
- Storybook: Component documentation and visual testing
- Feature Flags: Unleash for feature toggles
- Internationalization: React Intl
# Install dependencies
npm install
# Start development server
npm start
# Run tests
npm test
# Build for production
npm run build
# Run Storybook
npm run storybook
# Lint
npm run lint
npm run lint:ts:fix # Auto-fix linting issues
# Regenerate API clients from OpenAPI specs
npm run schemasrc/
├── api/ # API integration layer (axios + factories)
├── app/ # Core app components
│ ├── App.tsx # Main app with providers
│ └── rbac/ # RBAC/Kessel integration
├── components/ # Reusable UI components
│ ├── Integrations/ # Integration forms, tables, modals
│ ├── Notifications/# Notification UI components
│ └── Widgets/ # Dashboard widgets (EventsWidget)
├── generated/ # Auto-generated OpenAPI clients (DO NOT EDIT)
│ ├── OpenapiNotifications.ts (1,466 lines)
│ ├── OpenapiIntegrations.ts (933 lines)
│ ├── OpenapiRbac.ts (2,857 lines)
│ └── OpenapiPrivate.ts (962 lines)
├── hooks/ # Custom React hooks
├── pages/ # Page-level components
│ ├── Integrations/ # Integration pages (Create, List, Delete)
│ └── Notifications/# Notification pages (List, EventLog, Form)
├── services/ # API service hooks
│ ├── Integrations/ # GetEndpoint, ListIntegrations
│ ├── Notifications/# GetBehaviorGroups, GetBundles
│ └── Rbac/ # GetGroups
├── store/ # Redux state (minimal usage)
├── types/ # TypeScript type definitions
│ ├── Integration.ts # Integration types + adapters
│ ├── Notification.ts
│ └── adapters/ # API response transformers
└── utils/ # Utility functions
└── insights-common-typescript/ # Red Hat Insights utilities
- Form components:
src/components/Integrations/Form/IntegrationType{Name}Form.tsx - Type definitions:
src/types/Integration.ts(IntegrationType enum) - API helpers:
src/api/helpers/integrations/endpoints-helper.ts - Wizard flow:
src/pages/Integrations/Create/IntegrationWizard.tsx - Example: See
IntegrationTypeSlackForm.tsxorIntegrationTypeHttpForm.tsx
- List page:
src/pages/Notifications/List/Page.tsx - Event log:
src/pages/Notifications/EventLog/EventLogPage.tsx - Behavior groups:
src/components/Notifications/BehaviorGroup/ - API services:
src/services/Notifications/ - Types:
src/types/Notification.ts+src/generated/OpenapiNotifications.ts
- Primary example:
src/pages/Integrations/Create/CustomComponents/UserAccessGroupsDataView.tsx - Widget example:
src/components/Widgets/EventsWidget.tsx - Integrations table:
src/components/Integrations/IntegrationsTable.tsx - Key imports:
@patternfly/react-data-view(DataView, DataViewTable, DataViewToolbar)
- Context provider:
src/app/rbac/RbacGroupContextProvider.tsx - Kessel workspace:
src/app/rbac/KesselRbacAccessProvider.tsx - Workspace relations:
src/app/rbac/kesselWorkspaceRelations.ts - Permission checks:
src/components/CheckReadPermissions.tsx(wraps routes) - Service:
src/services/Rbac/GetGroups.ts
- Simple read-only table? → Use
DataViewTablefrom@patternfly/react-data-view - Need filtering/pagination? → Add
DataViewToolbarwithDataViewTextFilter - Need row selection? → Use
useDataViewSelectionhook - Complex interactions? → Check
UserAccessGroupsDataView.tsxfor complete example
- Is it in OpenAPI spec? → Use types from
src/generated/OpenapiNotifications.tsorOpenapiIntegrations.ts - Need to add new endpoint? → Update OpenAPI spec, then run
npm run schemato regenerate - Integration endpoint? → Use helpers in
src/api/helpers/integrations/endpoints-helper.ts - Need a service hook? → Create in
src/services/following existing patterns (useListIntegrations.ts)
- User-facing text? → Use
<FormattedMessage>fromreact-intl - Dynamic text? → Use
useIntl()hook withformatMessage() - Adding new translations? → Run
npm run translations:extractthennpm run translations:compile
- Simple form? → Use Formik + PatternFly form components
- Multi-step wizard? → Use
@data-driven-forms/react-form-renderer(see IntegrationWizard.tsx) - Form validation? → Use yup schema with Formik
- PatternFly form wrappers? → Import from
src/utils/insights-common-typescript/Formik.tsx
- Add route to:
src/Routes.tsx - Feature flagged route? → Check
notificationsOverhaulflag pattern - Protected route? → Wrap in
<CheckReadPermissions>component - Generate route URLs? → Use
linkTohelper object
- ❌ Don't import from
@patternfly/react-tablefor new code (legacy PF5) - ✅ Do use
@patternfly/react-data-viewfor tables (PF6) - ❌ Don't use legacy CSS class names (e.g.,
pf-c-table) - ✅ Do run
/pf-class-migration-scannerskill if migrating old code ⚠️ Note: Some components may still use react-table - migration in progress
- ❌ NEVER manually edit files in
src/generated/ - ✅ ALWAYS regenerate with
npm run schemaafter OpenAPI spec changes ⚠️ 4 separate OpenAPI files:OpenapiNotifications.ts- Notifications API (1,466 lines)OpenapiIntegrations.ts- Integrations API (933 lines)OpenapiRbac.ts- RBAC API (2,857 lines)OpenapiPrivate.ts- Private API (962 lines)
⚠️ Large file sizes expected - these are auto-generated, not code smells
- Auto-sync: RBAC groups sync every 2 minutes via
useSyncInterval - Pagination: Groups fetched 100 at a time
- Context usage: Access via
useRbacGroups()hook - Workspace relations: Defined in
kesselWorkspaceRelations.ts - Permission checks: Route-level with
CheckReadPermissionswrapper
- Uses Unleash:
@unleash/proxy-client-react - Key flag:
platform.notifications.overhaul- switches between legacy and new routes - Storybook mocking: Check
.storybook/preview.tsxfor Unleash mock setup
- Exposes: RootApp, IntegrationsTable, TimeConfig, DashboardWidget, IntegrationWizard
- Shares: react-router-dom (singleton)
- Config:
fec.config.js ⚠️ Shared dependencies - be careful with version conflicts
- Local dev requires:
/etc/hostsconfiguration for prod.foo and stage.foo - Dev server: Uses
insights-proxyviafec devcommand - Hot reload: Enabled with
HOT=trueenvironment variable - API routes: Configured in
config/api-routes.ts
- Test wrapper: Use
appWrapperSetup()from test utils for components needing routing/context - MSW mocking: Storybook uses MSW addon for API mocking
- Coverage: Only 29 test suites currently - not comprehensive
- E2E: Both Cypress AND Playwright configured (Cypress is primary)
import { render, screen } from '@testing-library/react';
import { appWrapperSetup } from '@redhat-cloud-services/frontend-components-testing';
describe('MyComponent', () => {
it('renders correctly', () => {
const { wrapper } = appWrapperSetup();
render(<MyComponent />, { wrapper });
expect(screen.getByText('Expected Text')).toBeInTheDocument();
});
});- Cypress: Primary E2E framework
- Config:
cypress.config.ts - Tests:
cypress/e2e/ - Run:
npm run cypress:open
- Config:
- Playwright: Secondary framework
- Config:
playwright/ - Example:
playwright/example.spec.ts
- Config:
- Test runner:
npm run test-storybook - Stories location: Co-located with components (
*.stories.tsx) - MSW integration: API mocking in
.storybook/preview.tsx
| What You Need | Where to Look |
|---|---|
| Notification pages | src/pages/Notifications/ |
| Integration forms | src/components/Integrations/Form/ |
| Integration wizard | src/pages/Integrations/Create/IntegrationWizard.tsx |
| API types (auto-generated) | src/generated/Openapi*.ts |
| API service hooks | src/services/ |
| Type definitions | src/types/ |
| Type adapters | src/types/adapters/ |
| RBAC logic | src/app/rbac/ |
| Redux store | src/store/ (minimal - one reducer) |
| Custom hooks | src/hooks/ |
| Utilities | src/utils/insights-common-typescript/ |
| E2E tests (Cypress) | cypress/e2e/ |
| E2E tests (Playwright) | playwright/ |
| Storybook config | .storybook/ |
| Build config | fec.config.js, config/ |
| CI/CD pipelines | .github/workflows/, .travis.yml, .tekton/ |
| Frontend Operator config | .rhcicd/frontend.yaml |
- TypeScript: Strict mode enabled, use explicit types
- React: Functional components with hooks (no class components)
- Styling: Use PatternFly components and utilities
- Testing: Test all components with React Testing Library
- Linting: ESLint configuration in
.eslintrc.js - Formatting: Prettier (auto-runs on commit via husky)
- Commits: Conventional commits enforced via commitlint
- Generated Code: Never manually edit files in
src/generated/- regenerate withnpm run schema - PatternFly First: Use PatternFly 6 components (
@patternfly/react-data-viewfor tables) - Type Safety: Maintain strict TypeScript types, avoid
any - Type Adapters: Use adapters in
src/types/adapters/for API response transformation - Test Coverage: Write tests for new components (currently low coverage - 29 test suites)
- Feature Flags: Check Unleash flags before implementing route changes
- RBAC: Always wrap protected routes in
CheckReadPermissions - Internationalization: All user-facing text must use
react-intl
The following PatternFly React skills are available via the pf-react plugin:
- /patternfly-component-structure - Audit component hierarchy, fix nesting violations, debug layout issues
- /pf-project-scaffolder - Bootstrap new PatternFly projects with PF6-safe dependencies
- /pf-import-checker - Fix PatternFly import path issues (charts, chatbot, component-groups)
- /pf-unit-test-generator - Generate comprehensive unit tests for PatternFly components
- /pf-library-test-writer - Write unit tests for PatternFly library contributors (not for consumers)
- /pf-class-migration-scanner - Scan for legacy PatternFly classes and suggest PF6 replacements
- /write-example-description - Write/refine example descriptions for PatternFly.org
- /icon-finder - Find Red Hat Design System icons by use case with visual preview
- /pf-bug-triage - Triage bug reports, suggest fixes, tag maintainers
- After adding PatternFly imports: Run
/pf-import-checkerto verify import paths - When building new components: Use
/patternfly-component-structureto audit hierarchy - When writing tests: Use
/pf-unit-test-generatorfor comprehensive test coverage - When migrating code: Use
/pf-class-migration-scannerto find legacy patterns - When searching for icons: Use
/icon-finderto browse Red Hat Design System icons
- Upgraded from PF5 → PF6.4.0
- Main breaking change:
@patternfly/react-data-viewreplaces@patternfly/react-table - Migration in progress - some components still use legacy react-table
- Examples:
UserAccessGroupsDataView.tsx,EventsWidget.tsx
- New workspace-based permissions model
- Auto-sync every 2 minutes
- Files:
src/app/rbac/KesselRbacAccessProvider.tsx,kesselWorkspaceRelations.ts
- Unleash flag
platform.notifications.overhaulcontrols route sets - Legacy vs new notification UI
- Micro-frontend architecture
- Exposes: RootApp, IntegrationsTable, TimeConfig, DashboardWidget, IntegrationWizard
- Config:
fec.config.js
- Platform: GitHub Actions + Travis CI
- Build Pipeline:
.github/workflows/and.travis.yml - Deployment: Automated via Konflux/Tekton (
.tekton/) - Frontend Operator: Configuration in
.rhcicd/frontend.yaml
- ✅
tsconfig.jsonsyntax fixed (trailing comma removed) ⚠️ Large generated files (4 files, largest is 2,857 lines) - expected, not code smells⚠️ Low test coverage (29 test suites for entire codebase)⚠️ Limited Storybook stories (only 3 story files)