Add new fields to TasksSerializer and enhance auto_generate_content_task with detailed step tracking
- Updated TasksSerializer to include 'primary_keyword', 'secondary_keywords', 'tags', and 'categories'. - Enhanced auto_generate_content_task to track progress with detailed steps, including initialization, preparation, AI call, parsing, and saving. - Updated progress modal to reflect new phases and improved animation for smoother user experience. - Adjusted routing and configuration for content and drafts pages in the frontend.
This commit is contained in:
@@ -250,21 +250,37 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
|
||||
// Fallback to phase or message if no step found
|
||||
if (!currentStep) {
|
||||
const currentPhase = (meta.phase || '').toLowerCase();
|
||||
const currentPhase = (meta.phase || '').toUpperCase();
|
||||
const currentMessage = (meta.message || '').toLowerCase();
|
||||
|
||||
if (currentPhase.includes('initializ') || currentMessage.includes('initializ') || currentMessage.includes('getting started')) {
|
||||
// Check exact phase match first (backend now sends uppercase phase names)
|
||||
if (currentPhase === 'INIT' || currentPhase.includes('INIT')) {
|
||||
currentStep = 'INIT';
|
||||
} else if (currentPhase.includes('prepar') || currentPhase.includes('prep') || currentMessage.includes('prepar') || currentMessage.includes('loading')) {
|
||||
} else if (currentPhase === 'PREP' || currentPhase.includes('PREP')) {
|
||||
currentStep = 'PREP';
|
||||
} else if (currentPhase.includes('analyzing') || currentPhase.includes('ai_call') || currentMessage.includes('analyzing') || currentMessage.includes('finding related')) {
|
||||
} else if (currentPhase === 'AI_CALL' || currentPhase.includes('AI_CALL') || currentPhase.includes('CALL')) {
|
||||
currentStep = 'AI_CALL';
|
||||
} else if (currentPhase.includes('pars') || currentMessage.includes('pars') || currentMessage.includes('organizing')) {
|
||||
} else if (currentPhase === 'PARSE' || currentPhase.includes('PARSE')) {
|
||||
currentStep = 'PARSE';
|
||||
} else if (currentPhase.includes('sav') || currentPhase.includes('creat') || currentMessage.includes('sav') || currentMessage.includes('creat') || (currentMessage.includes('cluster') && !currentMessage.includes('content'))) {
|
||||
} else if (currentPhase === 'SAVE' || currentPhase.includes('SAVE') || currentPhase.includes('CREAT')) {
|
||||
currentStep = 'SAVE';
|
||||
} else if (currentPhase.includes('done') || currentPhase.includes('complet') || currentMessage.includes('done') || currentMessage.includes('complet')) {
|
||||
} else if (currentPhase === 'DONE' || currentPhase.includes('DONE') || currentPhase.includes('COMPLETE')) {
|
||||
currentStep = 'DONE';
|
||||
} else {
|
||||
// Fallback to message-based detection
|
||||
if (currentMessage.includes('initializ') || currentMessage.includes('getting started')) {
|
||||
currentStep = 'INIT';
|
||||
} else if (currentMessage.includes('prepar') || currentMessage.includes('loading')) {
|
||||
currentStep = 'PREP';
|
||||
} else if (currentMessage.includes('generating') || currentMessage.includes('analyzing') || currentMessage.includes('finding related')) {
|
||||
currentStep = 'AI_CALL';
|
||||
} else if (currentMessage.includes('pars') || currentMessage.includes('organizing') || currentMessage.includes('processing content')) {
|
||||
currentStep = 'PARSE';
|
||||
} else if (currentMessage.includes('sav') || currentMessage.includes('creat') || (currentMessage.includes('cluster') && !currentMessage.includes('content'))) {
|
||||
currentStep = 'SAVE';
|
||||
} else if (currentMessage.includes('done') || currentMessage.includes('complet')) {
|
||||
currentStep = 'DONE';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +289,9 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
// Include title in message for better function type detection
|
||||
const messageWithContext = `${title} ${originalMessage}`;
|
||||
const stepInfo = getStepInfo(currentStep || '', messageWithContext, allSteps);
|
||||
const targetPercentage = stepInfo.percentage;
|
||||
// Use backend percentage if available, otherwise use step-based percentage
|
||||
const backendPercentage = meta.percentage !== undefined ? meta.percentage : null;
|
||||
const targetPercentage = backendPercentage !== null ? backendPercentage : stepInfo.percentage;
|
||||
const friendlyMessage = stepInfo.friendlyMessage;
|
||||
|
||||
// Check if we're transitioning to a new step
|
||||
@@ -286,13 +304,17 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
stepTransitionTimeoutRef.current = null;
|
||||
}
|
||||
|
||||
// Smooth progress animation: increment by 1% every 300ms until reaching target
|
||||
// Smooth progress animation: increment gradually until reaching target
|
||||
// Use smaller increments and faster updates for smoother animation
|
||||
if (targetPercentage > currentDisplayedPercentage) {
|
||||
// Start smooth animation
|
||||
let animatedPercentage = currentDisplayedPercentage;
|
||||
const animateProgress = () => {
|
||||
if (animatedPercentage < targetPercentage) {
|
||||
animatedPercentage = Math.min(animatedPercentage + 1, targetPercentage);
|
||||
// Calculate increment: smaller increments for smoother animation
|
||||
const diff = targetPercentage - animatedPercentage;
|
||||
const increment = diff > 10 ? 2 : 1; // Larger jumps for big differences
|
||||
animatedPercentage = Math.min(animatedPercentage + increment, targetPercentage);
|
||||
displayedPercentageRef.current = animatedPercentage;
|
||||
setProgress({
|
||||
percentage: animatedPercentage,
|
||||
@@ -308,25 +330,26 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
});
|
||||
|
||||
if (animatedPercentage < targetPercentage) {
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateProgress, 300);
|
||||
// Faster updates: 200ms for smoother feel
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateProgress, 200);
|
||||
} else {
|
||||
stepTransitionTimeoutRef.current = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// If it's a new step, add 500ms delay before starting animation
|
||||
// If it's a new step, add small delay before starting animation
|
||||
if (isNewStep && currentStepRef.current !== null) {
|
||||
stepTransitionTimeoutRef.current = setTimeout(() => {
|
||||
currentStepRef.current = currentStep;
|
||||
animateProgress();
|
||||
}, 500);
|
||||
}, 300);
|
||||
} else {
|
||||
// Same step or first step - start animation immediately
|
||||
currentStepRef.current = currentStep;
|
||||
animateProgress();
|
||||
}
|
||||
} else {
|
||||
} else if (targetPercentage !== currentDisplayedPercentage) {
|
||||
// Percentage decreased or same - update immediately (shouldn't happen normally)
|
||||
currentStepRef.current = currentStep;
|
||||
displayedPercentageRef.current = targetPercentage;
|
||||
@@ -342,6 +365,20 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
phase: meta.phase,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// Same percentage - just update message and details if needed
|
||||
currentStepRef.current = currentStep;
|
||||
setProgress(prev => ({
|
||||
...prev,
|
||||
message: friendlyMessage,
|
||||
details: {
|
||||
current: meta.current || 0,
|
||||
total: meta.total || 0,
|
||||
completed: meta.completed || 0,
|
||||
currentItem: meta.current_item,
|
||||
phase: meta.phase,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
// Update step logs if available
|
||||
|
||||
Reference in New Issue
Block a user