From 239fd328bc4d6ca4f675323baea72c6e2a644d50 Mon Sep 17 00:00:00 2001 From: Ida Dittrich Date: Mon, 12 Jan 2026 09:15:07 +0100 Subject: [PATCH] fix:readded deleted code, fixed build --- src/api/attributesApi.ts | 8 +- src/api/chatbotApi.ts | 16 +- .../FormGeneratorControls.tsx | 4 +- .../FormGeneratorList.module.css | 8 +- .../FormGeneratorList/FormGeneratorList.tsx | 119 +++++++------ src/core/PageManager/PageRenderer.tsx | 160 ++++++++++++++++-- .../PageManager/data/pages/pek/PekMapView.tsx | 2 +- src/core/PageManager/pageInterface.ts | 6 +- src/hooks/useChatbot.ts | 14 +- src/hooks/usePekTables.ts | 4 +- src/styles/pages.module.css | 4 + 11 files changed, 243 insertions(+), 102 deletions(-) diff --git a/src/api/attributesApi.ts b/src/api/attributesApi.ts index 28f9600..4805aa8 100644 --- a/src/api/attributesApi.ts +++ b/src/api/attributesApi.ts @@ -43,10 +43,10 @@ export async function fetchAttributes( request: ApiRequestFunction, entityType: string ): Promise { - const data = await request({ + const data = await request({ url: `/api/attributes/${entityType}`, method: 'get' - }); + }) as any; // Extract attributes from response - check if response.data.attributes exists, otherwise check if response.data is an array let attrs: AttributeDefinition[] = []; @@ -81,10 +81,10 @@ export async function fetchConnectionAttributes(request: ApiRequestFunction): Pr * Endpoint: GET /api/attributes/FileItem */ export async function fetchFileAttributes(request: ApiRequestFunction): Promise { - const data = await request({ + const data = await request({ url: '/api/attributes/FileItem', method: 'get' - }); + }) as AttributeDefinition[] | { attributes: AttributeDefinition[] }; // Handle different response formats if (Array.isArray(data)) { diff --git a/src/api/chatbotApi.ts b/src/api/chatbotApi.ts index 8876e1c..80f3eef 100644 --- a/src/api/chatbotApi.ts +++ b/src/api/chatbotApi.ts @@ -206,12 +206,12 @@ export async function stopChatbotApi( request: ApiRequestFunction, workflowId: string ): Promise { - const data = await request({ + const data = await request({ url: `/api/chatbot/${workflowId}/stop`, method: 'post' }); - return data; + return data as ChatbotWorkflow; } /** @@ -229,11 +229,11 @@ export async function getChatbotThreadsApi( console.log(`[getChatbotThreadsApi] Fetching threads with params:`, requestParams); - const data = await request({ + const data = await request({ url: '/api/chatbot/threads', method: 'get', params: requestParams - }); + }) as any; console.log(`[getChatbotThreadsApi] Full response:`, JSON.stringify(data, null, 2)); console.log(`[getChatbotThreadsApi] Response structure:`, { @@ -265,11 +265,11 @@ export async function getChatbotThreadApi( ): Promise<{ workflow: ChatbotWorkflow; chatData: { items: ChatDataItem[] } }> { console.log(`[getChatbotThreadApi] Fetching thread with workflowId: ${workflowId}`); - const data = await request<{ workflow: ChatbotWorkflow; chatData: { items: ChatDataItem[] } }>({ + const data = await request({ url: '/api/chatbot/threads', method: 'get', params: { workflowId } - }); + }) as { workflow: ChatbotWorkflow; chatData: { items: ChatDataItem[] } }; console.log(`[getChatbotThreadApi] Full response for workflowId ${workflowId}:`, JSON.stringify(data, null, 2)); console.log(`[getChatbotThreadApi] Response structure:`, { @@ -279,7 +279,7 @@ export async function getChatbotThreadApi( hasItems: !!data.chatData?.items, chatDataKeys: data.chatData ? Object.keys(data.chatData) : [], itemsLength: Array.isArray(data.chatData?.items) ? data.chatData.items.length : 'not an array', - chatDataTypes: Array.isArray(data.chatData?.items) ? data.chatData.items.map(item => item?.type).filter(Boolean) : [] + chatDataTypes: Array.isArray(data.chatData?.items) ? data.chatData.items.map((item: ChatDataItem) => item?.type).filter(Boolean) : [] }); return { @@ -301,7 +301,7 @@ export async function deleteChatbotWorkflowApi( workflowId: string ): Promise { try { - await request({ + await request({ url: `/api/chatbot/${workflowId}`, method: 'delete' }); diff --git a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx index 9fcad17..06de77f 100644 --- a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx +++ b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx @@ -162,7 +162,7 @@ export function FormGeneratorControls({ {/* Delete Controls - Show when items are selected */} {selectable && selectedCount > 0 && (
- {selectedCount === 1 && onDeleteSingle && !(selectedCount === _displayData.length && _displayData.length > 0) && ( + {selectedCount === 1 && onDeleteSingle && !(selectedCount === displayData.length && displayData.length > 0) && ( + +
+ ) : ( + + )} + + ) : ( + // Show select all checkbox when no items are selected + { + const selectableIndices = displayData + .map((row, index) => ({ row, index })) + .filter(({ row }) => !isItemSelectable || isItemSelectable(row)) + .map(({ index }) => index); + return selectedItems.size === selectableIndices.length && selectableIndices.length > 0; + })()} + onChange={handleSelectAll} + title={t('formgen.select.all', 'Select all items')} + className={styles.selectAllCheckbox} + /> + )} + + )} {title && (

{title}

)} {title && data.length > 0 && ( ({data.length}) )} - {hasSelectedItems && (onDeleteMultiple || onDelete) && ( -
- {isConfirmingDelete ? ( -
- - -
- ) : ( - - )} -
- )} {headerButton && (
{headerButton}
)} - {sortable && ( + {sortable && displayData.length > 0 && (
{detectedFields.map(field => ( + )} +
+ + ); + } + + return ( +
+ { + // Handle multiple delete + for (const rowToDelete of rowsToDelete) { + await handleDelete(rowToDelete.id); + } + } : undefined} + hookData={enhancedHookData} + getItemDataAttributes={getItemDataAttributes} + searchable={false} + filterable={false} + sortable={false} + pagination={false} + selectable={true} + className={styles.chatHistoryList} + headerButton={startNewChat ? ( + + ) : undefined} + /> +
+ ); + } + default: return null; } diff --git a/src/core/PageManager/data/pages/pek/PekMapView.tsx b/src/core/PageManager/data/pages/pek/PekMapView.tsx index 45663ab..8f1035e 100644 --- a/src/core/PageManager/data/pages/pek/PekMapView.tsx +++ b/src/core/PageManager/data/pages/pek/PekMapView.tsx @@ -20,7 +20,7 @@ const PekMapView: React.FC = () => { const adjacentSet = new Map(); selectedParcels.forEach(parcel => { if (parcel.adjacent_parcels) { - parcel.adjacent_parcels.forEach(adj => { + parcel.adjacent_parcels.forEach((adj: { id: string }) => { if (!adjacentSet.has(adj.id)) { adjacentSet.set(adj.id, adj); } diff --git a/src/core/PageManager/pageInterface.ts b/src/core/PageManager/pageInterface.ts index 3e222b5..f683e6d 100644 --- a/src/core/PageManager/pageInterface.ts +++ b/src/core/PageManager/pageInterface.ts @@ -125,7 +125,7 @@ export interface SettingsConfig { // Content section for paragraphs export interface PageContent { id: string; - type: 'paragraph' | 'heading' | 'list' | 'code' | 'divider' | 'custom' | 'table' | 'inputForm' | 'messages' | 'settings' | 'log' | 'tabs' | 'columns'; + type: 'paragraph' | 'heading' | 'list' | 'code' | 'divider' | 'custom' | 'table' | 'inputForm' | 'messages' | 'settings' | 'log' | 'tabs' | 'columns' | 'chatHistory'; content?: string | LanguageText; // Optional for dividers level?: number; // For headings (1-6) items?: (string | LanguageText)[]; // For lists @@ -150,6 +150,10 @@ export interface PageContent { logConfig?: { emptyMessage?: string | LanguageText; }; + // Chat history-specific properties + chatHistoryConfig?: { + emptyMessage?: string | LanguageText; + }; // Tabs-specific properties tabsConfig?: { tabs: Array<{ diff --git a/src/hooks/useChatbot.ts b/src/hooks/useChatbot.ts index ee4d129..da39ba6 100644 --- a/src/hooks/useChatbot.ts +++ b/src/hooks/useChatbot.ts @@ -69,7 +69,6 @@ export function useChatbot() { processedLogsRef.current.clear(); // Clear processed logs tracking // Reset thinking message refs - const thinkingId = thinkingMessageIdRef.current; thinkingMessageIdRef.current = null; thinkingLogsRef.current = []; @@ -189,13 +188,8 @@ export function useChatbot() { return; } - // Check if this is an assistant message that should clear thinking message - const messageRole = messageData.role?.toLowerCase(); - const isAssistantMessage = messageRole === 'assistant' || messageRole === 'ai' || messageRole === 'system'; - // ALWAYS clear thinking message when ANY message arrives (not just assistant) // The thinking message should disappear when the real message comes - const thinkingId = thinkingMessageIdRef.current; // Check if we've already processed this message const messageId = messageData.id; @@ -367,7 +361,7 @@ export function useChatbot() { }, []); // Handle file upload - const handleFileUpload = useCallback(async (file: File): Promise<{ success: boolean; data?: any }> => { + const handleFileUpload = useCallback(async (file: File): Promise<{ success: boolean; data: any }> => { setUploadError(null); setUploadingFile(true); @@ -417,7 +411,7 @@ export function useChatbot() { console.error('File upload failed:', err); const errorMessage = err.message || 'Failed to upload file'; setUploadError(errorMessage); - return { success: false, error: errorMessage }; + return { success: false, data: null }; } finally { setUploadingFile(false); } @@ -517,9 +511,6 @@ export function useChatbot() { console.log('[handleSubmit] Final requestBody:', JSON.stringify(requestBody, null, 2)); - // Track if workflow was created in this request - let workflowCreated = false; - // Clear thinking message when starting a new request clearThinkingMessage(); processedLogsRef.current.clear(); // Clear processed logs for new request @@ -553,7 +544,6 @@ export function useChatbot() { // New workflow created - select it automatically setWorkflowId(messageData.workflowId); setSelectedThreadId(messageData.workflowId); - workflowCreated = true; } else { // Existing workflow - ensure it's selected setSelectedThreadId(messageData.workflowId); diff --git a/src/hooks/usePekTables.ts b/src/hooks/usePekTables.ts index 9aa49f1..2661ce4 100644 --- a/src/hooks/usePekTables.ts +++ b/src/hooks/usePekTables.ts @@ -527,7 +527,7 @@ export function createProjectsTableHook(): () => GenericDataHook { }, []); // Update project - const handleProjectUpdate = useCallback(async (id: string, updateData: any, originalData?: any): Promise<{ success: boolean }> => { + const handleProjectUpdate = useCallback(async (id: string, updateData: any): Promise<{ success: boolean }> => { try { setEditingProjects(prev => new Set(prev).add(id)); @@ -999,7 +999,7 @@ export function createParzellenTableHook(): () => GenericDataHook { }, []); // Update parzelle - const handleParzelleUpdate = useCallback(async (id: string, updateData: any, originalData?: any): Promise<{ success: boolean }> => { + const handleParzelleUpdate = useCallback(async (id: string, updateData: any): Promise<{ success: boolean }> => { try { setEditingParzellen(prev => new Set(prev).add(id)); diff --git a/src/styles/pages.module.css b/src/styles/pages.module.css index 3f64b9e..8db87c3 100644 --- a/src/styles/pages.module.css +++ b/src/styles/pages.module.css @@ -458,6 +458,10 @@ height: 16px; } +.chatHistoryNewChatButton { + border-radius: 25px !important; +} + .chatHistoryEmpty { display: flex; align-items: center;