/** * NeutralizationView * * Combined view for the Neutralization feature with two tabs: * - Configuration: Configure names to parse. * - Playground: Upload file, paste text, or neutralize SharePoint files. Resolve placeholders. */ import React, { useState, useEffect, useCallback } from 'react'; import { useCurrentInstance } from '../../../hooks/useCurrentInstance'; import { useToast } from '../../../contexts/ToastContext'; import { useFileContext } from '../../../contexts/FileContext'; import { useConnections, type Connection } from '../../../hooks/useConnections'; import { getNeutralizationConfig, saveNeutralizationConfig, processSharepointFiles, neutralizeText, neutralizeFile, resolveText, type NeutralizationConfig, } from '../../../api/neutralizationApi'; import { Tabs } from '../../../components/UiComponents/Tabs'; import api from '../../../api'; import styles from './NeutralizationViews.module.css'; interface SiteOption { value: string; label: string; siteId: string; siteName: string; webUrl: string; path: string; } interface FolderOption { value: string; label: string; siteId: string; folderName: string; path: string; } // ============================================================================= // CONFIGURATION TAB // ============================================================================= const ConfigTab: React.FC = () => { const { instance } = useCurrentInstance(); const { showSuccess, showError } = useToast(); const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [enabled, setEnabled] = useState(true); const [namesToParse, setNamesToParse] = useState(''); const loadConfig = useCallback(async () => { setLoading(true); setError(null); try { const data = await getNeutralizationConfig(); setConfig(data); setEnabled(data.enabled); setNamesToParse(data.namesToParse || ''); } catch (err: unknown) { const errObj = err as { response?: { data?: { detail?: string | { msg?: string }[] } }; message?: string }; const detail = errObj.response?.data?.detail; const message = (typeof detail === 'string' ? detail : null) || (Array.isArray(detail) ? detail.map((e: { msg?: string }) => e.msg || JSON.stringify(e)).join(', ') : null) || errObj.message || 'Error loading configuration'; setError(message); showError('Error', message); } finally { setLoading(false); } }, [showError]); useEffect(() => { loadConfig(); }, [loadConfig]); const handleSave = async () => { setSaving(true); setError(null); try { const mandateId = instance?.mandateId; const featureInstanceId = instance?.id; if (!mandateId || !featureInstanceId) { throw new Error('Missing mandate or instance context'); } await saveNeutralizationConfig({ mandateId, featureInstanceId, userId: config?.userId || '', enabled, namesToParse, sharepointSourcePath: config?.sharepointSourcePath || '', sharepointTargetPath: config?.sharepointTargetPath || '', }); showSuccess('Saved', 'Configuration saved successfully.'); await loadConfig(); } catch (err: unknown) { const errObj = err as { response?: { data?: { detail?: string } }; message?: string }; const message = (typeof errObj.response?.data?.detail === 'string' ? errObj.response.data.detail : null) || errObj.message || 'Failed to save configuration'; setError(message); showError('Error', message); } finally { setSaving(false); } }; const dismissError = () => setError(null); if (loading) { return
Loading configuration...
; } return (

Neutralization Configuration

Configure data neutralization settings for this instance.

{error && (
{error}
)}