import React from 'react'; import { IconType } from 'react-icons'; import { DragDropConfig } from '../../components/UiComponents/DragDropOverlay/DragDropOverlay'; // Generic privilege checker function type export type PrivilegeChecker = () => boolean | Promise; // Form field configuration for create/edit buttons export interface ButtonFormField { key: string; label: string | LanguageText; type: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'readonly' | 'multiselect'; required?: boolean; placeholder?: string | LanguageText; minRows?: number; maxRows?: number; validator?: (value: any) => string | null; defaultValue?: any; options?: string[] | Array<{ value: string | number; label: string }>; // For enum/multiselect fields } // Dropdown configuration for header dropdown buttons export interface DropdownConfig { type: 'dropdown'; items: Array<{ id: string | number; label: string | LanguageText; value: T; metadata?: Record; }>; selectedItemId?: string | number | null; onSelect: (item: { id: string | number; label: string | LanguageText; value: T; metadata?: Record } | null, hookData?: any) => void | Promise; placeholder?: string | LanguageText; emptyMessage?: string | LanguageText; headerText?: string | LanguageText; // Optional: name of property in hookData that provides items, selectedItemId, and onSelect dataSource?: { itemsProperty?: string; // Property name in hookData that contains items array selectedIdProperty?: string; // Property name in hookData that contains selectedItemId onSelectMethod?: string; // Method name in hookData for onSelect callback loadingProperty?: string; // Property name in hookData that contains loading state }; } // Button configuration for header actions export interface PageButton { id: string; label: string | LanguageText; variant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning'; size?: 'sm' | 'md' | 'lg'; icon?: IconType; onClick?: (hookData?: any) => void | Promise; disabled?: boolean | ((hookData?: any) => boolean | { disabled: boolean; message?: string }); // Form configuration for create buttons formConfig?: { fields: ButtonFormField[]; popupTitle?: string | LanguageText; popupSize?: 'small' | 'medium' | 'large'; createOperationName?: string; // Name of the create operation in hookData (e.g., 'handlePromptCreate') successMessage?: string | LanguageText; errorMessage?: string | LanguageText; }; // Dropdown configuration for dropdown selection buttons dropdownConfig?: DropdownConfig; } // Input form configuration export interface InputFormConfig { hookFactory?: () => () => GenericDataHook; // Optional, can use page-level hook from tableConfig if exists placeholder?: string | LanguageText; buttonLabel?: string | LanguageText; stopButtonLabel?: string | LanguageText; // Label for stop button when workflow is running buttonIcon?: IconType; stopButtonIcon?: IconType; // Icon for stop button when workflow is running buttonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning'; stopButtonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning'; // Variant for stop button buttonSize?: 'sm' | 'md' | 'lg'; textFieldSize?: 'sm' | 'md' | 'lg'; } // Settings field configuration export interface SettingsFieldConfig { id: string; type: 'text' | 'select' | 'toggle'; label: string | LanguageText; description?: string | LanguageText; required?: boolean; disabled?: boolean | ((data: any) => boolean); inputType?: 'text' | 'email' | 'tel'; placeholder?: string | LanguageText; options?: Array<{id: string | number; label: string | LanguageText; value: any}>; dataKey: string; // Dot-notation path (e.g., "mandate_general.company_name") onSave?: (value: any, data: any) => Promise | void; } // Settings section configuration export interface SettingsSectionConfig { id: string; title: string | LanguageText; description?: string | LanguageText; icon?: IconType; // Optional icon for section header // Fields will be loaded from backend based on sectionId sectionId: string; // Identifier sent to backend to fetch fields // Save handler per section (uses Button component) onSave?: (sectionId: string, data: any) => Promise; saveButtonLabel?: string | LanguageText; saveButtonVariant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning'; saveButtonSize?: 'sm' | 'md' | 'lg'; // Optional: Static field overrides from config (takes precedence over backend) staticFields?: SettingsFieldConfig[]; // Optional: Conditional rendering - if provided, section only renders if condition returns true renderCondition?: (formData: any) => boolean; // Optional: Alternative content to render when renderCondition returns false renderAlternative?: (formData: any, t: (key: string) => string, resolveLanguageText: (text: string | LanguageText, t: (key: string) => string) => string) => React.ReactNode; } // Settings configuration export interface SettingsConfig { sections: SettingsSectionConfig[]; hookFactory?: () => () => GenericDataHook; // For data fetching and field loading } // Content section for paragraphs export interface PageContent { id: string; type: 'paragraph' | 'heading' | 'list' | 'code' | 'divider' | 'custom' | 'table' | 'inputForm' | 'messages' | 'settings' | 'log'; content?: string | LanguageText; // Optional for dividers level?: number; // For headings (1-6) items?: (string | LanguageText)[]; // For lists language?: string; // For code blocks customComponent?: React.ComponentType; // Table-specific properties tableConfig?: TableContentConfig; // Input form-specific properties inputFormConfig?: InputFormConfig; // Messages-specific properties messagesConfig?: { variant?: 'chat' | 'log'; // Message display variant: 'chat' for bubble UI, 'log' for list/table UI dataSource?: 'messages' | 'logs' | 'both'; // Data source to render: 'messages' (default), 'logs', or 'both' (logs use log variant when merged) showDocuments?: boolean; showMetadata?: boolean; showProgress?: boolean; emptyMessage?: string | LanguageText; }; // Settings-specific properties settingsConfig?: SettingsConfig; // Log-specific properties logConfig?: { emptyMessage?: string | LanguageText; }; } // Generic hook interface for data fetching export interface GenericDataHook { data: any[]; loading: boolean; isRefetching?: boolean; // True when refetching data (keeps existing data visible) error: string | null; refetch?: () => Promise; removeFileOptimistically?: (fileId: string) => void; // For optimistic updates columns?: any[]; // Optional columns configuration // File operations handleUpload?: (file: File) => Promise<{ success: boolean; data: any }>; // For file upload functionality handleFileUpload?: (file: File) => Promise<{ success: boolean; data: any }>; // Alias for handleUpload handleDownload?: (fileId: string, fileName: string) => Promise; // For file download functionality handleDelete?: (fileId: string, onOptimisticDelete?: () => void) => Promise; // For file delete functionality handleFileDelete?: ((fileId: string, onOptimisticDelete?: () => void) => Promise) | ((file: any) => Promise); // Can accept fileId or WorkflowFile handlePreview?: (fileId: string, fileName: string, mimeType?: string) => Promise; // For file preview functionality // File management properties workflowFiles?: any[]; // Files connected to workflow pendingFiles?: any[]; // Files pending attachment allUserFiles?: any[]; // All user files handleFileRemove?: ((fileId: string) => Promise | void) | ((file: any) => Promise | void); // Can accept fileId or WorkflowFile handleFileAttach?: (fileId: string) => Promise; // Attach file to workflow (always returns Promise) handleFileUploadAndAttach?: (file: File) => Promise<{ success: boolean; data: any }>; // Upload and attach file uploadingFile?: boolean; // Loading state for file upload deletingFiles?: Set; // Set of file IDs being deleted previewingFiles?: Set; // Set of file IDs being previewed removingFiles?: Set; // Set of file IDs being removed isFileAttachmentPopupOpen?: boolean; // Whether file attachment popup is open setIsFileAttachmentPopupOpen?: (open: boolean) => void; // Set file attachment popup state // FormGenerator specific handlers onDelete?: (row: any) => Promise; // For single item deletion onDeleteMultiple?: (rows: any[]) => Promise; // For multiple item deletion // Input form operations inputValue?: string; onInputChange?: (value: string) => void; handleSubmit?: () => Promise; // No parameters, uses internal inputValue isSubmitting?: boolean; // Prompt selector properties promptPermission?: { view?: boolean; read?: string; }; promptItems?: Array<{ id: string | number; label: string; value: any }>; selectedPromptId?: string | number | null; onPromptSelect?: (item: { id: string | number; label: string; value: any } | null) => void | Promise; promptsLoading?: boolean; // Workflow mode selector properties workflowModeItems?: Array<{ id: string | number; label: string; value: any }>; selectedWorkflowMode?: string | number | null; onWorkflowModeSelect?: (item: { id: string | number; label: string; value: any } | null) => void | Promise; // Workflow lifecycle state workflowId?: string; workflowStatus?: string; workflowData?: { currentRound?: number; [key: string]: any; }; isRunning?: boolean; currentRound?: number; // Current workflow round latestStats?: any; // Latest workflow statistics // Messages from workflow messages?: any[]; // Logs from workflow logs?: any[]; // Dashboard log tree dashboardTree?: any; // Dashboard log tree structure onToggleOperationExpanded?: (operationId: string) => void; getChildOperations?: (parentId: string | null) => string[]; // Message overlay component MessageOverlayComponent?: () => React.ReactElement; // Settings-specific properties settingsData?: any; // Unified data object for settings fields settingsFields?: Record; // Field definitions per sectionId settingsLoading?: Record; // Loading state per section settingsErrors?: Record; // Error state per section saveSection?: (sectionId: string, data: any) => Promise; // Save handler for a section // Dropdown data source loading property [key: string]: any; // Allow additional properties for dynamic data sources } // Action button configuration export interface ActionButtonConfig { type: 'view' | 'edit' | 'download' | 'delete' | 'copy' | 'connect' | 'play'; onAction?: (row: any) => Promise | void; // Optional for delete buttons since they handle their own logic title?: string | LanguageText; disabled?: (row: any) => boolean | { disabled: boolean; message?: string }; loading?: (row: any) => boolean; // Field mappings for flexible data access idField?: string; // Field name for the unique identifier (default: 'id') nameField?: string; // Field name for display name (default: 'name' or 'file_name') typeField?: string; // Field name for type/mime type (default: 'type' or 'mime_type') contentField?: string; // Field name for content (default: 'content') statusField?: string; // Field name for status (default: 'status') authorityField?: string; // Field name for authority (msft/google) (default: 'authority') // Operation and loading state names operationName?: string; // Name of the operation function in hookData disconnectOperationName?: string; // Name of the disconnect operation function in hookData (for connect button) refreshOperationName?: string; // Name of the refresh operation function in hookData (for connect button) loadingStateName?: string; // Name of the loading state in hookData fetchItemFunctionName?: string; // Name of the function in hookData to fetch a single item by ID (for edit button) // Navigation and behavior (for play button) navigateTo?: string; // Path to navigate to after action (default: 'start/dashboard') mode?: 'workflow' | 'prompt'; // Behavior mode for play button: 'workflow' selects workflow, 'prompt' sets input value (default: 'prompt') } // Table content configuration export interface TableContentConfig { hookFactory: () => () => GenericDataHook; // Hook factory that returns a hook function columns?: any[]; // Column configuration (optional - can be generated dynamically from attributes via hookData.columns) actionButtons?: ActionButtonConfig[]; // Action buttons configuration searchable?: boolean; filterable?: boolean; sortable?: boolean; resizable?: boolean; pagination?: boolean; pageSize?: number; className?: string; } // Language-aware text interface export interface LanguageText { de: string; en: string; fr: string; } // Utility function to resolve language text export const resolveLanguageText = (text: string | LanguageText | undefined, t?: (key: string, fallback?: string) => string): string => { if (!text) return ''; if (typeof text === 'string') { // Always use the translation function for strings (language keys) if (t) { return t(text); } return text; } // For LanguageText objects, we should convert them to language keys // For now, fallback to the first available language return text.de || text.en || text.fr || ''; }; // Generic page data interface export interface GenericPageData { // Core identification id: string; path: string; name: string; description?: string | LanguageText; // Navigation parentPath?: string; // For subpages/subsubpages order?: number; showInSidebar?: boolean; // Visual icon?: IconType; title: string | LanguageText; subtitle?: string | LanguageText; // Header configuration headerButtons?: PageButton[]; // Content sections content?: PageContent[]; // Page behavior persistent?: boolean; preserveState?: boolean; preload?: boolean; moduleEnabled?: boolean; hide?: boolean; // If true, page is completely hidden and not rendered // Subpage support hasSubpages?: boolean; // Lifecycle hooks onActivate?: () => void | Promise; onDeactivate?: () => void | Promise; onLoad?: () => void | Promise; onUnload?: () => void | Promise; // Custom component override (optional) customComponent?: React.ComponentType; // Drag and drop configuration dragDropConfig?: DragDropConfig; } // Page data file structure export interface PageDataFile { page: GenericPageData; subpages?: PageDataFile[]; } // Sidebar item interface for compatibility export interface SidebarItem { id: string; name: string; link: string | undefined; // Allow undefined for parent groups that aren't clickable pages icon?: IconType | React.ComponentType>; // Allow both IconType and SVG components moduleEnabled: boolean; order: number; submenu?: SidebarSubmenuItemData[]; } // Sidebar submenu item data interface export interface SidebarSubmenuItemData { id: string; name: string; link: string; icon?: IconType; } // Page instance for PageManager export interface PageInstance { path: string; component: React.ReactElement; isActive: boolean; shouldPreserve: boolean; pageData: GenericPageData; } // Page manager props export interface PageManagerProps { loadingComponent: React.ComponentType; errorComponent: React.ComponentType; }