ProgressModalUpdates
This commit is contained in:
@@ -37,6 +37,29 @@ class AIEngine:
|
||||
return f"{count} task{'s' if count != 1 else ''}"
|
||||
return f"{count} item{'s' if count != 1 else ''}"
|
||||
|
||||
def _build_validation_message(self, function_name: str, payload: dict, count: int, input_description: str) -> str:
|
||||
"""Build validation message with item names for better UX"""
|
||||
if function_name == 'auto_cluster' and count > 0:
|
||||
try:
|
||||
from igny8_core.modules.planner.models import Keywords
|
||||
ids = payload.get('ids', [])
|
||||
keywords = Keywords.objects.filter(id__in=ids, account=self.account).values_list('keyword', flat=True)[:3]
|
||||
keyword_list = list(keywords)
|
||||
|
||||
if len(keyword_list) > 0:
|
||||
remaining = count - len(keyword_list)
|
||||
if remaining > 0:
|
||||
keywords_text = ', '.join(keyword_list)
|
||||
return f"Validating {keywords_text} and {remaining} more keyword{'s' if remaining != 1 else ''}"
|
||||
else:
|
||||
keywords_text = ', '.join(keyword_list)
|
||||
return f"Validating {keywords_text}"
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to load keyword names for validation message: {e}")
|
||||
|
||||
# Fallback to simple count message
|
||||
return f"Validating {input_description}"
|
||||
|
||||
def _get_prep_message(self, function_name: str, count: int, data: Any) -> str:
|
||||
"""Get user-friendly prep message"""
|
||||
if function_name == 'auto_cluster':
|
||||
@@ -73,6 +96,18 @@ class AIEngine:
|
||||
return "Processing images"
|
||||
return "Processing results"
|
||||
|
||||
def _get_parse_message_with_count(self, function_name: str, count: int) -> str:
|
||||
"""Get user-friendly parse message with count"""
|
||||
if function_name == 'auto_cluster':
|
||||
return f"{count} cluster{'s' if count != 1 else ''} created"
|
||||
elif function_name == 'generate_ideas':
|
||||
return f"{count} idea{'s' if count != 1 else ''} created"
|
||||
elif function_name == 'generate_content':
|
||||
return f"{count} article{'s' if count != 1 else ''} created"
|
||||
elif function_name == 'generate_images':
|
||||
return f"{count} image{'s' if count != 1 else ''} created"
|
||||
return f"{count} item{'s' if count != 1 else ''} processed"
|
||||
|
||||
def _get_save_message(self, function_name: str, count: int) -> str:
|
||||
"""Get user-friendly save message"""
|
||||
if function_name == 'auto_cluster':
|
||||
@@ -117,7 +152,9 @@ class AIEngine:
|
||||
self.console_tracker.error('ValidationError', validated['error'])
|
||||
return self._handle_error(validated['error'], fn)
|
||||
|
||||
validation_message = f"Validating {input_description}"
|
||||
# Build validation message with keyword names for auto_cluster
|
||||
validation_message = self._build_validation_message(function_name, payload, input_count, input_description)
|
||||
|
||||
self.console_tracker.prep("Validation complete")
|
||||
self.step_tracker.add_request_step("INIT", "success", validation_message)
|
||||
self.tracker.update("INIT", 10, validation_message, meta=self.step_tracker.get_meta())
|
||||
@@ -253,6 +290,9 @@ class AIEngine:
|
||||
else:
|
||||
parsed_count = 1
|
||||
|
||||
# Update parse message with count for better UX
|
||||
parse_message = self._get_parse_message_with_count(function_name, parsed_count)
|
||||
|
||||
self.console_tracker.parse(f"Successfully parsed {parsed_count} items from response")
|
||||
self.step_tracker.add_response_step("PARSE", "success", parse_message)
|
||||
self.tracker.update("PARSE", 85, parse_message, meta=self.step_tracker.get_meta())
|
||||
|
||||
@@ -201,15 +201,93 @@ export default function ProgressModal({
|
||||
const steps = getStepsForFunction(functionId, title);
|
||||
const currentPhase = getCurrentPhase(stepLogs, percentage);
|
||||
|
||||
// Format step message with counts and better formatting
|
||||
const formatStepMessage = (stepPhase: string, stepLog: any, defaultLabel: string, allStepLogs: any[], functionId?: string, title?: string): string => {
|
||||
const funcName = (functionId || title || '').toLowerCase();
|
||||
const message = stepLog?.message || defaultLabel;
|
||||
|
||||
// Extract counts from message
|
||||
const extractCount = (pattern: RegExp): string => {
|
||||
const match = message.match(pattern);
|
||||
return match && match[1] ? match[1] : '';
|
||||
};
|
||||
|
||||
if (funcName.includes('cluster')) {
|
||||
if (stepPhase === 'INIT') {
|
||||
// For INIT: Message already includes keyword names from backend (e.g., "Validating keyword1, keyword2, keyword3 and 5 more keywords")
|
||||
// Just return the message as-is since backend formats it
|
||||
return message;
|
||||
} else if (stepPhase === 'PREP') {
|
||||
// For PREP: Show count of keywords being loaded
|
||||
const keywordCount = extractCount(/(\d+)\s+keyword/i);
|
||||
if (keywordCount) {
|
||||
return `Loading ${keywordCount} keyword${keywordCount !== '1' ? 's' : ''} for clustering`;
|
||||
}
|
||||
return message;
|
||||
} else if (stepPhase === 'AI_CALL') {
|
||||
// For AI_CALL: Show count of keywords being sent
|
||||
const keywordCount = extractCount(/(\d+)\s+keyword/i);
|
||||
if (keywordCount) {
|
||||
return `Sending ${keywordCount} keyword${keywordCount !== '1' ? 's' : ''} for clustering`;
|
||||
}
|
||||
return message;
|
||||
} else if (stepPhase === 'PARSE') {
|
||||
// For PARSE: Show count of clusters created
|
||||
const clusterCount = extractCount(/(\d+)\s+cluster/i);
|
||||
if (clusterCount) {
|
||||
return `${clusterCount} cluster${clusterCount !== '1' ? 's' : ''} created`;
|
||||
}
|
||||
// Try to find cluster count in any step log
|
||||
for (const log of allStepLogs) {
|
||||
const count = log.message?.match(/(\d+)\s+cluster/i);
|
||||
if (count && count[1]) {
|
||||
return `${count[1]} cluster${count[1] !== '1' ? 's' : ''} created`;
|
||||
}
|
||||
}
|
||||
return message;
|
||||
} else if (stepPhase === 'SAVE') {
|
||||
// For SAVE: Show count of clusters being saved
|
||||
const clusterCount = extractCount(/(\d+)\s+cluster/i);
|
||||
if (clusterCount) {
|
||||
return `Saving ${clusterCount} cluster${clusterCount !== '1' ? 's' : ''}`;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
} else if (funcName.includes('idea')) {
|
||||
if (stepPhase === 'PARSE') {
|
||||
const ideaCount = extractCount(/(\d+)\s+idea/i);
|
||||
if (ideaCount) {
|
||||
return `${ideaCount} idea${ideaCount !== '1' ? 's' : ''} created`;
|
||||
}
|
||||
}
|
||||
} else if (funcName.includes('content')) {
|
||||
if (stepPhase === 'PARSE') {
|
||||
const articleCount = extractCount(/(\d+)\s+article/i);
|
||||
if (articleCount) {
|
||||
return `${articleCount} article${articleCount !== '1' ? 's' : ''} created`;
|
||||
}
|
||||
}
|
||||
} else if (funcName.includes('image')) {
|
||||
if (stepPhase === 'PARSE') {
|
||||
const imageCount = extractCount(/(\d+)\s+image/i);
|
||||
if (imageCount) {
|
||||
return `${imageCount} image${imageCount !== '1' ? 's' : ''} created`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
// Build checklist items with visual completion state (needed for allStepsVisuallyCompleted)
|
||||
const checklistItems = steps.map((step) => {
|
||||
const actuallyCompleted = isStepCompleted(step.phase, currentPhase, stepLogs);
|
||||
const visuallyCompleted = visuallyCompletedSteps.has(step.phase);
|
||||
const inProgress = isStepInProgress(step.phase, currentPhase) && !visuallyCompleted;
|
||||
|
||||
// Get user-friendly message from step logs if available (includes counts from backend)
|
||||
// Get step log and format message
|
||||
const stepLog = stepLogs.find(log => log.stepName === step.phase);
|
||||
const stepMessage = stepLog?.message || step.label;
|
||||
const stepMessage = formatStepMessage(step.phase, stepLog, step.label, stepLogs, functionId, title);
|
||||
|
||||
return {
|
||||
label: stepMessage,
|
||||
@@ -329,9 +407,12 @@ export default function ProgressModal({
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-1">
|
||||
{title}
|
||||
</h3>
|
||||
{!showSuccess && (
|
||||
{!showSuccess && status !== 'completed' && (
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400">{message}</p>
|
||||
)}
|
||||
{status === 'completed' && !allStepsVisuallyCompleted && (
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400">Processing...</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user