mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
Compare commits
1 Commits
main
...
fix/ideati
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37a41d3868 |
@@ -11,7 +11,6 @@ import { useIdeationStore } from '@/store/ideation-store';
|
|||||||
import { useAppStore } from '@/store/app-store';
|
import { useAppStore } from '@/store/app-store';
|
||||||
import { useGenerateIdeationSuggestions } from '@/hooks/mutations';
|
import { useGenerateIdeationSuggestions } from '@/hooks/mutations';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { useNavigate } from '@tanstack/react-router';
|
|
||||||
import type { IdeaCategory, IdeationPrompt } from '@automaker/types';
|
import type { IdeaCategory, IdeationPrompt } from '@automaker/types';
|
||||||
|
|
||||||
interface PromptListProps {
|
interface PromptListProps {
|
||||||
@@ -24,10 +23,8 @@ export function PromptList({ category, onBack }: PromptListProps) {
|
|||||||
const generationJobs = useIdeationStore((s) => s.generationJobs);
|
const generationJobs = useIdeationStore((s) => s.generationJobs);
|
||||||
const setMode = useIdeationStore((s) => s.setMode);
|
const setMode = useIdeationStore((s) => s.setMode);
|
||||||
const addGenerationJob = useIdeationStore((s) => s.addGenerationJob);
|
const addGenerationJob = useIdeationStore((s) => s.addGenerationJob);
|
||||||
const updateJobStatus = useIdeationStore((s) => s.updateJobStatus);
|
|
||||||
const [loadingPromptId, setLoadingPromptId] = useState<string | null>(null);
|
const [loadingPromptId, setLoadingPromptId] = useState<string | null>(null);
|
||||||
const [startedPrompts, setStartedPrompts] = useState<Set<string>>(new Set());
|
const [startedPrompts, setStartedPrompts] = useState<Set<string>>(new Set());
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
// React Query mutation
|
// React Query mutation
|
||||||
const generateMutation = useGenerateIdeationSuggestions(currentProject?.path ?? '');
|
const generateMutation = useGenerateIdeationSuggestions(currentProject?.path ?? '');
|
||||||
@@ -72,27 +69,13 @@ export function PromptList({ category, onBack }: PromptListProps) {
|
|||||||
toast.info(`Generating ideas for "${prompt.title}"...`);
|
toast.info(`Generating ideas for "${prompt.title}"...`);
|
||||||
setMode('dashboard');
|
setMode('dashboard');
|
||||||
|
|
||||||
|
// Start mutation - onSuccess/onError are handled at the hook level to ensure
|
||||||
|
// they fire even after this component unmounts (which happens due to setMode above)
|
||||||
generateMutation.mutate(
|
generateMutation.mutate(
|
||||||
{ promptId: prompt.id, category },
|
{ promptId: prompt.id, category, jobId, promptTitle: prompt.title },
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
// Optional: reset local loading state if component is still mounted
|
||||||
updateJobStatus(jobId, 'ready', data.suggestions);
|
onSettled: () => {
|
||||||
toast.success(`Generated ${data.suggestions.length} ideas for "${prompt.title}"`, {
|
|
||||||
duration: 10000,
|
|
||||||
action: {
|
|
||||||
label: 'View Ideas',
|
|
||||||
onClick: () => {
|
|
||||||
setMode('dashboard');
|
|
||||||
navigate({ to: '/ideation' });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
setLoadingPromptId(null);
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
console.error('Failed to generate suggestions:', error);
|
|
||||||
updateJobStatus(jobId, 'error', undefined, error.message);
|
|
||||||
toast.error(error.message);
|
|
||||||
setLoadingPromptId(null);
|
setLoadingPromptId(null);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|||||||
import { getElectronAPI } from '@/lib/electron';
|
import { getElectronAPI } from '@/lib/electron';
|
||||||
import { queryKeys } from '@/lib/query-keys';
|
import { queryKeys } from '@/lib/query-keys';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import type { IdeaCategory, IdeaSuggestion } from '@automaker/types';
|
import type { IdeaCategory, AnalysisSuggestion } from '@automaker/types';
|
||||||
|
import { useIdeationStore } from '@/store/ideation-store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input for generating ideation suggestions
|
* Input for generating ideation suggestions
|
||||||
@@ -16,15 +17,23 @@ import type { IdeaCategory, IdeaSuggestion } from '@automaker/types';
|
|||||||
interface GenerateSuggestionsInput {
|
interface GenerateSuggestionsInput {
|
||||||
promptId: string;
|
promptId: string;
|
||||||
category: IdeaCategory;
|
category: IdeaCategory;
|
||||||
|
/** Job ID for tracking generation progress - used to update job status on completion */
|
||||||
|
jobId: string;
|
||||||
|
/** Prompt title for toast notifications */
|
||||||
|
promptTitle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result from generating suggestions
|
* Result from generating suggestions
|
||||||
*/
|
*/
|
||||||
interface GenerateSuggestionsResult {
|
interface GenerateSuggestionsResult {
|
||||||
suggestions: IdeaSuggestion[];
|
suggestions: AnalysisSuggestion[];
|
||||||
promptId: string;
|
promptId: string;
|
||||||
category: IdeaCategory;
|
category: IdeaCategory;
|
||||||
|
/** Job ID passed through for onSuccess handler */
|
||||||
|
jobId: string;
|
||||||
|
/** Prompt title passed through for toast notifications */
|
||||||
|
promptTitle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +61,7 @@ export function useGenerateIdeationSuggestions(projectPath: string) {
|
|||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (input: GenerateSuggestionsInput): Promise<GenerateSuggestionsResult> => {
|
mutationFn: async (input: GenerateSuggestionsInput): Promise<GenerateSuggestionsResult> => {
|
||||||
const { promptId, category } = input;
|
const { promptId, category, jobId, promptTitle } = input;
|
||||||
|
|
||||||
const api = getElectronAPI();
|
const api = getElectronAPI();
|
||||||
if (!api.ideation?.generateSuggestions) {
|
if (!api.ideation?.generateSuggestions) {
|
||||||
@@ -69,14 +78,33 @@ export function useGenerateIdeationSuggestions(projectPath: string) {
|
|||||||
suggestions: result.suggestions ?? [],
|
suggestions: result.suggestions ?? [],
|
||||||
promptId,
|
promptId,
|
||||||
category,
|
category,
|
||||||
|
jobId,
|
||||||
|
promptTitle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: (data) => {
|
||||||
|
// Update job status in Zustand store - this runs even if the component unmounts
|
||||||
|
// Using getState() to access store directly without hooks (safe in callbacks)
|
||||||
|
const updateJobStatus = useIdeationStore.getState().updateJobStatus;
|
||||||
|
updateJobStatus(data.jobId, 'ready', data.suggestions);
|
||||||
|
|
||||||
|
// Show success toast
|
||||||
|
toast.success(`Generated ${data.suggestions.length} ideas for "${data.promptTitle}"`, {
|
||||||
|
duration: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
// Invalidate ideation ideas cache
|
// Invalidate ideation ideas cache
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: queryKeys.ideation.ideas(projectPath),
|
queryKey: queryKeys.ideation.ideas(projectPath),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// Toast notifications are handled by the component since it has access to prompt title
|
onError: (error, variables) => {
|
||||||
|
// Update job status to error - this runs even if the component unmounts
|
||||||
|
const updateJobStatus = useIdeationStore.getState().updateJobStatus;
|
||||||
|
updateJobStatus(variables.jobId, 'error', undefined, error.message);
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
toast.error(`Failed to generate ideas: ${error.message}`);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user