import React from 'react'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { SettingsControlGroup, SettingsFieldRow, SETTINGS_FIELDS_STACK_CLASS, SETTINGS_SELECT_ROW_TRIGGER_CLASS, SETTINGS_SELECT_SIZE, } from '@/components/sections/shared/SettingsSection'; import { reportSettingsSaveState } from '@/lib/persistence'; import { useI18n } from '@/lib/i18n'; import { useProjectsStore } from '@/stores/useProjectsStore'; import type { LinearAPI, LinearMappingResult } from '@/lib/api/types'; const NONE = '__none__'; const INHERIT = '__inherit__'; export function LinearProjectMapping({ linear, connected, organizationId, }: { linear: LinearAPI; connected: boolean; organizationId?: string | null; }) { const { t } = useI18n(); const projects = useProjectsStore((state) => state.projects); const [mapping, setMapping] = React.useState(null); const [loadFailed, setLoadFailed] = React.useState(false); const [isSaving, setIsSaving] = React.useState(false); const loadMapping = React.useCallback(async () => { if (!connected) { setMapping(null); setLoadFailed(false); return; } try { const next = await linear.mappingGet(); if (next.connected === false) { setMapping(null); setLoadFailed(false); return; } setMapping(next); setLoadFailed(false); } catch (error) { console.error('Failed to load Linear mapping:', error); setLoadFailed(true); } }, [connected, linear]); React.useEffect(() => { void loadMapping(); }, [loadMapping, organizationId]); const saveMapping = React.useCallback(async (next: LinearMappingResult) => { const teamProjectPaths: { [teamId: string]: string } = {}; for (const team of next.teams ?? []) { if (team.projectPath) { teamProjectPaths[team.id] = team.projectPath; } } setIsSaving(true); reportSettingsSaveState('saving'); try { const saved = await linear.mappingSet({ defaultProjectPath: next.defaultProjectPath ?? null, teamProjectPaths, }); if (saved.connected === false) { setMapping(null); reportSettingsSaveState('error'); return; } setMapping(saved); setLoadFailed(false); reportSettingsSaveState('saved'); } catch (error) { console.error('Failed to save Linear mapping:', error); reportSettingsSaveState('error'); } finally { setIsSaving(false); } }, [linear]); if (!connected) { return null; } if (loadFailed && !mapping) { return (

{t('settings.integrations.linear.mapping.loadFailed')}

); } if (!mapping) { return null; } const projectLabel = (path: string) => { const project = projects.find((entry) => entry.path === path); return project?.label?.trim() || path; }; const defaultProjectLabel = (value: string | undefined) => { if (!value || value === NONE) { return t('settings.integrations.linear.mapping.defaultProject.placeholder'); } return projectLabel(value); }; const teamProjectLabel = (value: string | undefined) => { if (!value || value === INHERIT) { return t('settings.integrations.linear.mapping.teams.useDefault'); } return projectLabel(value); }; return (
{projects.length === 0 ? (

{t('settings.integrations.linear.mapping.emptyProjects')}

) : null} {(mapping.teams ?? []).length === 0 ? (

{t('settings.integrations.linear.mapping.emptyTeams')}

) : (
{(mapping.teams ?? []).map((team) => ( ))}
)}
); }