mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
improvement(integrations, models): ui/ux (#4105)
* improvement(integrations, models): ui/ux * fix(models, integrations): dedup ChevronArrow/provider colors, fix UTC date rendering - Extract PROVIDER_COLORS and getProviderColor to model-colors.ts to eliminate identical definitions in model-comparison-charts and model-timeline-chart - Remove duplicate private ChevronArrow from integration-card; import the exported one from model-primitives instead - Add timeZone: 'UTC' to formatShortDate so ISO date-only strings (parsed as UTC midnight) render the correct calendar day in all timezones * refactor(models): rename model-colors.ts to consts.ts * improvement(models): derive provider colors/resellers from definitions, reorient FAQs to agent builder Dynamic data: - Add `color` and `isReseller` fields to ProviderDefinition interface - Move brand colors for all 10 providers into their definitions - Mark 6 reseller providers (Azure, Bedrock, Vertex, OpenRouter, Fireworks) - consts.ts now derives color map from MODEL_CATALOG_PROVIDERS - model-comparison-charts derives RESELLER_PROVIDERS from catalog - Fix deepseek name: Deepseek → DeepSeek; remove now-redundant PROVIDER_NAME_OVERRIDES and getProviderDisplayName from utils - Add color/isReseller fields to CatalogProvider; clean up duplicate providerDisplayName in searchText array FAQs: - Replace all 4 main-page FAQs with 5 agent-builder-oriented ones covering model selection, context windows, pricing, tool use, and how to use models in a Sim agent workflow - buildProviderFaqs: add conditional tool use FAQ per provider - buildModelFaqs: add bestFor FAQ (conditional on field presence); improve context window answer to explain agent implications; tighten capabilities answer wording * chore(models): remove model-colors.ts (superseded by consts.ts) * update footer --------- Co-authored-by: waleed <walif6@gmail.com>
This commit is contained in:
@@ -100,7 +100,7 @@ interface IntegrationEntry {
|
||||
triggerCount: number
|
||||
authType: 'oauth' | 'api-key' | 'none'
|
||||
category: string
|
||||
integrationType?: string
|
||||
integrationTypes?: string[]
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
@@ -676,7 +676,14 @@ async function writeIntegrationsJson(iconMapping: Record<string, string>): Promi
|
||||
triggerCount: triggers.length,
|
||||
authType,
|
||||
category: config.category,
|
||||
...(config.integrationType ? { integrationType: config.integrationType } : {}),
|
||||
...(config.integrationType || config.tags
|
||||
? {
|
||||
integrationTypes: deriveIntegrationTypes(
|
||||
config.integrationType || null,
|
||||
config.tags || []
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
...(config.tags ? { tags: config.tags } : {}),
|
||||
})
|
||||
}
|
||||
@@ -930,6 +937,85 @@ function extractStringPropertyFromContent(
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag-to-category mapping used by deriveIntegrationTypes to expand a block's
|
||||
* primary integrationType into a full set of categories for the landing page.
|
||||
*/
|
||||
const TAG_TO_CATEGORIES: Record<string, string[]> = {
|
||||
llm: ['ai'],
|
||||
agentic: ['ai'],
|
||||
'image-generation': ['ai', 'design'],
|
||||
'video-generation': ['ai', 'design'],
|
||||
'text-to-speech': ['ai'],
|
||||
'speech-to-text': ['ai'],
|
||||
ocr: ['ai', 'documents'],
|
||||
'vector-search': ['ai', 'search'],
|
||||
'document-processing': ['documents'],
|
||||
'content-management': ['documents'],
|
||||
'e-signatures': ['documents'],
|
||||
'note-taking': ['productivity', 'documents'],
|
||||
'knowledge-base': ['documents', 'search'],
|
||||
'data-analytics': ['analytics'],
|
||||
seo: ['analytics', 'search'],
|
||||
monitoring: ['developer-tools', 'analytics'],
|
||||
'error-tracking': ['developer-tools'],
|
||||
'incident-management': ['developer-tools'],
|
||||
'version-control': ['developer-tools'],
|
||||
'ci-cd': ['developer-tools'],
|
||||
'feature-flags': ['developer-tools'],
|
||||
messaging: ['communication'],
|
||||
meeting: ['communication', 'productivity'],
|
||||
calendar: ['productivity'],
|
||||
scheduling: ['productivity'],
|
||||
'project-management': ['productivity'],
|
||||
ticketing: ['productivity', 'customer-support'],
|
||||
forms: ['productivity'],
|
||||
spreadsheet: ['productivity', 'databases'],
|
||||
'data-warehouse': ['databases'],
|
||||
cloud: ['developer-tools'],
|
||||
'web-scraping': ['search'],
|
||||
'sales-engagement': ['sales'],
|
||||
enrichment: ['sales'],
|
||||
'email-marketing': ['email'],
|
||||
marketing: ['analytics'],
|
||||
payments: ['ecommerce'],
|
||||
subscriptions: ['ecommerce'],
|
||||
hiring: ['hr'],
|
||||
identity: ['security'],
|
||||
'secrets-management': ['security'],
|
||||
'customer-support': ['customer-support'],
|
||||
webhooks: ['developer-tools'],
|
||||
automation: ['developer-tools'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the full list of integration type categories from a block's primary
|
||||
* integrationType and its tags. The primary type is always first; additional
|
||||
* categories are inferred from tags via TAG_TO_CATEGORIES.
|
||||
*/
|
||||
function deriveIntegrationTypes(primaryType: string | null, tags: string[]): string[] {
|
||||
const types = new Set<string>()
|
||||
if (primaryType) {
|
||||
types.add(primaryType)
|
||||
}
|
||||
for (const tag of tags) {
|
||||
const mapped = TAG_TO_CATEGORIES[tag]
|
||||
if (mapped) {
|
||||
for (const t of mapped) {
|
||||
types.add(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return primary first, then the rest sorted for deterministic output
|
||||
const result: string[] = []
|
||||
if (primaryType && types.has(primaryType)) {
|
||||
result.push(primaryType)
|
||||
types.delete(primaryType)
|
||||
}
|
||||
result.push(...Array.from(types).sort())
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract an enum property value from block content.
|
||||
* Matches patterns like `integrationType: IntegrationType.DeveloperTools`
|
||||
@@ -943,7 +1029,6 @@ function extractEnumPropertyFromContent(content: string, propName: string): stri
|
||||
const ENUM_MAP: Record<string, string> = {
|
||||
AI: 'ai',
|
||||
Analytics: 'analytics',
|
||||
Automation: 'automation',
|
||||
Communication: 'communication',
|
||||
CRM: 'crm',
|
||||
CustomerSupport: 'customer-support',
|
||||
@@ -955,13 +1040,11 @@ function extractEnumPropertyFromContent(content: string, propName: string): stri
|
||||
Email: 'email',
|
||||
FileStorage: 'file-storage',
|
||||
HR: 'hr',
|
||||
Media: 'media',
|
||||
Other: 'other',
|
||||
Productivity: 'productivity',
|
||||
SalesIntelligence: 'sales-intelligence',
|
||||
Sales: 'sales',
|
||||
Search: 'search',
|
||||
Security: 'security',
|
||||
Social: 'social',
|
||||
}
|
||||
return ENUM_MAP[enumKey] || enumKey.toLowerCase()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user