A modern, responsive React TypeScript component designed specifically for integration with Pega Constellation applications. This component serves as a comprehensive fragrance formula creation tool for perfumer case types, with built-in data capture and API integration capabilities for seamless Pega workflow integration.
- Case-Driven Architecture: Initializes with Pega case ID for seamless case management integration
- API-First Design: Built-in service layer for direct communication with Pega REST APIs
- Data Capture System: Automatic formatting of formula data for Pega case submission
- Validation Engine: Comprehensive formula validation before Pega API submission
- Real-time Status Tracking: Live integration status with success/error handling
- Structured Data Export: Active formula data automatically captured in Pega-compatible format
- JSON Export Capability: Complete formula data available as downloadable JSON files
- API Submission Ready: Formatted payload ready for immediate Pega API integration
- Local Backup System: Automatic local storage for debugging and backup purposes
- Validation Reporting: Detailed validation errors and compliance status for case updates
- Balanced Column Spacing: Implemented optimized grid template with fractional units
2.8fr 1.2fr 1.2fr 1.2fr 1fr - Action Button Spacing: Add and Delete icons now have proper space allocation with
colspanequivalent functionality - Ingredient Name Allocation: Ingredient names get adequate space with smart text truncation
- Responsive Adjustment: Grid automatically adapts to content while maintaining visual balance
- Grouped Formula Support: When grouped formulas are added to active panel, all reference panels show synchronized blank rows
- Perfect Alignment: All panels maintain consistent row structure regardless of expansion state
- Missing Row Prevention: Eliminated missing rows in Reference Formula and Reference Attributes panels
- Notes Panel Integration: Notes column now fully supports grouped formulas with proper row synchronization
- Horizontal Scroll Containers: Proper overflow handling prevents data from flowing out of panels
- Text Truncation: Long text gracefully truncates with ellipsis (...) while preserving readability
- Container Flexibility: Overflow containers use
overflowX: autofor smooth horizontal scrolling - Content Protection: All panels maintain their boundaries regardless of content length
- Warning Icon System: Replaced verbose "(missing ingredient)" text with clean warning icons
- Inline Icon Layout: Warning icons stay inline with text using optimized flex layout
- Tooltip Integration: Hover tooltips provide "Missing ingredient" information without cluttering the interface
- Color-Coded Warnings: Red warning icons (
#dc2626) provide clear visual distinction - Icon Positioning: Smart flex properties prevent icon wrapping to new lines
/* Optimized grid template for balanced spacing */
.grid-container {
grid-template-columns: 2.8fr 1.2fr 1.2fr 1.2fr 1fr;
}
/* Inline icon and text layout */
.inline-content {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
min-width: 0;
overflow: hidden;
}
/* Text truncation with icon protection */
.truncated-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
min-width: 0;
}
.protected-icon {
flex-shrink: 0; /* Prevents icon compression */
}- Left Panel: Collapsible Ingredients & Formulas Library with tabbed interface
- Right Panel: Active Workspace with Unified Grouped Columns for comprehensive formula management
- Smart Grid Layout: Optimized column spacing with balanced fractional units (2.8fr 1.2fr 1.2fr 1.2fr 1fr)
- Perfect Column Synchronization: All panels maintain consistent row alignment for grouped formulas
- Overflow Management: Horizontal scrolling containers with proper text truncation and ellipsis
- Responsive Design: Collapsible panels with drag handles and intelligent spacing
- Warning Icon System: Missing ingredients display inline warning icons with tooltips instead of verbose text
- Optimized Text Layout: Text and icons remain inline, preventing wrapping with proper flex controls
- Grouped Formula Notes: Notes panel fully supports grouped formulas with synchronized row structure
- Smart Text Truncation: Long text truncates with ellipsis while preserving important visual indicators
- Consistent Visual Language: Unified design system across all panels and components
- Smart Ingredient Aggregation: When adding reference formulas, ALL ingredients from those formulas automatically appear across ALL columns
- Missing Ingredient Detection: Ingredients present in reference formulas but missing from active formula are clearly marked with visual warning icons
- One-Click Add Functionality: Missing ingredients feature prominent "Add" buttons (+) to quickly incorporate them into the active formula
- Dynamic Content-Based Layout: All columns automatically adjust height based on content, preventing container overflow
- Perfect Row Synchronization: Grouped formulas maintain consistent row alignment across all panels for seamless comparison
- Optimized Grid Spacing: Balanced column spacing with intelligent fractional units for optimal space utilization
- Inline Editing: Real-time concentration and quantity adjustments with automatic recalculation
- Smart Batch Controls: Dynamic batch size management with unit selection (ml/g)
- Cost Calculations: Live cost updates per ingredient and total formula cost
- Formula Summary: Key metrics display including ingredient count and total concentration
- Action Buttons: Comprehensive formula operations (Save, Share, Download, Calculate)
- Comprehensive Database: Full ingredient library with CAS numbers and detailed attributes
- Category Organization: Natural, Synthetic, Solvent, and Functional ingredient classifications
- Rich Attributes: Intensity, family, note, volatility, solubility, and safety information
- Smart Search: Multi-field search across names, CAS numbers, and attributes
- Visual Status Indicators: Clear indication of already-added ingredients with warning icons for missing items
- Inline Warning System: Missing ingredients display warning tooltips with clear visual indicators
- Multi-Formula Comparison: Side-by-side analysis with unlimited reference formulas
- Visual Difference Indicators: Color-coded percentage differences (positive/negative/new)
- Attribute Analysis: Comprehensive ingredient property comparison with overflow protection
- Smart Highlighting: Common and unique ingredients clearly identified
- Advanced Search & Filter: Powerful filtering capabilities across all data points
- Grouped Formula Support: Formula groups maintain perfect row synchronization across all comparison panels
- Responsive Column Management: Horizontal scrolling with proper text truncation prevents data overflow
src/
โโโ services/
โ โโโ PegaIntegrationService.ts # Core Pega API integration service
โโโ hooks/
โ โโโ usePegaIntegration.ts # React hook for Pega operations
โโโ components/
โ โโโ PegaIntegrationPanel.tsx # UI for Pega submission management
โ โโโ FormulaWorkbench/ # Main formula creation workspace
โโโ types/
โโโ PegaTypes.ts # Pega-specific data structures
- Formula Creation: User builds formula using FormulaWorkbench component
- Real-time Validation: Continuous validation against Pega business rules
- Data Capture: Active formula data automatically formatted for Pega API
- API Submission: Structured payload sent to Pega REST endpoint
- Case Update: Pega case updated with formula data and status
- Response Handling: Success/error responses processed and displayed to user
// Main formula data structure for Pega
interface PegaFormulaData {
caseId: string; // Pega case identifier
formulaName: string; // User-defined formula name
formulaVersion: string; // Version control
author: string; // Formula creator
batchConfiguration: {
batchSize: number;
batchUnit: "ml" | "g";
};
ingredients: PegaIngredientData[]; // Complete ingredient list
formulaSummary: PegaFormulaSummary; // Calculated summary metrics
complianceStatus: {
// Regulatory compliance info
status: "compliant" | "non-compliant" | "pending-review";
lastChecked: string;
};
metadata: {
// Additional formula metadata
totalIngredients: number;
formulaComplexity: "simple" | "moderate" | "complex";
estimatedProductionCost: number;
sustainabilityScore: number;
};
}# Add to your .env file for Pega API integration
REACT_APP_PEGA_API_ENDPOINT=https://your-pega-instance.com/api/v1/formula
REACT_APP_PEGA_AUTH_TOKEN=your_pega_auth_token_here// Example usage in Pega Constellation
import { FormulaWorkbench, PegaIntegrationPanel } from "./components";
import { usePegaIntegration } from "./hooks/usePegaIntegration";
function PerfumerCaseWorkspace({ caseId, caseData }) {
const pegaIntegration = usePegaIntegration();
useEffect(() => {
// Initialize with Pega case context
pegaIntegration.initializePegaContext(caseId);
}, [caseId]);
return (
<div>
<FormulaWorkbench />
<PegaIntegrationPanel
initialCaseId={caseId}
defaultAuthor={caseData.author}
onSubmissionComplete={(success, result) => {
// Handle Pega submission result
if (success) {
console.log("Formula submitted to Pega:", result);
// Update case or navigate to next step
}
}}
/>
</div>
);
}- Case Initialization:
POST /api/pega/case/initialize - Formula Submission:
POST /api/pega/formula/submit - Validation Endpoint:
POST /api/pega/formula/validate - Status Updates:
GET /api/pega/case/{caseId}/status
- Library-First Approach: Start with ingredient/formula selection in left panel
- Drag-Free Operations: Click-to-add functionality eliminates complex interactions
- Visual Feedback: Immediate visual confirmation for all user actions
- Smart Defaults: Intelligent default values for concentration, cost, and units
- Unified View: All ingredient data consolidated in single workspace view
- Contextual Actions: Action buttons appear contextually based on ingredient state
- Hover Enhancements: Rich hover states with opacity and scale transitions
- Progressive Disclosure: Collapsible panels reveal/hide information as needed
- Inline Visual Feedback: Warning icons with tooltips for missing ingredients
- Optimized Grid Spacing: Balanced column allocation for Add/Delete icons and ingredient names
- Text Overflow Protection: Smart truncation with ellipsis prevents layout breaking
- Status Indicators: Green (added), Blue (new), Red (remove), Gray (missing)
- Difference Visualization: Positive/negative percentage changes clearly marked
- Category Coding: Ingredient types distinguished by consistent color schemes
- Accessibility Compliant: High contrast ratios meeting WCAG AA standards
- Dynamic Layout: Container heights automatically adjust to content
- Touch-Friendly: Minimum 44px touch targets for mobile devices
- Swipe Gestures: Horizontal scrolling for reference formula columns
- Breakpoint Management: Fluid design across mobile, tablet, and desktop
- Node.js (v16 or higher)
- npm or yarn
- Modern web browser (Chrome 90+, Firefox 88+, Safari 14+)
- Pega Platform: Pega Platform 8.5+ with Constellation UI framework
# Clone the repository
git clone <repository-url>
cd createFormula
# Install dependencies
npm install
# Configure Pega integration (create .env file)
echo "REACT_APP_PEGA_API_ENDPOINT=https://your-pega-instance.com/api/v1" > .env
# Start development server (runs on http://localhost:3001)
npm run dev
# Open browser and start building formulas!npm run dev # Start development server with hot reload
npm run build # Build optimized production bundle for Pega integration
npm run preview # Preview production build locally
npm run lint # Run ESLint for code quality checks# Build for Pega Constellation integration
npm run build
# The /dist folder contains the optimized component bundle
# Import into your Pega application as a custom UI component- CSS Grid Mastery: Optimized grid template columns with fractional units for perfect spacing balance
- Flexbox Integration: Smart flex properties for text truncation and icon alignment
- Overflow Management: Sophisticated horizontal scroll containers with proper text handling
- Row Synchronization Algorithm: Advanced logic to maintain consistent row alignment across all panels
- Responsive Grid Adaptation: Dynamic column sizing that adapts to content while maintaining proportions
- React Context Architecture: Centralized formula state management with
FormulaContext - Optimized Re-renders: Memoized calculations and selective component updates
- Real-time Synchronization: Live updates across all columns when data changes
- Batch Operations: Efficient handling of multiple ingredient additions/removals
- Grouped Formula State: Complex state management for formula groups with expanded/collapsed states
- 100% Type Coverage: Strict TypeScript mode with comprehensive interfaces
- Generic Components: Reusable typed components for different data structures
- Interface Contracts: Well-defined props and state interfaces
- Type Guards: Runtime type checking for data validation
- Intelligent Memoization:
useMemoanduseCallbackfor expensive operations - Virtual Scrolling Ready: Architecture prepared for large ingredient datasets
- Debounced Interactions: Smooth user interactions with optimized event handling
- Bundle Optimization: Tree shaking and code splitting capabilities
- Efficient Row Generation: Optimized getAllRowItems algorithm for unified ingredient display
- Smart Text Rendering: Flex-based text truncation that preserves performance
- Custom Hooks: Reusable logic for ingredient management and calculations
- Compound Components: Flexible composition patterns for complex UI elements
- Error Boundaries: Graceful error handling and user feedback
- Suspense Ready: Prepared for concurrent React features
// Enhanced Ingredient Model with Rich Attributes
interface Ingredient {
id: string;
name: string;
casNumber: string;
category: "Natural" | "Synthetic" | "Solvent" | "Functional";
defaultConcentration: number;
costPerKg: number;
tags: string[];
attributes: {
intensity?: number;
family?: string;
note?: "Top" | "Middle" | "Base";
volatility?: "high" | "medium" | "low";
solubility?: "water" | "oil" | "alcohol";
};
description?: string;
safetyNotes?: string;
regulatoryStatus?: string;
sustainabilityRating?: number;
allergenRisk?: "low" | "medium" | "high";
supplier?: string;
createdAt: Date;
updatedAt: Date;
}
// Active Formula Ingredient with Additional Context
interface FormulaIngredient {
id: string;
ingredient: Ingredient;
concentration: number;
quantity: number;
unit: "ml" | "g";
isMissing?: boolean; // For unified ingredient display
notes?: string;
}
// Reference Formula for Comparison
interface ReferenceFormula {
metadata: {
id: string;
name: string;
author?: string;
base?: string;
ph?: number;
cost?: number;
density?: string;
stability?: string;
};
ingredients: Array<{
ingredientName: string;
concentration: number;
}>;
}
// Formula Summary with Real-time Calculations
interface FormulaSummary {
totalWeight: number;
totalCost: number;
ingredientCount: number;
totalConcentration: number;
averageCostPerKg: number;
batchSize: number;
batchUnit: "ml" | "g";
complianceStatus: "compliant" | "non-compliant" | "pending";
}// Core algorithm for unified ingredient display with row synchronization
const getAllRowItems = () => {
const rowItems: Array<{
type: "ingredient" | "formulaGroup" | "expandedIngredient" | "blank";
data: any;
}> = [];
const activeIngredientMap = new Map<string, FormulaIngredient>();
// Process active ingredients including formula groups
activeIngredients.forEach((item) => {
if ("type" in item && item.type === "formulaGroup") {
// Add formula group header for perfect row synchronization
rowItems.push({
type: "formulaGroup",
data: item,
});
// Process ingredients within formula groups
if (item.ingredients && Array.isArray(item.ingredients)) {
item.ingredients.forEach((groupIngredient: any) => {
if (groupIngredient.ingredient?.name) {
activeIngredientMap.set(
groupIngredient.ingredient.name,
groupIngredient
);
rowItems.push({
type: "expandedIngredient",
data: { ...groupIngredient, isMissing: false },
});
}
});
}
} else {
// Regular ingredient processing
const formulaIngredient = item as FormulaIngredient;
if (formulaIngredient.ingredient?.name) {
activeIngredientMap.set(
formulaIngredient.ingredient.name,
formulaIngredient
);
rowItems.push({
type: "ingredient",
data: { ...formulaIngredient, isMissing: false },
});
}
}
});
// Add missing ingredients with warning indicators
const processedIngredients = new Set<string>();
activeIngredientMap.forEach((_, ingredientName) => {
processedIngredients.add(ingredientName);
});
referenceFormulas.forEach((formula) => {
formula.ingredients.forEach((ing: any) => {
if (
ing.concentration > 0 &&
!processedIngredients.has(ing.ingredientName)
) {
const ingredient = mockIngredients.find(
(mockIng) => mockIng.name === ing.ingredientName
);
rowItems.push({
type: "ingredient",
data: {
id: `missing-${ing.ingredientName}`,
ingredient: ingredient || {
id: `unknown-${ing.ingredientName}`,
name: ing.ingredientName,
attributes: {},
},
concentration: 0,
quantity: 0,
isMissing: true, // Triggers warning icon display
},
});
processedIngredients.add(ing.ingredientName);
}
});
});
// Add blank row for "Add Ingredient" button alignment
rowItems.push({
type: "blank",
data: null,
});
return rowItems;
};- Start with Active Formula: Add ingredients to create your base formula
- Add Reference Formulas: Select reference formulas for comparison from the library
- Automatic Aggregation: ALL ingredients from active + reference formulas appear in ALL columns
- Missing Ingredient Detection: Ingredients present in references but missing from active are highlighted with warning icons
- One-Click Addition: Click the "+" button to instantly add missing ingredients to active formula
- Dynamic Updates: All calculations and displays update in real-time
- Perfect Row Sync: Grouped formulas maintain consistent alignment across all panels
- Overflow Protection: Long text truncates with ellipsis while preserving visual indicators
- Multi-Formula View: Each reference formula gets its own column for side-by-side comparison
- Percentage Differences: Visual indicators show +/- percentage differences vs active formula
- Missing/Present Indicators: Clear visual cues for ingredient presence across formulas
- Contextual Actions: Remove individual reference formulas or ingredients as needed
- Attribute Analysis: Compare ingredient properties across all formulas simultaneously
- Intelligent Lookup: System matches ingredients by name with fuzzy matching capability
- Fallback Creation: Creates temporary ingredient entries for unknowns with sensible defaults
- Bulk Operations: Add multiple missing ingredients efficiently
- Real-time Validation: Immediate feedback on ingredient additions/modifications
- Enhanced Formula Library: Categorization, tagging, and advanced search capabilities
- Batch Operations: Multi-ingredient selection and bulk actions
- Formula Validation: Real-time compliance checking and regulatory warnings
- Export Functionality: PDF, Excel, and industry-standard format exports
- User Preferences: Customizable defaults, units, and display options
- AI-Powered Suggestions: Intelligent ingredient recommendations based on existing formulas
- Sustainability Metrics: Environmental impact scoring and eco-friendly alternatives
- Cost Optimization: Automatic suggestions for cost-effective ingredient substitutions
- Regulatory Compliance: Region-specific safety and legal requirement validation
- Historical Analysis: Formula version control and change tracking
- Multi-User Collaboration: Real-time collaborative formula development
- Database Integration: Full backend connectivity with PostgreSQL/MongoDB
- API Ecosystem: RESTful APIs for external system integration
- Analytics Dashboard: Usage patterns, popular ingredients, and performance metrics
- White-Label Solutions: Customizable branding for different organizations
- Performance Scaling: Virtual scrolling for large datasets (1000+ ingredients)
- Advanced State Management: Redux/Zustand integration for complex workflows
- PWA Capabilities: Offline functionality and mobile app-like experience
- Real-time Sync: WebSocket integration for live collaborative editing
- Microservices Architecture: Scalable backend services for enterprise deployment
# Clone the repository
git clone <repository-url>
cd createFormula
# Install dependencies
npm install
# Start development server with hot reload
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run linting
npm run lint- Component Structure: Follow the established FormulaWorkbench pattern with grouped columns
- TypeScript First: All new code must be fully typed with strict mode compliance
- Styled Components: Use the centralized styling system, no global CSS
- Unified System: Extend the unified ingredient display pattern for new features
- Performance: Implement memoization for expensive calculations
- Accessibility: Ensure WCAG AA compliance for all new UI elements
- Separation of Concerns: Keep data, logic, and presentation layers distinct
- Reusable Components: Create small, composable components with clear interfaces
- Context Usage: Leverage React Context for cross-component state management
- Error Handling: Implement proper error boundaries and user feedback
- Testing Strategy: Write unit tests for business logic and integration tests for workflows
- Feature Development: Create feature branches from main
- Code Review: All changes require peer review before merging
- Testing: Ensure new features include appropriate test coverage
- Documentation: Update README and component documentation for new features
- Performance: Profile performance impact of changes using React DevTools
This project is licensed under the MIT License - see the LICENSE file for details.
- React Team: For the amazing framework
- Styled Components: For the excellent styling solution
- Lucide React: For the beautiful icons
- Inter Font: For the modern typography
- Fragrance Industry: For inspiration and domain knowledge