Select Control
Select controls provide a dropdown interface for choosing from a predefined set of options. They support both static option lists and dynamic options that are fetched asynchronously, making them ideal for configuration choices and API-driven selections.
Basic Usage
import * as i from '@xentom/integration-framework';
// Simple static options
i.controls.select({
label: 'HTTP Method',
placeholder: 'Choose a method',
options: [
{ value: 'GET', label: 'GET' },
{ value: 'POST', label: 'POST' },
{ value: 'PUT', label: 'PUT' },
{ value: 'DELETE', label: 'DELETE' },
],
});Configuration Options
Prop
Type
Static Options
For fixed sets of choices, use a static array of options:
// Simple value/label pairs
priority: i.pins.data({
control: i.controls.select({
label: 'Priority Level',
placeholder: 'Select priority...',
options: [
{ value: 'low', label: 'Low Priority' },
{ value: 'medium', label: 'Medium Priority' },
{ value: 'high', label: 'High Priority' },
{ value: 'urgent', label: 'Urgent' },
],
}),
});
// Options with descriptions
region: i.pins.data({
control: i.controls.select({
label: 'AWS Region',
options: [
{
value: 'us-east-1',
label: 'US East (N. Virginia)',
description: 'Primary AWS region for US customers',
},
{
value: 'us-west-2',
label: 'US West (Oregon)',
description: 'West coast AWS region',
},
{
value: 'eu-west-1',
label: 'Europe (Ireland)',
description: 'Primary AWS region for European customers',
},
],
}),
});Dynamic Options
For options that need to be fetched from external sources, use an async callback function. Note: Dynamic options are only supported for node pins, not environment variables.
// Fetch options from API
apiEndpoint: i.pins.data({
control: i.controls.select({
label: 'API Endpoint',
placeholder: 'Select an endpoint...',
options: async ({ state }) => {
// Access shared integration state
const client = state.apiClient;
const endpoints = await client.getEndpoints();
return endpoints.map((endpoint) => ({
value: endpoint.url,
label: endpoint.name,
description: `${endpoint.method} ${endpoint.path}`,
}));
},
}),
});
// Database-driven options
userId: i.pins.data({
control: i.controls.select({
label: 'User',
placeholder: 'Select a user...',
options: async ({ state }) => {
const users = await state.database.getUsers();
return users.map((user) => ({
value: user.id,
label: user.displayName,
description: user.email,
}));
},
}),
});Option Structure
Each option in the array must follow this structure:
Prop
Type
Complex Value Types
Select controls aren't limited to string values - they can handle any serializable data type:
// Object values
database: i.pins.data({
control: i.controls.select({
label: 'Database Connection',
options: [
{
value: { host: 'localhost', port: 5432, name: 'dev_db' },
label: 'Development Database',
description: 'Local development environment',
},
{
value: { host: 'prod.example.com', port: 5432, name: 'prod_db' },
label: 'Production Database',
description: 'Live production environment',
},
],
}),
});
// Numeric values
timeout: i.pins.data({
control: i.controls.select({
label: 'Request Timeout',
options: [
{ value: 5000, label: '5 seconds' },
{ value: 10000, label: '10 seconds' },
{ value: 30000, label: '30 seconds' },
{ value: 60000, label: '1 minute' },
],
}),
});Caching Dynamic Options
For expensive API calls, implement caching in your integration state:
// In your integration definition
async start({ state }) {
state.optionsCache = new Map();
state.apiClient = new ApiClient();
}
// In your select control
options: async ({ state }) => {
const cacheKey = 'api_endpoints';
if (state.optionsCache.has(cacheKey)) {
return state.optionsCache.get(cacheKey);
}
const endpoints = await state.apiClient.getEndpoints();
const options = endpoints.map(ep => ({
value: ep.id,
label: ep.name,
description: `${ep.method} ${ep.path}`
}));
// Cache for 5 minutes
state.optionsCache.set(cacheKey, options);
setTimeout(() => {
state.optionsCache.delete(cacheKey);
}, 5 * 60 * 1000);
return options;
}Common Patterns
HTTP Methods
method: i.pins.data({
control: i.controls.select({
label: 'HTTP Method',
default: 'GET',
options: [
{ value: 'GET', label: 'GET', description: 'Retrieve data' },
{ value: 'POST', label: 'POST', description: 'Create new resource' },
{ value: 'PUT', label: 'PUT', description: 'Update entire resource' },
{ value: 'PATCH', label: 'PATCH', description: 'Partial update' },
{ value: 'DELETE', label: 'DELETE', description: 'Remove resource' },
],
}),
});Content Types
contentType: i.pins.data({
control: i.controls.select({
label: 'Content Type',
default: 'application/json',
options: [
{ value: 'application/json', label: 'JSON' },
{ value: 'application/xml', label: 'XML' },
{ value: 'text/plain', label: 'Plain Text' },
{ value: 'text/html', label: 'HTML' },
],
}),
});Environment-Specific Configuration
// For environment variables (static options only)
ENVIRONMENT: i.env({
control: i.controls.select({
label: 'Environment',
description: 'Target deployment environment',
options: [
{ value: 'development', label: 'Development' },
{ value: 'staging', label: 'Staging' },
{ value: 'production', label: 'Production' },
],
}),
});Usage Context
Select controls can be used in two contexts:
- Environment Variables: Only static options are supported
- Node Pins: Both static and dynamic options are supported
Dynamic options provide powerful integration with external data sources but require careful consideration of performance and caching strategies.
Boolean Control
Boolean controls provide a simple toggle interface for boolean values (true/false). They're ideal for enabling or disabling features, setting configuration flags, and any scenario where you need a clear on/off state.
Object Control
Object controls provide a JSON editor for supplying structured data — objects, arrays, or any JSON-serializable value. They're ideal for HTTP headers, custom metadata, configuration maps, and typed arrays where users need to supply composite values rather than a single scalar.