panel-config.json is a centralized configuration file that defines the structure, validation rules, and rendering properties for all form fields used in the integration management system. It serves as a single source of truth for field definitions, eliminating hardcoded field configurations scattered throughout the codebase.
The panel configuration system provides:
- Template-driven form generation - Fields can be rendered dynamically based on configuration
- Centralized validation rules - All validation logic is defined in one place
- Consistent field behavior - Same configuration drives both frontend rendering and validation
- Easy maintenance - Add, modify, or remove fields by editing JSON without touching code
- Type safety - Clear separation between data types and HTML rendering types
The configuration file is organized into sections, where each section represents a step or category of fields:
{
"sectionName": {
"fieldName": {
// Field configuration properties
}
}
}basicInfo- Fields for Step 1 (Basic Information)features- Fields for Step 3 (Features & Endpoints)rateLimits- Fields for Step 4 (Rate Limits configuration)additionalFields- Configuration for Extra Fields in Feature-Integration MappingcustomHandlers- Configuration for Custom Handler Types (NEW)
Each field in the configuration must follow this structure:
The display label shown to users in the UI.
"label": "Integration Name"Rules:
- Must be user-friendly and descriptive
- Should use title case
- Keep it concise (2-5 words recommended)
Help text or instructions for the field. Provides additional context to users.
"description": "The display name shown to users"Rules:
- Should explain the purpose or expected input
- Can include examples or constraints
- Keep it under 100 characters for better UX
Defines the data type for validation purposes. This is used by the backend/validators to ensure data integrity.
"dataType": "string"Supported values:
"string"- Text data"number"- Numeric data (integer or float)"url"- Valid URL format"email"- Valid email format"boolean"- True/false values
Rules:
- Choose the appropriate type for validation
- This does NOT affect HTML rendering (use
htmlTypefor that)
Defines how the field should be rendered in HTML. This strictly controls the UI element type.
"htmlType": "text"Supported values:
"text"- Single-line text input (<input type="text">)"textarea"- Multi-line text input (<textarea>)"number"- Number input (<input type="number">)"select"- Dropdown menu (<select>)"checkbox"- Checkbox input (<input type="checkbox">)"radio"- Radio button (<input type="radio">)
Rules:
- Choose based on UI/UX requirements, not data type
- Example: A URL field should have
htmlType: "text"(not "url") because HTML type="url" has browser-specific behavior
Indicates whether the field must have a value.
"required": trueRules:
- Use
truefor mandatory fields - Use
falsefor optional fields - If required, validation will fail when field is empty
Placeholder text shown in empty input fields.
"placeholder": "e.g., Salesforce"Rules:
- Should provide an example value
- Use "e.g., ..." format for clarity
- Keep it short and relevant
Default value for the field when not provided by user.
"default": "1.0.0"Rules:
- Type should match
dataType - Used for optional fields with sensible defaults
Regular expression pattern for string validation.
"pattern": "^[a-z0-9_-]+$"Rules:
- Only applicable when
dataType: "string" - Must be a valid JavaScript regex pattern
- Used to enforce specific formats (e.g., lowercase, no spaces)
Minimum character length for string fields.
"minLength": 3Rules:
- Only applicable when
dataType: "string" - Must be a positive integer
- Validation fails if string length < minLength
Maximum character length for string fields.
"maxLength": 100Rules:
- Only applicable when
dataType: "string" - Must be a positive integer
- Validation fails if string length > maxLength
Minimum value for numeric fields.
"min": 1Rules:
- Only applicable when
dataType: "number" - Can be any number (integer or float)
- Validation fails if value < min
Maximum value for numeric fields.
"max": 10000Rules:
- Only applicable when
dataType: "number" - Can be any number (integer or float)
- Validation fails if value > max
Available options for select/dropdown fields.
"options": [
{ "value": "crm", "label": "CRM" },
{ "value": "payment", "label": "Payment" }
]Rules:
- Only applicable when
htmlType: "select" - Each option must have
valueandlabel valueis stored in data,labelis shown to user
This is a critical distinction in the configuration system:
- Purpose: Validation and data integrity
- Used by: Backend validators, type checking
- Example:
"dataType": "url"ensures the value is a valid URL
- Purpose: UI rendering and user interaction
- Used by: Frontend form generation
- Example:
"htmlType": "text"renders a text input box
For a documentation URL field:
"docsUrl": {
"label": "Documentation URL",
"description": "Link to API documentation",
"dataType": "url", // ← Validates as URL
"htmlType": "text", // ← Renders as text input
"required": false,
"placeholder": "https://docs.example.com"
}Why this combination?
dataType: "url"- Ensures the value is a valid URL using URL validationhtmlType: "text"- Renders as a simple text input (not HTML5 type="url" which has browser-specific validation and behavior)
When a form is submitted:
- Data Collection: Field values are collected from the form
- Config Loading: The relevant section from
panel-config.jsonis loaded - Field Validation: For each field:
- Check
requiredproperty - Validate against
dataTyperules - Apply
pattern,min,max, etc. constraints
- Check
- Error Handling: First validation error is shown to user
- Data Storage: Valid data is stored and processed
To add a new section (e.g., for a new wizard step):
{
"basicInfo": { ... },
"features": { ... },
"rateLimits": { ... },
"newSection": {
"fieldOne": {
"label": "Field One",
"description": "Description of field one",
"dataType": "string",
"htmlType": "text",
"required": true
},
"fieldTwo": {
"label": "Field Two",
"description": "Description of field two",
"dataType": "number",
"htmlType": "number",
"required": false,
"default": 0
}
}
}To add a new field to an existing section:
"sectionName": {
"existingField": { ... },
"newField": {
"label": "New Field Label", // Required: User-facing label
"description": "What this field does", // Required: Help text
"dataType": "string", // Required: Validation type
"htmlType": "text", // Required: HTML element type
"required": true, // Required: Is it mandatory?
"placeholder": "e.g., example", // Optional: Example value
"pattern": "^[a-z]+$", // Optional: Regex validation
"default": "defaultValue" // Optional: Default value
}
}| Property | dataType | Required | Notes |
|---|---|---|---|
pattern |
string |
No | Regex pattern for string matching |
minLength |
string |
No | Minimum character length |
maxLength |
string |
No | Maximum character length |
min |
number |
No | Minimum numeric value |
max |
number |
No | Maximum numeric value |
options |
any | No | Only with htmlType: "select" |
Every field must have both properties for clear UI and user guidance.
// ✅ Good
"displayName": {
"label": "Integration Name",
"description": "The display name shown to users",
...
}
// ❌ Bad
"displayName": {
"dataType": "string",
...
}Use the most specific type for proper validation.
// ✅ Good - URL validation will be applied
"iconUrl": {
"dataType": "url",
"htmlType": "text"
}
// ❌ Bad - No URL validation
"iconUrl": {
"dataType": "string",
"htmlType": "text"
}For fields requiring specific formats, use regex patterns.
"id": {
"label": "Unique Identifier",
"description": "Lowercase, numbers, hyphens, and underscores only",
"dataType": "string",
"htmlType": "text",
"required": true,
"pattern": "^[a-z0-9_-]+$" // ✅ Enforces format
}Use examples that show the expected format.
// ✅ Good
"placeholder": "e.g., salesforce"
// ❌ Bad
"placeholder": "Enter value"For optional fields, provide defaults when appropriate.
"version": {
"label": "Version",
"dataType": "string",
"htmlType": "text",
"required": false,
"default": "1.0.0" // ✅ Good default
}Group related fields into logical sections.
{
"basicInfo": {
// Basic integration details
},
"authSettings": {
// Authentication configuration
},
"advanced": {
// Advanced options
}
}The Validators utility (public/js/validators.js) reads this configuration and applies rules automatically:
// Load config
const panelConfig = await fetch('/api/panel-config').then(r => r.json());
// Collect form data
const formData = {
displayName: "My Integration",
id: "my-integration",
category: "crm"
};
// Validate using config
const result = Validators.validateFields(formData, panelConfig.basicInfo);
if (!result.valid) {
console.log(result.errors); // { displayName: ["..."], id: ["..."] }
}Validation errors are generated automatically based on field configuration:
- Required:
"{label} is required" - Pattern:
"{label} format is invalid. {description}" - Min/Max:
"{label} must be at least {min}"or"{label} must be at most {max}" - Type:
"{label} must be a valid {dataType}"
Example:
"id": {
"label": "Unique Identifier",
"pattern": "^[a-z0-9_-]+$",
"required": true
}Error: "Unique Identifier is required" or "Unique Identifier format is invalid"
To add a new data type (e.g., date, json):
- Add validation function in
validators.js:
isDate(value) {
return !isNaN(Date.parse(value));
}- Add case in
validateField():
case 'date':
if (!this.isDate(value)) {
errors.push(`${label} must be a valid date`);
}
break;- Use in
panel-config.json:
"createdAt": {
"dataType": "date",
"htmlType": "text"
}For new HTML elements (e.g., file, color):
- Add to supported
htmlTypevalues in this documentation - Update form rendering logic to handle the new type
- Use in
panel-config.json:
"logo": {
"dataType": "string",
"htmlType": "file"
}- Ensure
dataTypeis spelled correctly - Check if validators.js is loaded
- Verify panel-config.json is valid JSON
- Ensure form rendering logic reads the config
- Check
htmlTypeis a supported value - Verify the section name matches
- Double-check
dataTypevshtmlType - Ensure
patternis valid regex - Verify
min/maxmatch data type
Added: 2025-11-26 Purpose: Centralized configuration for custom handler types
The customHandlers section defines handler types that can be applied to fields for transformation, validation, and processing. This is a special section - unlike other sections, it doesn't define form fields but rather defines handler type metadata.
{
"customHandlers": {
"handlerTypeId": {
"id": "handlerTypeId",
"label": "Handler Type Label",
"description": "What this handler does",
"placeholder": "e.g., functionName",
"icon": "🔧",
"helpText": "Detailed explanation",
"category": "transformation|validation|submission|formatting|parsing|conditional",
"order": 1
}
}
}Unique identifier matching the key. Must be camelCase.
"id": "valueHandler"Display name shown in UI.
"label": "Value Handler"Brief explanation of handler purpose (for tooltips).
"description": "Transform or normalize field values before processing"Example function name shown in input field.
"placeholder": "e.g., capitalizeFirstName, formatPhoneNumber"Unicode icon displayed next to handler name.
"icon": "↓"Common icons:
↓- Transformation/input✓- Validation/check⚙- Processing/submission📝- Formatting/display🔍- Parsing/extraction🔀- Conditional/branching
Detailed explanation shown below input field.
"helpText": "Function to transform field values (e.g., uppercase, trim spaces)"Handler category for organization.
"category": "transformation"Supported categories:
transformation- Value transformationvalidation- Value validationsubmission- API submission processingformatting- Display formattingparsing- Data parsingconditional- Conditional logic
Display order in UI (ascending). Determines column order in tables.
"order": 1The system includes 6 built-in handler types:
{
"customHandlers": {
"valueHandler": {
"id": "valueHandler",
"label": "Value Handler",
"description": "Transform or normalize field values before processing",
"placeholder": "e.g., capitalizeFirstName, formatPhoneNumber",
"icon": "↓",
"helpText": "Function to transform field values (e.g., uppercase, trim spaces)",
"category": "transformation",
"order": 1
},
"validationHandler": {
"id": "validationHandler",
"label": "Validation Handler",
"description": "Validate field values and return error messages if invalid",
"placeholder": "e.g., validateEmail, validatePhoneNumber",
"icon": "✓",
"helpText": "Function to validate field values (returns true or error message)",
"category": "validation",
"order": 2
},
"submitHandler": {
"id": "submitHandler",
"label": "Submit Handler",
"description": "Process field values before API submission",
"placeholder": "e.g., encryptData, base64Encode",
"icon": "⚙",
"helpText": "Function to process values before sending to API",
"category": "submission",
"order": 3
},
"formatHandler": {
"id": "formatHandler",
"label": "Format Handler",
"description": "Format field values for display purposes",
"placeholder": "e.g., formatCurrency, formatDate",
"icon": "📝",
"helpText": "Function to format values for display",
"category": "formatting",
"order": 4
},
"parseHandler": {
"id": "parseHandler",
"label": "Parse Handler",
"description": "Parse incoming data before populating fields",
"placeholder": "e.g., parseJSON, parseXML",
"icon": "🔍",
"helpText": "Function to parse data from API responses",
"category": "parsing",
"order": 5
},
"conditionalHandler": {
"id": "conditionalHandler",
"label": "Conditional Handler",
"description": "Determine if field should be shown/enabled based on conditions",
"placeholder": "e.g., showIfPremium, enableIfAdmin",
"icon": "🔀",
"helpText": "Function to evaluate field visibility/enablement",
"category": "conditional",
"order": 6
}
}
}Handler configuration is accessible via REST API:
Endpoint:
GET /api/panel-config/custom-handlers
Response:
{
"valueHandler": { ... },
"validationHandler": { ... },
"submitHandler": { ... },
"formatHandler": { ... },
"parseHandler": { ... },
"conditionalHandler": { ... }
}Handler types are automatically integrated into:
-
Feature-Integration Mapping Wizard
- Field Configuration Modal (Step 2)
- Extra Fields Modal (Step 4)
-
Integration Detail Page
- Template Fields table columns
- Extra Fields table columns
The system automatically:
- ✅ Renders input fields based on handler config
- ✅ Sorts handlers by
orderproperty - ✅ Displays icons, labels, and help text
- ✅ Validates handler function names (alphanumeric + underscore only)
- ✅ Updates table headers dynamically
To add a custom handler type:
- Add to panel-config.json:
{
"customHandlers": {
"myCustomHandler": {
"id": "myCustomHandler",
"label": "My Custom Handler",
"description": "Does something custom",
"placeholder": "e.g., myCustomFunction",
"icon": "✨",
"helpText": "Detailed instructions for using this handler",
"category": "custom",
"order": 7
}
}
}-
Restart the server (handler config is loaded on startup)
-
No code changes needed! The UI automatically updates to show the new handler type in all relevant locations.
✅ DO:
- Use clear, descriptive labels
- Provide helpful placeholders with examples
- Write comprehensive help text
- Choose appropriate icons that convey meaning
- Assign logical order values (gaps of 1 or 10)
- Keep handler IDs in camelCase
❌ DON'T:
- Use generic labels like "Handler 1"
- Leave placeholder or helpText empty
- Use random emojis that don't relate to function
- Reuse order numbers (causes unpredictable sorting)
- Use special characters in handler IDs
Prior to this feature (before 2025-11-26), handler types were hardcoded in JavaScript files. The old system had only 3 handlers: valueHandler, validationHandler, and submitHandler.
Benefits of the new system:
- ✅ No code changes to add/modify handler types
- ✅ Centralized configuration
- ✅ Consistent behavior across all pages
- ✅ Easy to extend with new handler types
- ✅ Self-documenting with metadata
The panel-config.json system provides a powerful, maintainable way to manage form fields:
- ✅ Single source of truth for field definitions
- ✅ Automatic validation based on configuration
- ✅ Clear separation:
dataTypefor validation,htmlTypefor rendering - ✅ Easy to extend and maintain
- ✅ Consistent user experience across the application
- ✅ NEW: Dynamic custom handler configuration without code changes
When adding or modifying fields, always follow the property rules and best practices outlined in this guide.