mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
feat: Add bulk AI analyzer component to process product data and generate insights.
This commit is contained in:
1 parent
8c02771e46
commit
17498dcc10
4 files changed
+47
-8
No files matched your search
@@ -12,15 +12,18 @@ interface AiInsightBlockProps {
|
||||
}
|
||||
|
||||
export function AiInsightBlock({ row }: AiInsightBlockProps) {
|
||||
const { insights, analyzeProduct } = useAiCopilotStore();
|
||||
const setDraftGamme = useGridStore(state => state.setDraftGamme);
|
||||
const insight = insights[row.codein];
|
||||
const insight = useAiCopilotStore((s) => s.insights[row.codein]);
|
||||
const analyzeProduct = useAiCopilotStore((s) => s.analyzeProduct);
|
||||
const setLoading = useAiCopilotStore((s) => s.setLoading);
|
||||
const setDraftGamme = useGridStore((s) => s.setDraftGamme);
|
||||
|
||||
const status = insight?.status ?? "idle";
|
||||
|
||||
const handleAnalyze = () => {
|
||||
if (status === "loading") return;
|
||||
|
||||
// Vider la recommandation actuelle avant de relancer l'IA
|
||||
// Reset Visuel Immédiat
|
||||
setLoading(row.codein);
|
||||
setDraftGamme(row.codein, "Aucune");
|
||||
|
||||
const regScore = Object.values(row.sales12m || {}).filter(v => v > 0).length;
|
||||
|
||||
@@ -14,6 +14,7 @@ interface AiCopilotState {
|
||||
insights: Record<string, AiInsight>;
|
||||
setInsight: (codein: string, insight: string, isDuplicate?: boolean) => void;
|
||||
setLoading: (codein: string) => void;
|
||||
batchSetLoading: (codeins: string[]) => void;
|
||||
setError: (codein: string, error: string) => void;
|
||||
analyzeProduct: (payload: {
|
||||
codein: string;
|
||||
@@ -56,6 +57,16 @@ export const useAiCopilotStore = create<AiCopilotState>()(
|
||||
}));
|
||||
},
|
||||
|
||||
batchSetLoading: (codeins) => {
|
||||
set((s) => {
|
||||
const nextInsights = { ...s.insights };
|
||||
codeins.forEach(codein => {
|
||||
nextInsights[codein] = { codein, insight: "", status: "loading" };
|
||||
});
|
||||
return { insights: nextInsights };
|
||||
});
|
||||
},
|
||||
|
||||
setError: (codein, error) => {
|
||||
set((s) => ({
|
||||
insights: {
|
||||
|
||||
@@ -12,8 +12,9 @@ export function BulkAiAnalyzer() {
|
||||
const [progress, setProgress] = useState({ current: 0, total: 0, message: "", errors: 0 });
|
||||
const isCancelledRef = useRef(false);
|
||||
|
||||
const batchSetDraftGamme = useGridStore((s) => s.batchSetDraftGamme);
|
||||
const setDraftGamme = useGridStore((s) => s.setDraftGamme);
|
||||
const { setInsight, setLoading, setError } = useAiCopilotStore();
|
||||
const { setInsight, batchSetLoading, setError } = useAiCopilotStore();
|
||||
|
||||
const handleStop = () => {
|
||||
isCancelledRef.current = true;
|
||||
@@ -111,6 +112,14 @@ export function BulkAiAnalyzer() {
|
||||
const totalItems = productPayloads.length;
|
||||
setProgress({ current: 0, total: totalItems, message: "Initialisation...", errors: 0 });
|
||||
|
||||
// Reset global ATOMIQUE et IMMÉDIAT
|
||||
const codeins = productPayloads.map(p => p.codein);
|
||||
batchSetLoading(codeins);
|
||||
|
||||
const gammeChanges: Record<string, GammeCode> = {};
|
||||
codeins.forEach(c => gammeChanges[c] = "Aucune");
|
||||
batchSetDraftGamme(gammeChanges);
|
||||
|
||||
const CONCURRENCY = 3;
|
||||
const remaining = [...productPayloads];
|
||||
|
||||
@@ -120,9 +129,6 @@ export function BulkAiAnalyzer() {
|
||||
const payload = remaining.shift();
|
||||
if (!payload) break;
|
||||
|
||||
setLoading(payload.codein);
|
||||
setDraftGamme(payload.codein, "Aucune");
|
||||
|
||||
try {
|
||||
let res: Response | null = null;
|
||||
for (let i = 0; i < 3; i++) {
|
||||
|
||||
@@ -25,6 +25,7 @@ interface GridState {
|
||||
setDisplayDensity: (density: "compact" | "normal" | "comfortable") => void;
|
||||
setActiveGridQuery: (query: string) => void;
|
||||
restoreSnapshot: (changes: Record<string, GammeCode>) => void;
|
||||
batchSetDraftGamme: (changes: Record<string, GammeCode>) => void;
|
||||
}
|
||||
|
||||
function computeSummary(rows: ProductRow[], drafts: Record<string, GammeCode>): GridSummary {
|
||||
@@ -105,6 +106,24 @@ export const useGridStore = create<GridState>()(
|
||||
restoreSnapshot: (changes) => {
|
||||
set({ draftChanges: changes, summary: computeSummary(get().rows, changes) });
|
||||
},
|
||||
|
||||
batchSetDraftGamme: (newChanges) => {
|
||||
const { rows, draftChanges: oldDrafts } = get();
|
||||
const updatedDrafts = { ...oldDrafts };
|
||||
|
||||
Object.entries(newChanges).forEach(([codein, gamme]) => {
|
||||
const originalRow = rows.find(r => r.codein === codein);
|
||||
const originalGamme = originalRow?.codeGamme;
|
||||
|
||||
if (gamme === originalGamme) {
|
||||
delete updatedDrafts[codein];
|
||||
} else {
|
||||
updatedDrafts[codein] = gamme;
|
||||
}
|
||||
});
|
||||
|
||||
set({ draftChanges: updatedDrafts, summary: computeSummary(rows, updatedDrafts) });
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "collectflow-grid-storage",
|
||||
|
||||
Reference in new issue
Block a user