import { useId } from 'react'; import type { ResolvedApp } from '../types'; import { shortToolTitle } from '../toolPresentation'; import { ModalPanel } from './ModalPanel'; interface AppDetailsPanelProps { activeTag: string; app: ResolvedApp; catalogueUrl: string; hidden: boolean; pinned: boolean; contextualUrl: (entryUrl: string, catalogueUrl: string) => string; onCategory: (category: string) => void; onClose: () => void; onTag: (tag: string) => void; } function RequirementSummary({ app }: { app: ResolvedApp }) { if (!app.requirements) return null; const requirements = [ app.requirements.secureContext && 'Secure context', app.requirements.workers && 'Web workers', app.requirements.indexedDb && 'IndexedDB', app.requirements.crossOriginIsolated && 'Cross-origin isolation', ].filter(Boolean); if (requirements.length === 0) return null; return
Needs {requirements.join(' · ')}
; } function PrivacySummary({ app }: { app: ResolvedApp }) { if (!app.privacy) return (External destination · review its privacy terms
); if (app.privacy.label) return{app.privacy.label}
; const processing = { local: 'Local processing', remote: 'Remote processing', mixed: 'Local and remote capabilities', }[app.privacy.processing]; return ({processing} ·{' '} {app.privacy.fileUploads ? 'file/data transmission declared' : 'no file uploads declared'}{' '} · {app.privacy.telemetry ? 'telemetry declared' : 'no telemetry declared'}
); } export function AppDetailsPanel({ activeTag, app, catalogueUrl, hidden, pinned, contextualUrl, onCategory, onClose, onTag, }: AppDetailsPanelProps) { const titleId = useId(); const launchUrl = app.isExternal ? app.entryUrl : contextualUrl(app.entryUrl, catalogueUrl); const target = app.launchModes.includes('navigate') ? undefined : '_blank'; return (Tool information
{app.description}