import React from 'react'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Icon } from '@/components/icon/Icon'; import { ModelSelector } from '@/components/sections/agents/ModelSelector'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { SettingsFieldRow, SETTINGS_CUSTOM_TRIGGER_CLASS, SETTINGS_SELECT_ROW_TRIGGER_CLASS, SETTINGS_SELECT_SIZE, } from '@/components/sections/shared/SettingsSection'; import { useConfigStore } from '@/stores/useConfigStore'; import { modelVariantNames } from '@/lib/modelVariants'; import { PROJECT_COLORS, PROJECT_ICONS, PROJECT_COLOR_MAP as COLOR_MAP, ProjectIconImage } from '@/lib/projectMeta'; import { useThemeSystem } from '@/contexts/useThemeSystem'; import { useI18n } from '@/lib/i18n'; import { cn } from '@/lib/utils'; import { PROJECT_SETTINGS_CONTROL_WIDTH, ProjectSettingsSubsection, } from '@/components/sections/projects/ProjectSettingsSubsection'; import type { useProjectIdentityForm } from './useProjectIdentityForm'; type ProjectIdentityFormState = ReturnType; type ProjectIdentityFieldsProps = { form: ProjectIdentityFormState; }; const NO_VARIANT_VALUE = '__default__'; const formatVariantLabel = (variant: string): string => variant.charAt(0).toUpperCase() + variant.slice(1); export const ProjectIdentityFields: React.FC = ({ form }) => { const { t } = useI18n(); const { currentTheme } = useThemeSystem(); const providers = useConfigStore((state) => state.providers); const { name, setName, icon, setIcon, color, setColor, iconBackground, setIconBackground, parsedDefaultModel, defaultVariant, handleDefaultModelChange, handleDefaultVariantChange, isUploadingIcon, isRemovingCustomIcon, isDiscoveringIcon, pendingRemoveImageIcon, setPendingRemoveImageIcon, pendingUploadIconPreviewUrl, setPreviewImageFailed, hasPendingUploadImageIcon, hasCustomIcon, effectiveHasImageIcon, hasRemovableImageIcon, showImagePreview, fileInputRef, handleUploadIcon, handleRemoveImageIcon, handleDiscoverIcon, currentIconImage, project, } = form; const availableVariants = React.useMemo(() => { const { providerId, modelId } = parsedDefaultModel; if (!providerId || !modelId) return []; const model = providers .find((provider) => provider.id === providerId) ?.models.find((entry) => entry.id === modelId); return modelVariantNames(model); }, [parsedDefaultModel, providers]); if (!project) { return null; } const currentColorVar = color ? (COLOR_MAP[color] ?? null) : null; return ( <> setName(event.target.value)} placeholder={t('settings.projects.page.field.projectNamePlaceholder')} className={cn('h-8 rounded-md px-3', PROJECT_SETTINGS_CONTROL_WIDTH)} /> {availableVariants.length > 0 ? ( ) : null}
{PROJECT_COLORS.map((entry) => (
{ const file = event.target.files?.[0] ?? null; void handleUploadIcon(file); event.currentTarget.value = ''; }} />
{PROJECT_ICONS.map((entry) => { const iconName = entry.Icon; return ( ); })}
{effectiveHasImageIcon && showImagePreview && (
{t('settings.projects.page.field.preview')} {hasPendingUploadImageIcon && pendingUploadIconPreviewUrl ? ( setPreviewImageFailed(true)} /> ) : ( setPreviewImageFailed(true)} /> )}
)} {effectiveHasImageIcon && (
setIconBackground(event.target.value)} className="h-7 w-9 cursor-pointer rounded border border-border bg-transparent p-1" aria-label={t('settings.projects.page.field.projectIconBackgroundAria')} /> setIconBackground(event.target.value)} placeholder="#000000" className="h-7 w-[8rem]" />
)}
{!hasCustomIcon && ( <> )} {hasRemovableImageIcon && ( )} {pendingRemoveImageIcon && ( )}
); };