@flowselections/logistiek-engine 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist-lib/_core-safelist.d.ts +2 -0
- package/dist-lib/_core-safelist.d.ts.map +1 -0
- package/dist-lib/_core-safelist.js +15 -0
- package/dist-lib/components/BeladingIndelingCard.d.ts +2 -0
- package/dist-lib/components/BeladingIndelingCard.d.ts.map +1 -0
- package/dist-lib/components/BeladingIndelingCard.js +77 -0
- package/dist-lib/components/BufferDebugCard.d.ts +19 -0
- package/dist-lib/components/BufferDebugCard.d.ts.map +1 -0
- package/dist-lib/components/BufferDebugCard.js +69 -0
- package/dist-lib/components/CapaciteitMeldingenCard.d.ts +2 -0
- package/dist-lib/components/CapaciteitMeldingenCard.d.ts.map +1 -0
- package/dist-lib/components/CapaciteitMeldingenCard.js +40 -0
- package/dist-lib/components/LadingdragersPage.d.ts +2 -0
- package/dist-lib/components/LadingdragersPage.d.ts.map +1 -0
- package/dist-lib/components/LadingdragersPage.js +102 -0
- package/dist-lib/components/LogistiekEngineLogo.d.ts +6 -0
- package/dist-lib/components/LogistiekEngineLogo.d.ts.map +1 -0
- package/dist-lib/components/LogistiekEngineLogo.js +4 -0
- package/dist-lib/components/LogistiekEnginePage.d.ts +2 -0
- package/dist-lib/components/LogistiekEnginePage.d.ts.map +1 -0
- package/dist-lib/components/LogistiekEnginePage.js +53 -0
- package/dist-lib/components/ModulePromptsPage.d.ts +2 -0
- package/dist-lib/components/ModulePromptsPage.d.ts.map +1 -0
- package/dist-lib/components/ModulePromptsPage.js +58 -0
- package/dist-lib/components/RegiePage.d.ts +2 -0
- package/dist-lib/components/RegiePage.d.ts.map +1 -0
- package/dist-lib/components/RegiePage.js +82 -0
- package/dist-lib/components/RuleEnginePage.d.ts +7 -0
- package/dist-lib/components/RuleEnginePage.d.ts.map +1 -0
- package/dist-lib/components/RuleEnginePage.js +114 -0
- package/dist-lib/components/StrategieDialog.d.ts +11 -0
- package/dist-lib/components/StrategieDialog.d.ts.map +1 -0
- package/dist-lib/components/StrategieDialog.js +38 -0
- package/dist-lib/components/VertragingMeldingenCard.d.ts +2 -0
- package/dist-lib/components/VertragingMeldingenCard.d.ts.map +1 -0
- package/dist-lib/components/VertragingMeldingenCard.js +32 -0
- package/dist-lib/components/VoorraadMeldingenCard.d.ts +2 -0
- package/dist-lib/components/VoorraadMeldingenCard.d.ts.map +1 -0
- package/dist-lib/components/VoorraadMeldingenCard.js +26 -0
- package/dist-lib/components/rule-engine/CollapsibleGroup.d.ts +12 -0
- package/dist-lib/components/rule-engine/CollapsibleGroup.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/CollapsibleGroup.js +11 -0
- package/dist-lib/components/rule-engine/ConditionsEditor.d.ts +8 -0
- package/dist-lib/components/rule-engine/ConditionsEditor.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/ConditionsEditor.js +31 -0
- package/dist-lib/components/rule-engine/FieldHelp.d.ts +14 -0
- package/dist-lib/components/rule-engine/FieldHelp.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/FieldHelp.js +18 -0
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +2 -0
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +41 -0
- package/dist-lib/components/rule-engine/ImpactPanel.d.ts +5 -0
- package/dist-lib/components/rule-engine/ImpactPanel.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/ImpactPanel.js +25 -0
- package/dist-lib/components/rule-engine/RuleFieldInput.d.ts +9 -0
- package/dist-lib/components/rule-engine/RuleFieldInput.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/RuleFieldInput.js +80 -0
- package/dist-lib/components/rule-engine/VersionsPanel.d.ts +10 -0
- package/dist-lib/components/rule-engine/VersionsPanel.d.ts.map +1 -0
- package/dist-lib/components/rule-engine/VersionsPanel.js +16 -0
- package/dist-lib/components/settings/LogistiekEngineSettingsCard.d.ts +2 -0
- package/dist-lib/components/settings/LogistiekEngineSettingsCard.d.ts.map +1 -0
- package/dist-lib/components/settings/LogistiekEngineSettingsCard.js +22 -0
- package/dist-lib/hooks/useCapaciteitMeldingen.d.ts +20 -0
- package/dist-lib/hooks/useCapaciteitMeldingen.d.ts.map +1 -0
- package/dist-lib/hooks/useCapaciteitMeldingen.js +46 -0
- package/dist-lib/hooks/useDocumentLayouts.d.ts +13 -0
- package/dist-lib/hooks/useDocumentLayouts.d.ts.map +1 -0
- package/dist-lib/hooks/useDocumentLayouts.js +54 -0
- package/dist-lib/hooks/useLadingdragers.d.ts +16 -0
- package/dist-lib/hooks/useLadingdragers.d.ts.map +1 -0
- package/dist-lib/hooks/useLadingdragers.js +86 -0
- package/dist-lib/hooks/useLogistiekStrategieen.d.ts +29 -0
- package/dist-lib/hooks/useLogistiekStrategieen.d.ts.map +1 -0
- package/dist-lib/hooks/useLogistiekStrategieen.js +111 -0
- package/dist-lib/hooks/useLogistiekTaken.d.ts +89 -0
- package/dist-lib/hooks/useLogistiekTaken.d.ts.map +1 -0
- package/dist-lib/hooks/useLogistiekTaken.js +314 -0
- package/dist-lib/hooks/usePickstations.d.ts +10 -0
- package/dist-lib/hooks/usePickstations.d.ts.map +1 -0
- package/dist-lib/hooks/usePickstations.js +51 -0
- package/dist-lib/hooks/useRecalcJob.d.ts +24 -0
- package/dist-lib/hooks/useRecalcJob.d.ts.map +1 -0
- package/dist-lib/hooks/useRecalcJob.js +83 -0
- package/dist-lib/hooks/useRuleEngine.d.ts +48 -0
- package/dist-lib/hooks/useRuleEngine.d.ts.map +1 -0
- package/dist-lib/hooks/useRuleEngine.js +222 -0
- package/dist-lib/hooks/useVertragingMeldingen.d.ts +29 -0
- package/dist-lib/hooks/useVertragingMeldingen.d.ts.map +1 -0
- package/dist-lib/hooks/useVertragingMeldingen.js +68 -0
- package/dist-lib/hooks/useVoorraadMeldingen.d.ts +30 -0
- package/dist-lib/hooks/useVoorraadMeldingen.d.ts.map +1 -0
- package/dist-lib/hooks/useVoorraadMeldingen.js +70 -0
- package/dist-lib/index.d.ts +36 -0
- package/dist-lib/index.d.ts.map +1 -0
- package/dist-lib/index.js +52 -0
- package/dist-lib/integrations/supabase/auth-attacher.d.ts +2 -0
- package/dist-lib/integrations/supabase/auth-attacher.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/auth-attacher.js +12 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +19781 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/auth-middleware.js +52 -0
- package/dist-lib/integrations/supabase/client.d.ts +19777 -0
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/client.js +13 -0
- package/dist-lib/integrations/supabase/client.server.d.ts +19777 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/client.server.js +30 -0
- package/dist-lib/integrations/supabase/types.d.ts +20355 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/types.js +78 -0
- package/dist-lib/lib/bufferMatching.d.ts +26 -0
- package/dist-lib/lib/bufferMatching.d.ts.map +1 -0
- package/dist-lib/lib/bufferMatching.js +73 -0
- package/dist-lib/lib/bulkLoadCarrierPlanning.server.d.ts +23 -0
- package/dist-lib/lib/bulkLoadCarrierPlanning.server.d.ts.map +1 -0
- package/dist-lib/lib/bulkLoadCarrierPlanning.server.js +126 -0
- package/dist-lib/lib/floridayDocuments.functions.d.ts +59415 -0
- package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -0
- package/dist-lib/lib/floridayDocuments.functions.js +68 -0
- package/dist-lib/lib/floridayDocuments.server.d.ts +51 -0
- package/dist-lib/lib/floridayDocuments.server.d.ts.map +1 -0
- package/dist-lib/lib/floridayDocuments.server.js +109 -0
- package/dist-lib/lib/loadCarrierPlanner.d.ts +71 -0
- package/dist-lib/lib/loadCarrierPlanner.d.ts.map +1 -0
- package/dist-lib/lib/loadCarrierPlanner.js +374 -0
- package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +98984 -0
- package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -0
- package/dist-lib/lib/loadCarrierPlanning.functions.js +106 -0
- package/dist-lib/lib/loadCarrierPlanning.server.d.ts +46 -0
- package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -0
- package/dist-lib/lib/loadCarrierPlanning.server.js +515 -0
- package/dist-lib/lib/loadCarrierTaskSync.server.d.ts +3 -0
- package/dist-lib/lib/loadCarrierTaskSync.server.d.ts.map +1 -0
- package/dist-lib/lib/loadCarrierTaskSync.server.js +56 -0
- package/dist-lib/lib/loadCarrierTypes.d.ts +19 -0
- package/dist-lib/lib/loadCarrierTypes.d.ts.map +1 -0
- package/dist-lib/lib/loadCarrierTypes.js +41 -0
- package/dist-lib/lib/logisticsPlanner.d.ts +56 -0
- package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -0
- package/dist-lib/lib/logisticsPlanner.js +273 -0
- package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +39575 -0
- package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -0
- package/dist-lib/lib/logisticsRecalcJob.functions.js +30 -0
- package/dist-lib/lib/logisticsRecalcJob.server.d.ts +32 -0
- package/dist-lib/lib/logisticsRecalcJob.server.d.ts.map +1 -0
- package/dist-lib/lib/logisticsRecalcJob.server.js +116 -0
- package/dist-lib/lib/logisticsRecalculate.functions.d.ts +19792 -0
- package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -0
- package/dist-lib/lib/logisticsRecalculate.functions.js +35 -0
- package/dist-lib/lib/logisticsTasks.d.ts +23 -0
- package/dist-lib/lib/logisticsTasks.d.ts.map +1 -0
- package/dist-lib/lib/logisticsTasks.js +92 -0
- package/dist-lib/lib/modulePrompts.d.ts +31 -0
- package/dist-lib/lib/modulePrompts.d.ts.map +1 -0
- package/dist-lib/lib/modulePrompts.js +1195 -0
- package/dist-lib/lib/ruleEngineImpact.d.ts +27 -0
- package/dist-lib/lib/ruleEngineImpact.d.ts.map +1 -0
- package/dist-lib/lib/ruleEngineImpact.js +257 -0
- package/dist-lib/lib/ruleEngineSchema.d.ts +69 -0
- package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -0
- package/dist-lib/lib/ruleEngineSchema.js +899 -0
- package/dist-lib/lib/ruleEngineWizard.d.ts +17 -0
- package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -0
- package/dist-lib/lib/ruleEngineWizard.js +204 -0
- package/dist-lib/lib/utils.d.ts +3 -0
- package/dist-lib/lib/utils.d.ts.map +1 -0
- package/dist-lib/lib/utils.js +5 -0
- package/dist-lib/lib/validationSchemas.d.ts +15 -0
- package/dist-lib/lib/validationSchemas.d.ts.map +1 -0
- package/dist-lib/lib/validationSchemas.js +25 -0
- package/dist-lib/styles.css +1 -0
- package/package.json +113 -0
- package/public/logo.png +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { LogisticsModuleKey, LogisticsTaskStatus } from "../lib/logisticsTasks";
|
|
2
|
+
export interface BulkIndelingTotaal {
|
|
3
|
+
buffers: number;
|
|
4
|
+
orders: number;
|
|
5
|
+
beladingen: number;
|
|
6
|
+
overgeslagen: number;
|
|
7
|
+
mislukt: number;
|
|
8
|
+
takenBijgewerkt: number;
|
|
9
|
+
takenAangemaakt: number;
|
|
10
|
+
fouten: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface LogistiekTaak {
|
|
13
|
+
id: string;
|
|
14
|
+
order_ref: string;
|
|
15
|
+
buffer_ref: string | null;
|
|
16
|
+
task_type: string;
|
|
17
|
+
owner_module: LogisticsModuleKey;
|
|
18
|
+
sequence: number;
|
|
19
|
+
planned_start: string | null;
|
|
20
|
+
planned_end: string | null;
|
|
21
|
+
due_at: string | null;
|
|
22
|
+
status: LogisticsTaskStatus;
|
|
23
|
+
shadow: boolean;
|
|
24
|
+
payload: Record<string, unknown>;
|
|
25
|
+
rule_version: number | null;
|
|
26
|
+
priority: number;
|
|
27
|
+
claimed_by: string | null;
|
|
28
|
+
claimed_at: string | null;
|
|
29
|
+
error: string | null;
|
|
30
|
+
created_at: string;
|
|
31
|
+
}
|
|
32
|
+
export interface LogistiekPlanRun {
|
|
33
|
+
id: string;
|
|
34
|
+
order_ref: string;
|
|
35
|
+
source_module: string | null;
|
|
36
|
+
trigger: string;
|
|
37
|
+
rule_version: number | null;
|
|
38
|
+
status: string;
|
|
39
|
+
tasks_created: number;
|
|
40
|
+
tasks_revised: number;
|
|
41
|
+
settings_hash: string | null;
|
|
42
|
+
settings_snapshot: Record<string, unknown> | null;
|
|
43
|
+
warnings: Array<Record<string, unknown>> | null;
|
|
44
|
+
created_at: string;
|
|
45
|
+
}
|
|
46
|
+
export interface LogistiekMelding {
|
|
47
|
+
id: string;
|
|
48
|
+
source_module: string;
|
|
49
|
+
event_type: string;
|
|
50
|
+
order_ref: string;
|
|
51
|
+
status: string;
|
|
52
|
+
shadow: boolean;
|
|
53
|
+
error: string | null;
|
|
54
|
+
plan_run_id: string | null;
|
|
55
|
+
idempotency_key: string | null;
|
|
56
|
+
processed_at: string | null;
|
|
57
|
+
created_at: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function useLogistiekTaken(): {
|
|
60
|
+
taken: LogistiekTaak[];
|
|
61
|
+
planRuns: LogistiekPlanRun[];
|
|
62
|
+
meldingen: LogistiekMelding[];
|
|
63
|
+
loading: boolean;
|
|
64
|
+
laden: () => Promise<void>;
|
|
65
|
+
verwijderOrder: (orderRef: string) => Promise<void>;
|
|
66
|
+
herverwerkMelding: (eventId: string) => Promise<void>;
|
|
67
|
+
maakTestmelding: (strategyId?: string | null) => Promise<void>;
|
|
68
|
+
claimTaak: (taakId: string, worker?: string) => Promise<void>;
|
|
69
|
+
rondTaakAf: (taakId: string, resultaat?: Record<string, unknown>) => Promise<void>;
|
|
70
|
+
meldTaakMislukt: (taakId: string, foutmelding: string) => Promise<void>;
|
|
71
|
+
annuleerOrder: (orderRef: string, reden?: string) => Promise<void>;
|
|
72
|
+
zetPrioriteit: (orderRef: string, prioriteit: number) => Promise<void>;
|
|
73
|
+
splitsOrder: (orderRef: string, deelorders: Array<Record<string, unknown>>) => Promise<void>;
|
|
74
|
+
herindelenBuffers: (strategyId?: string | null) => Promise<{
|
|
75
|
+
checked?: number;
|
|
76
|
+
updated?: number;
|
|
77
|
+
} | null>;
|
|
78
|
+
herindelenOrders: (dagen?: number) => Promise<{
|
|
79
|
+
checked?: number;
|
|
80
|
+
updated?: number;
|
|
81
|
+
durationMs?: number;
|
|
82
|
+
} | null>;
|
|
83
|
+
simuleerBuffers: (orders: Array<Record<string, unknown>>, strategyId?: string | null) => Promise<{
|
|
84
|
+
orders: Array<Record<string, any>>;
|
|
85
|
+
groups: Array<Record<string, any>>;
|
|
86
|
+
} | null>;
|
|
87
|
+
deelAllesIn: (strategyId?: string | null, onVoortgang?: (tekst: string) => void) => Promise<BulkIndelingTotaal | null>;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=useLogistiekTaken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLogistiekTaken.d.ts","sourceRoot":"","sources":["../../src/hooks/useLogistiekTaken.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/hooks/useLogistiekTaken.ts — regieoverzicht: taken en planruns lezen
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { supabase, toast } from "@flowselections/core";
|
|
6
|
+
import { ensureLogisticsTasks, planAllLoadCarriers } from "../lib/loadCarrierPlanning.functions";
|
|
7
|
+
const db = () => supabase;
|
|
8
|
+
export function useLogistiekTaken() {
|
|
9
|
+
const [taken, setTaken] = useState([]);
|
|
10
|
+
const [planRuns, setPlanRuns] = useState([]);
|
|
11
|
+
const [meldingen, setMeldingen] = useState([]);
|
|
12
|
+
const [loading, setLoading] = useState(true);
|
|
13
|
+
const laden = useCallback(async () => {
|
|
14
|
+
setLoading(true);
|
|
15
|
+
try {
|
|
16
|
+
const [takenRes, runsRes, eventsRes] = await Promise.all([
|
|
17
|
+
db()
|
|
18
|
+
.from("logistics_tasks")
|
|
19
|
+
.select("*")
|
|
20
|
+
.order("order_ref", { ascending: true })
|
|
21
|
+
.order("sequence", { ascending: true })
|
|
22
|
+
.limit(500),
|
|
23
|
+
db().from("logistics_plan_runs").select("*").order("created_at", { ascending: false }).limit(50),
|
|
24
|
+
db().from("logistics_events").select("*").order("created_at", { ascending: false }).limit(50),
|
|
25
|
+
]);
|
|
26
|
+
if (takenRes.error)
|
|
27
|
+
throw takenRes.error;
|
|
28
|
+
if (runsRes.error)
|
|
29
|
+
throw runsRes.error;
|
|
30
|
+
if (eventsRes.error)
|
|
31
|
+
throw eventsRes.error;
|
|
32
|
+
setTaken(Array.isArray(takenRes.data) ? takenRes.data : []);
|
|
33
|
+
setPlanRuns(Array.isArray(runsRes.data) ? runsRes.data : []);
|
|
34
|
+
setMeldingen(Array.isArray(eventsRes.data) ? eventsRes.data : []);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
toast.error("Taken laden mislukt", { description: err?.message });
|
|
38
|
+
setTaken([]);
|
|
39
|
+
setPlanRuns([]);
|
|
40
|
+
setMeldingen([]);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
setLoading(false);
|
|
44
|
+
}
|
|
45
|
+
}, []);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
void laden();
|
|
48
|
+
}, [laden]);
|
|
49
|
+
const verwijderOrder = useCallback(async (orderRef) => {
|
|
50
|
+
const { error } = await db().from("logistics_tasks").delete().eq("order_ref", orderRef);
|
|
51
|
+
if (error) {
|
|
52
|
+
toast.error("Verwijderen mislukt", { description: error.message });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
toast.success(`Taken van ${orderRef} verwijderd`);
|
|
56
|
+
void laden();
|
|
57
|
+
}, [laden]);
|
|
58
|
+
/** Een mislukte melding opnieuw door de planner halen. */
|
|
59
|
+
const herverwerkMelding = useCallback(async (eventId) => {
|
|
60
|
+
const { error } = await db().rpc("process_logistics_event", { p_event_id: eventId });
|
|
61
|
+
if (error) {
|
|
62
|
+
toast.error("Opnieuw verwerken mislukt", { description: error.message });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
toast.success("Melding opnieuw verwerkt");
|
|
66
|
+
void laden();
|
|
67
|
+
}, [laden]);
|
|
68
|
+
/** Voorbeeldmelding wegschrijven om de hele keten te testen. */
|
|
69
|
+
const maakTestmelding = useCallback(async (strategyId) => {
|
|
70
|
+
const nu = Date.now();
|
|
71
|
+
const orderRef = `TEST-${new Date(nu).toISOString().slice(11, 19).replace(/:/g, "")}`;
|
|
72
|
+
const { data, error } = await db().rpc("logistics_emit_event", {
|
|
73
|
+
p_source_module: "verkoop",
|
|
74
|
+
p_event_type: "order.received",
|
|
75
|
+
p_order_ref: orderRef,
|
|
76
|
+
p_payload: {
|
|
77
|
+
checkinAt: new Date(nu + 4 * 3600000).toISOString(),
|
|
78
|
+
pickupAt: new Date(nu + 6 * 3600000).toISOString(),
|
|
79
|
+
customerRef: "TEST-KLANT",
|
|
80
|
+
loadCarriers: [
|
|
81
|
+
{ type: "trolley", count: 3 },
|
|
82
|
+
{ type: "euro_pallet", count: 10 },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
p_strategy_id: strategyId ?? null,
|
|
86
|
+
p_shadow: true,
|
|
87
|
+
p_idempotency_key: `test:${orderRef}`,
|
|
88
|
+
});
|
|
89
|
+
if (error) {
|
|
90
|
+
toast.error("Testmelding mislukt", { description: error.message });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (data?.duplicate) {
|
|
94
|
+
toast.info(`Melding ${orderRef} bestond al (dubbel voorkomen)`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
toast.success(`Testmelding ${orderRef} aangemaakt`);
|
|
98
|
+
}
|
|
99
|
+
void laden();
|
|
100
|
+
}, [laden]);
|
|
101
|
+
/** Taak claimen zodat niemand anders hem oppakt. */
|
|
102
|
+
const claimTaak = useCallback(async (taakId, worker) => {
|
|
103
|
+
const { data, error } = await db().rpc("logistics_claim_task", {
|
|
104
|
+
p_task_id: taakId,
|
|
105
|
+
p_worker: worker ?? "regieoverzicht",
|
|
106
|
+
});
|
|
107
|
+
if (error) {
|
|
108
|
+
toast.error("Claimen mislukt", { description: error.message });
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!data) {
|
|
112
|
+
toast.error("Taak is al geclaimd of niet meer beschikbaar");
|
|
113
|
+
void laden();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
toast.success("Taak geclaimd");
|
|
117
|
+
void laden();
|
|
118
|
+
}, [laden]);
|
|
119
|
+
/** Taak afronden. */
|
|
120
|
+
const rondTaakAf = useCallback(async (taakId, resultaat = {}) => {
|
|
121
|
+
const { data, error } = await db().rpc("logistics_complete_task", {
|
|
122
|
+
p_task_id: taakId,
|
|
123
|
+
p_result: resultaat,
|
|
124
|
+
});
|
|
125
|
+
if (error) {
|
|
126
|
+
toast.error("Afronden mislukt", { description: error.message });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!data) {
|
|
130
|
+
toast.error("Taak kon niet worden afgerond");
|
|
131
|
+
void laden();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
toast.success("Taak afgerond");
|
|
135
|
+
void laden();
|
|
136
|
+
}, [laden]);
|
|
137
|
+
/** Taak als mislukt melden zodat hij opnieuw opgepakt kan worden. */
|
|
138
|
+
const meldTaakMislukt = useCallback(async (taakId, foutmelding) => {
|
|
139
|
+
const { error } = await db().rpc("logistics_fail_task", {
|
|
140
|
+
p_task_id: taakId,
|
|
141
|
+
p_error: foutmelding,
|
|
142
|
+
});
|
|
143
|
+
if (error) {
|
|
144
|
+
toast.error("Melden mislukt", { description: error.message });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
toast.success("Taak op mislukt gezet");
|
|
148
|
+
void laden();
|
|
149
|
+
}, [laden]);
|
|
150
|
+
/** Alle openstaande taken van een order annuleren. */
|
|
151
|
+
const annuleerOrder = useCallback(async (orderRef, reden = "Handmatig geannuleerd vanuit regieoverzicht") => {
|
|
152
|
+
const { data, error } = await db().rpc("logistics_cancel_order", {
|
|
153
|
+
p_order_ref: orderRef,
|
|
154
|
+
p_reason: reden,
|
|
155
|
+
});
|
|
156
|
+
if (error) {
|
|
157
|
+
toast.error("Annuleren mislukt", { description: error.message });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
toast.success(`${Number(data ?? 0)} taken van ${orderRef} geannuleerd`);
|
|
161
|
+
void laden();
|
|
162
|
+
}, [laden]);
|
|
163
|
+
/** Prioriteit van een order wijzigen (hoger = eerder oppakken). */
|
|
164
|
+
const zetPrioriteit = useCallback(async (orderRef, prioriteit) => {
|
|
165
|
+
const { error } = await db().rpc("logistics_set_order_priority", {
|
|
166
|
+
p_order_ref: orderRef,
|
|
167
|
+
p_priority: prioriteit,
|
|
168
|
+
});
|
|
169
|
+
if (error) {
|
|
170
|
+
toast.error("Prioriteit wijzigen mislukt", { description: error.message });
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
toast.success(prioriteit > 0 ? `${orderRef} op spoed gezet` : `${orderRef} terug op normaal`);
|
|
174
|
+
void laden();
|
|
175
|
+
}, [laden]);
|
|
176
|
+
/** Een order splitsen in deelorders; de Engine plant elke deelorder opnieuw. */
|
|
177
|
+
const splitsOrder = useCallback(async (orderRef, deelorders) => {
|
|
178
|
+
const kinderen = Array.isArray(deelorders) ? deelorders : [];
|
|
179
|
+
if (kinderen.length === 0) {
|
|
180
|
+
toast.error("Geef minstens één deelorder op");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const { error } = await db().rpc("logistics_emit_event", {
|
|
184
|
+
p_source_module: "verkoop",
|
|
185
|
+
p_event_type: "order.split",
|
|
186
|
+
p_order_ref: orderRef,
|
|
187
|
+
p_payload: { children: kinderen },
|
|
188
|
+
p_shadow: false,
|
|
189
|
+
p_idempotency_key: `split:${orderRef}:${Date.now()}`,
|
|
190
|
+
});
|
|
191
|
+
if (error) {
|
|
192
|
+
toast.error("Splitsen mislukt", { description: error.message });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
toast.success(`${orderRef} gesplitst in ${kinderen.length} deelorders`);
|
|
196
|
+
void laden();
|
|
197
|
+
}, [laden]);
|
|
198
|
+
/** Alle openstaande orders opnieuw indelen volgens de huidige combineerregels. */
|
|
199
|
+
const herindelenBuffers = useCallback(async (strategyId) => {
|
|
200
|
+
const { data, error } = await db().rpc("logistics_rebuffer_open_orders", {
|
|
201
|
+
p_strategy_id: strategyId ?? null,
|
|
202
|
+
});
|
|
203
|
+
if (error) {
|
|
204
|
+
toast.error("Opnieuw indelen mislukt", { description: error.message });
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const result = (data ?? {});
|
|
208
|
+
toast.success(`${Number(result.updated ?? 0)} van ${Number(result.checked ?? 0)} orders opnieuw ingedeeld`);
|
|
209
|
+
void laden();
|
|
210
|
+
return result;
|
|
211
|
+
}, [laden]);
|
|
212
|
+
/** Alle recente orders direct opnieuw in buffers indelen (set-based, snel). */
|
|
213
|
+
const herindelenOrders = useCallback(async (dagen = 30) => {
|
|
214
|
+
const { data, error } = await db().rpc("logistics_rebuffer_orders", { p_days: dagen });
|
|
215
|
+
if (error) {
|
|
216
|
+
toast.error("Orders opnieuw indelen mislukt", { description: error.message });
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
const result = (data ?? {});
|
|
220
|
+
toast.success(`${Number(result.updated ?? 0)} van ${Number(result.checked ?? 0)} orders verplaatst in ${Number(result.durationMs ?? 0)} ms`);
|
|
221
|
+
void laden();
|
|
222
|
+
return result;
|
|
223
|
+
}, [laden]);
|
|
224
|
+
/** Simulatie: laat zien hoe orders gegroepeerd zouden worden en waarom. */
|
|
225
|
+
const simuleerBuffers = useCallback(async (orders, strategyId) => {
|
|
226
|
+
const { data, error } = await db().rpc("logistics_buffer_simulate", {
|
|
227
|
+
p_orders: Array.isArray(orders) ? orders : [],
|
|
228
|
+
p_strategy_id: strategyId ?? null,
|
|
229
|
+
});
|
|
230
|
+
if (error) {
|
|
231
|
+
toast.error("Simulatie mislukt", { description: error.message });
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return (data ?? { orders: [], groups: [] });
|
|
235
|
+
}, []);
|
|
236
|
+
/** Alle orders in één keer indelen (batchgewijs, met voortgang). */
|
|
237
|
+
const deelAllesIn = useCallback(async (strategyId, onVoortgang) => {
|
|
238
|
+
const totaal = {
|
|
239
|
+
buffers: 0,
|
|
240
|
+
orders: 0,
|
|
241
|
+
beladingen: 0,
|
|
242
|
+
overgeslagen: 0,
|
|
243
|
+
mislukt: 0,
|
|
244
|
+
takenBijgewerkt: 0,
|
|
245
|
+
takenAangemaakt: 0,
|
|
246
|
+
fouten: [],
|
|
247
|
+
};
|
|
248
|
+
try {
|
|
249
|
+
onVoortgang?.("Takenketens aanmaken voor orders zonder taken…");
|
|
250
|
+
const taken = await ensureLogisticsTasks({ data: { strategyId: strategyId ?? null } });
|
|
251
|
+
totaal.takenAangemaakt = Number(taken?.created ?? 0);
|
|
252
|
+
for (const f of taken?.errors ?? [])
|
|
253
|
+
if (totaal.fouten.length < 5)
|
|
254
|
+
totaal.fouten.push(f);
|
|
255
|
+
for (const phase of ["buffers", "orders"]) {
|
|
256
|
+
let cursor = null;
|
|
257
|
+
let ronde = 0;
|
|
258
|
+
// Harde bovengrens zodat we nooit oneindig doorlopen.
|
|
259
|
+
while (ronde < 200) {
|
|
260
|
+
ronde++;
|
|
261
|
+
const batch = await planAllLoadCarriers({ data: { phase, cursor, limit: 20 } });
|
|
262
|
+
if (phase === "buffers")
|
|
263
|
+
totaal.buffers += Number(batch?.processed ?? 0);
|
|
264
|
+
else
|
|
265
|
+
totaal.orders += Number(batch?.processed ?? 0);
|
|
266
|
+
totaal.beladingen += Number(batch?.cartsCreated ?? 0);
|
|
267
|
+
totaal.overgeslagen += Number(batch?.skippedLocked ?? 0);
|
|
268
|
+
totaal.mislukt += Number(batch?.failed ?? 0);
|
|
269
|
+
totaal.takenBijgewerkt += Number(batch?.tasksUpdated ?? 0);
|
|
270
|
+
for (const f of batch?.errors ?? [])
|
|
271
|
+
if (totaal.fouten.length < 5)
|
|
272
|
+
totaal.fouten.push(f);
|
|
273
|
+
onVoortgang?.(phase === "buffers"
|
|
274
|
+
? `${totaal.buffers} buffers ingedeeld, ${totaal.beladingen} beladingen…`
|
|
275
|
+
: `${totaal.orders} losse orders ingedeeld…`);
|
|
276
|
+
cursor = (batch?.nextCursor ?? null);
|
|
277
|
+
if (batch?.done || !cursor)
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
toast.success(`${totaal.beladingen} beladingen gemaakt voor ${totaal.buffers + totaal.orders} groepen`, {
|
|
282
|
+
description: `${totaal.takenBijgewerkt} taken bijgewerkt${totaal.takenAangemaakt > 0 ? `, ${totaal.takenAangemaakt} nieuwe takenketens` : ""}${totaal.overgeslagen > 0 ? `, ${totaal.overgeslagen} vergrendeld overgeslagen` : ""}`,
|
|
283
|
+
});
|
|
284
|
+
void laden();
|
|
285
|
+
return totaal;
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
toast.error("Indelen mislukt", {
|
|
289
|
+
description: err instanceof Error ? err.message : String(err),
|
|
290
|
+
});
|
|
291
|
+
return totaal;
|
|
292
|
+
}
|
|
293
|
+
}, [laden]);
|
|
294
|
+
return {
|
|
295
|
+
taken,
|
|
296
|
+
planRuns,
|
|
297
|
+
meldingen,
|
|
298
|
+
loading,
|
|
299
|
+
laden,
|
|
300
|
+
verwijderOrder,
|
|
301
|
+
herverwerkMelding,
|
|
302
|
+
maakTestmelding,
|
|
303
|
+
claimTaak,
|
|
304
|
+
rondTaakAf,
|
|
305
|
+
meldTaakMislukt,
|
|
306
|
+
annuleerOrder,
|
|
307
|
+
zetPrioriteit,
|
|
308
|
+
splitsOrder,
|
|
309
|
+
herindelenBuffers,
|
|
310
|
+
herindelenOrders,
|
|
311
|
+
simuleerBuffers,
|
|
312
|
+
deelAllesIn,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePickstations.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickstations.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AA0BD,wBAAgB,eAAe;;;;EAuB9B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/hooks/usePickstations.ts — pickstations en stationtypes uit de
|
|
3
|
+
// bestaande Pickstations-module, voor de documentinstellingen.
|
|
4
|
+
// ============================================================================
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import { supabase } from "@flowselections/core";
|
|
7
|
+
const db = () => supabase;
|
|
8
|
+
let cache = null;
|
|
9
|
+
let inflight = null;
|
|
10
|
+
async function load() {
|
|
11
|
+
if (cache)
|
|
12
|
+
return cache;
|
|
13
|
+
if (!inflight) {
|
|
14
|
+
inflight = (async () => {
|
|
15
|
+
const [stations, types] = await Promise.all([
|
|
16
|
+
db().from("pick_stations").select("id, name, active").order("sort_order", { ascending: true }),
|
|
17
|
+
db().from("pick_station_types").select("id, name, active").order("sort_order", { ascending: true }),
|
|
18
|
+
]);
|
|
19
|
+
const map = (rows) => (Array.isArray(rows) ? rows : [])
|
|
20
|
+
.filter((r) => r && r.active !== false)
|
|
21
|
+
.map((r) => ({ id: String(r.id), name: String(r.name ?? r.id) }));
|
|
22
|
+
cache = { stations: map(stations?.data), types: map(types?.data) };
|
|
23
|
+
return cache;
|
|
24
|
+
})();
|
|
25
|
+
}
|
|
26
|
+
return inflight;
|
|
27
|
+
}
|
|
28
|
+
export function usePickstations() {
|
|
29
|
+
const [stations, setStations] = useState(cache?.stations ?? []);
|
|
30
|
+
const [types, setTypes] = useState(cache?.types ?? []);
|
|
31
|
+
const [loading, setLoading] = useState(!cache);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
let active = true;
|
|
34
|
+
load()
|
|
35
|
+
.then((result) => {
|
|
36
|
+
if (!active)
|
|
37
|
+
return;
|
|
38
|
+
setStations(result.stations);
|
|
39
|
+
setTypes(result.types);
|
|
40
|
+
})
|
|
41
|
+
.catch(() => undefined)
|
|
42
|
+
.finally(() => {
|
|
43
|
+
if (active)
|
|
44
|
+
setLoading(false);
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
active = false;
|
|
48
|
+
};
|
|
49
|
+
}, []);
|
|
50
|
+
return { stations, types, loading };
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface RecalcJobRow {
|
|
2
|
+
id: string;
|
|
3
|
+
status: "running" | "done" | "error";
|
|
4
|
+
phase: "buffers" | "orders" | "finalize";
|
|
5
|
+
processed: number;
|
|
6
|
+
carts_created: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
errors: string[];
|
|
9
|
+
steps: Array<{
|
|
10
|
+
step: string;
|
|
11
|
+
ok: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
}>;
|
|
14
|
+
finished_at: string | null;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function phaseLabel(phase?: string | null): string;
|
|
18
|
+
export declare function useRecalcJob(): {
|
|
19
|
+
job: RecalcJobRow | null;
|
|
20
|
+
starting: boolean;
|
|
21
|
+
startRecalculation: (strategyId: string | null) => Promise<void>;
|
|
22
|
+
refresh: () => Promise<RecalcJobRow | null>;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=useRecalcJob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRecalcJob.d.ts","sourceRoot":"","sources":["../../src/hooks/useRecalcJob.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,UAE/C;AAED,wBAAgB,YAAY;;;qCA4DL,MAAM,GAAG,IAAI;;EAanC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/hooks/useRecalcJob.ts — voortgang van de herberekening op de achtergrond
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
|
+
import { useServerFn } from "@tanstack/react-start";
|
|
6
|
+
import { supabase } from "../integrations/supabase/client";
|
|
7
|
+
import { startRecalcJob, tickRecalcJob } from "../lib/logisticsRecalcJob.functions";
|
|
8
|
+
const PHASE_LABEL = {
|
|
9
|
+
buffers: "Orderbuffers indelen",
|
|
10
|
+
orders: "Losse orders indelen",
|
|
11
|
+
finalize: "Planning herberekenen",
|
|
12
|
+
};
|
|
13
|
+
export function phaseLabel(phase) {
|
|
14
|
+
return (phase && PHASE_LABEL[phase]) || "Bezig";
|
|
15
|
+
}
|
|
16
|
+
export function useRecalcJob() {
|
|
17
|
+
const [job, setJob] = useState(null);
|
|
18
|
+
const [starting, setStarting] = useState(false);
|
|
19
|
+
const start = useServerFn(startRecalcJob);
|
|
20
|
+
const tick = useServerFn(tickRecalcJob);
|
|
21
|
+
const ticking = useRef(false);
|
|
22
|
+
const load = useCallback(async () => {
|
|
23
|
+
const { data } = await supabase
|
|
24
|
+
.from("logistics_recalc_jobs")
|
|
25
|
+
.select("*")
|
|
26
|
+
.order("created_at", { ascending: false })
|
|
27
|
+
.limit(1);
|
|
28
|
+
const row = Array.isArray(data) && data.length > 0 ? data[0] : null;
|
|
29
|
+
setJob(row);
|
|
30
|
+
return row;
|
|
31
|
+
}, []);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
void load();
|
|
34
|
+
const channel = supabase
|
|
35
|
+
.channel("logistics-recalc-jobs")
|
|
36
|
+
.on("postgres_changes", { event: "*", schema: "public", table: "logistics_recalc_jobs" }, () => void load())
|
|
37
|
+
.subscribe();
|
|
38
|
+
const timer = setInterval(() => void load(), 5000);
|
|
39
|
+
return () => {
|
|
40
|
+
clearInterval(timer);
|
|
41
|
+
void supabase.removeChannel(channel);
|
|
42
|
+
};
|
|
43
|
+
}, [load]);
|
|
44
|
+
// Zolang deze pagina open staat duwen we de job zelf door, zodat het snel
|
|
45
|
+
// gaat. Sluit de gebruiker de pagina, dan neemt de cron-taak het over.
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (job?.status !== "running" || ticking.current)
|
|
48
|
+
return;
|
|
49
|
+
let cancelled = false;
|
|
50
|
+
ticking.current = true;
|
|
51
|
+
(async () => {
|
|
52
|
+
try {
|
|
53
|
+
for (let guard = 0; guard < 500 && !cancelled; guard++) {
|
|
54
|
+
const res = await tick({});
|
|
55
|
+
if (!res || res.status !== "running")
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* de cron-taak pakt het verder op */
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
ticking.current = false;
|
|
64
|
+
if (!cancelled)
|
|
65
|
+
void load();
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
return () => {
|
|
69
|
+
cancelled = true;
|
|
70
|
+
};
|
|
71
|
+
}, [job?.status, tick, load]);
|
|
72
|
+
const startRecalculation = useCallback(async (strategyId) => {
|
|
73
|
+
setStarting(true);
|
|
74
|
+
try {
|
|
75
|
+
await start({ data: { strategyId } });
|
|
76
|
+
await load();
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
setStarting(false);
|
|
80
|
+
}
|
|
81
|
+
}, [start, load]);
|
|
82
|
+
return { job, starting, startRecalculation, refresh: load };
|
|
83
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type RuleEngineSettings } from "../lib/ruleEngineSchema";
|
|
2
|
+
export interface RuleConfig {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string | null;
|
|
6
|
+
status: string;
|
|
7
|
+
is_active: boolean;
|
|
8
|
+
current_version: number;
|
|
9
|
+
settings: RuleEngineSettings;
|
|
10
|
+
updated_at: string;
|
|
11
|
+
}
|
|
12
|
+
export interface RuleVersion {
|
|
13
|
+
id: string;
|
|
14
|
+
config_id: string;
|
|
15
|
+
version: number;
|
|
16
|
+
label: string | null;
|
|
17
|
+
status: string;
|
|
18
|
+
note: string | null;
|
|
19
|
+
settings: RuleEngineSettings;
|
|
20
|
+
created_at: string;
|
|
21
|
+
}
|
|
22
|
+
export interface UseRuleEngineOptions {
|
|
23
|
+
/** Beperk configuraties tot één strategie */
|
|
24
|
+
strategyId?: string | null;
|
|
25
|
+
/** Naam voor de automatisch aangemaakte configuratie van die strategie */
|
|
26
|
+
strategyName?: string | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function useRuleEngine(options?: UseRuleEngineOptions): {
|
|
29
|
+
configs: RuleConfig[];
|
|
30
|
+
versions: RuleVersion[];
|
|
31
|
+
activeConfig: RuleConfig | null;
|
|
32
|
+
activeId: string | null;
|
|
33
|
+
setActiveId: import("react").Dispatch<import("react").SetStateAction<string | null>>;
|
|
34
|
+
loading: boolean;
|
|
35
|
+
saving: boolean;
|
|
36
|
+
error: string | null;
|
|
37
|
+
createConfig: (name: string, description?: string) => Promise<RuleConfig | null>;
|
|
38
|
+
patchSettings: (configId: string, settings: RuleEngineSettings) => void;
|
|
39
|
+
saveConfig: (config: RuleConfig, options?: {
|
|
40
|
+
note?: string;
|
|
41
|
+
status?: string;
|
|
42
|
+
}) => Promise<void>;
|
|
43
|
+
activateConfig: (configId: string) => Promise<void>;
|
|
44
|
+
restoreVersion: (version: RuleVersion) => Promise<void>;
|
|
45
|
+
deleteConfig: (configId: string) => Promise<void>;
|
|
46
|
+
reload: () => Promise<void>;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=useRuleEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRuleEngine.d.ts","sourceRoot":"","sources":["../../src/hooks/useRuleEngine.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsC,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEtG,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB;;;;;;;;;yBAoF3C,MAAM,gBAAgB,MAAM;8BA2BE,MAAM,YAAY,kBAAkB;yBAUhE,UAAU,YAAY;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;+BA4CtD,MAAM;8BA+BP,WAAW;6BAYqB,MAAM;;EA4BzD"}
|