Skip to content

Commit 792705a

Browse files
Merge pull request #15 from SamMed05/fix/preserve-algo-param-in-url
Fix algorithm selection not persisting from URL query parameters
2 parents 45cb7c1 + 194bfc8 commit 792705a

File tree

1 file changed

+79
-40
lines changed

1 file changed

+79
-40
lines changed

components/MainForm.tsx

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,43 @@ export default function MainForm() {
8585
const searchParams = useSearchParams();
8686
const router = useRouter();
8787

88+
// Helper to normalize algorithm values from URL to internal values
89+
const normalizeAlgorithm = (algo?: string | null) => {
90+
if (!algo) return null;
91+
const a = algo.toLowerCase();
92+
if (a === "fcfs" || a === "firstcomefirstserve" || a === "first_come_first_serve") return "FCFS";
93+
if (a === "rr" || a === "roundrobin" || a === "round_robin") return "RR";
94+
if (a === "sjf" || a === "shortestjobfirst" || a === "shortest_job_first") return "SJF";
95+
if (
96+
a === "srtf" ||
97+
a === "shortestremainingtimefirst" ||
98+
a === "shortest_remaining_time_first"
99+
)
100+
return "SRTF";
101+
return null;
102+
};
103+
104+
// Get initial values from URL
105+
const getInitialAlgorithm = () => {
106+
const algoRaw = searchParams?.get("algo");
107+
return normalizeAlgorithm(algoRaw) || "";
108+
};
109+
110+
const getInitialQuantum = () => {
111+
const quantum = searchParams?.get("quantum");
112+
const algo = normalizeAlgorithm(searchParams?.get("algo"));
113+
if (quantum && algo === "RR") {
114+
return parseInt(quantum);
115+
}
116+
return undefined;
117+
};
118+
88119
const form = useForm<z.infer<typeof FormSchema>>({
89120
resolver: zodResolver(FormSchema),
121+
defaultValues: {
122+
algorithm: getInitialAlgorithm(),
123+
quantum: getInitialQuantum(),
124+
},
90125
});
91126

92127
// Watch quantum so URL stays in sync when it changes
@@ -111,41 +146,22 @@ export default function MainForm() {
111146

112147
const summaryRef = useRef<HTMLDivElement>(null);
113148

114-
// Helper to normalize algorithm values from URL to internal values
115-
const normalizeAlgorithm = (algo?: string | null) => {
116-
if (!algo) return null;
117-
const a = algo.toLowerCase();
118-
if (a === "fcfs" || a === "firstcomefirstserve" || a === "first_come_first_serve")
119-
return "FCFS"; // internal value used in Select
120-
if (a === "rr" || a === "roundrobin" || a === "round_robin") return "RR";
121-
if (a === "sjf" || a === "shortestjobfirst" || a === "shortest_job_first")
122-
return "SJF";
123-
if (
124-
a === "srtf" ||
125-
a === "shortestremainingtimefirst" ||
126-
a === "shortest_remaining_time_first"
127-
)
128-
return "SRTF";
129-
return null;
130-
};
149+
// Sync selectedAlgorithm with form value on mount and changes
150+
useEffect(() => {
151+
const formAlgo = form.getValues("algorithm");
152+
if (formAlgo && formAlgo !== selectedAlgorithm) {
153+
setSelectedAlgorithm(formAlgo);
154+
}
155+
}, [form.watch("algorithm")]);
131156

132-
// Load data from URL on mount (only once)
157+
// Load processes from URL on mount (only once)
133158
useEffect(() => {
134-
if (hasLoadedFromUrl) return; // Prevent re-running
159+
if (hasLoadedFromUrl) return;
160+
if (!searchParams) return;
135161

162+
const processesData = searchParams.get("processes");
136163
const algoRaw = searchParams.get("algo");
137164
const algo = normalizeAlgorithm(algoRaw);
138-
const quantum = searchParams.get("quantum");
139-
const processesData = searchParams.get("processes");
140-
141-
if (algo) {
142-
form.setValue("algorithm", algo);
143-
setSelectedAlgorithm(algo);
144-
}
145-
146-
if (quantum && algo === "RR") {
147-
form.setValue("quantum", parseInt(quantum));
148-
}
149165

150166
if (processesData) {
151167
try {
@@ -159,21 +175,21 @@ export default function MainForm() {
159175
}
160176
if (Array.isArray(parsed)) {
161177
setProcesses(parsed as Process[]);
178+
179+
// If we have both algo and processes, trigger auto-submit
180+
if (algo && parsed.length > 0) {
181+
setShouldAutoSubmit(true);
182+
}
162183
} else {
163184
console.error("Invalid processes data from URL");
164185
}
165-
166-
// If we have both algo and processes, trigger auto-submit
167-
if (algo && Array.isArray(parsed) && parsed.length > 0) {
168-
setShouldAutoSubmit(true);
169-
}
170186
} catch (error) {
171187
console.error("Failed to parse processes from URL:", error);
172188
}
173189
}
174190

175191
setHasLoadedFromUrl(true);
176-
}, []); // Run only once on mount
192+
}, [searchParams, hasLoadedFromUrl]);
177193

178194
// Auto-submit when loaded from URL
179195
useEffect(() => {
@@ -194,22 +210,45 @@ export default function MainForm() {
194210
// Skip URL update if we haven't finished initial load
195211
if (!hasLoadedFromUrl) return;
196212

197-
const params = new URLSearchParams();
213+
// Start from current params so we don't accidentally drop existing ones
214+
const params = new URLSearchParams(window.location.search);
198215

216+
// algo handling
199217
if (selectedAlgorithm) {
200218
params.set("algo", selectedAlgorithm);
219+
} else {
220+
// If no algorithm is selected in state, do not drop an existing algo from the URL
221+
// Only remove it when state explicitly says there is none AND there wasn't one before
222+
// i.e., when it's already missing.
223+
if (!params.get("algo")) {
224+
params.delete("algo");
225+
}
201226
}
202227

203-
if (selectedAlgorithm === "RR" && quantumValue != null && !Number.isNaN(quantumValue)) {
228+
// quantum handling (only valid for RR)
229+
if (
230+
selectedAlgorithm === "RR" &&
231+
quantumValue != null &&
232+
!Number.isNaN(quantumValue)
233+
) {
204234
params.set("quantum", String(quantumValue));
235+
} else {
236+
params.delete("quantum");
205237
}
206238

239+
// processes handling
207240
if (processes.length > 0) {
208241
params.set("processes", encodeURIComponent(JSON.stringify(processes)));
242+
} else {
243+
params.delete("processes");
209244
}
210245

211-
const newUrl = params.toString() ? `?${params.toString()}` : window.location.pathname;
212-
router.replace(newUrl, { scroll: false });
246+
const newQuery = params.toString();
247+
const currentQuery = window.location.search.replace(/^\?/, "");
248+
if (newQuery !== currentQuery) {
249+
const newUrl = newQuery ? `?${newQuery}` : window.location.pathname;
250+
router.replace(newUrl, { scroll: false });
251+
}
213252
}, [processes, selectedAlgorithm, quantumValue, router, hasLoadedFromUrl]);
214253

215254
const addProcess = (newProcess: Omit<Process, "process_id">) => {

0 commit comments

Comments
 (0)