fix: agenda setting

This commit is contained in:
Sabda Yagra 2025-08-15 22:23:33 +07:00
parent 71f0b3b52e
commit 5ae245c123
1 changed files with 114 additions and 66 deletions

View File

@ -65,38 +65,66 @@ export function UnitMapping(props: {
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {
const response = await getUserLevelForAssignments(); const response = await getUserLevelForAssignments();
setupUnit(response?.data?.data.list); const list: UnitType[] = response?.data?.data?.list ?? [];
console.log("list", response?.data?.data.list); setupUnit(list);
// console.log("list", list);
} }
initState(); initState();
}, []); }, []);
const unitType = form.watch("items"); // Selalu punya array
const unitType = form.watch("items") ?? [];
const isAllUnitChecked = unitType && unitList.every((item) => // ---- FIX: case-insensitive + flatMap semua node ----
unitType.includes(String(item.id)) const setupUnit = (data: UnitType[] = []) => {
); const norm = (v?: string) => (v ?? "").toUpperCase();
const isAllSatkerChecked = unitType && satkerList.every((item) =>
unitType.includes(String(item.id))
);
const isAllPolresChecked = polresList.every((item) =>
unitType?.includes(String(item.id))
);
const setupUnit = (data: UnitType[]) => { const poldaNodes = data.filter((a) => norm(a.name).includes("POLDA"));
const temp = data.filter((a) => a.name.includes("POLDA")); const satkerNodes = data.filter((a) => norm(a.name).includes("SATKER"));
const temp2 = data.filter((a) => a.name.includes("SATKER"));
const temp3 = temp.flatMap((item) => item.subDestination || []); // POLDA level (UnitType)
setUnitList(temp); setUnitList(poldaNodes);
setSatkerList(temp2[0]?.subDestination || []);
setPolresList(temp3); // SATKER adalah gabungan semua subDestination dari node SATKER
const allSatker = satkerNodes.flatMap((n) => n.subDestination ?? []) ?? [];
setSatkerList(allSatker);
// POLRES adalah gabungan semua subDestination dari node POLDA
const allPolres = poldaNodes.flatMap((n) => n.subDestination ?? []);
setPolresList(allPolres);
}; };
// ---- FIX: jangan true saat list kosong ----
const isAllUnitChecked =
unitList.length > 0 &&
unitList.every((item) => unitType.includes(String(item.id)));
const isAllSatkerChecked =
satkerList.length > 0 &&
satkerList.every((item) => unitType.includes(String(item.id)));
const isAllPolresChecked =
polresList.length > 0 &&
polresList.every((item) => unitType.includes(String(item.id)));
useEffect(() => { useEffect(() => {
sendDataToParent(form.getValues("items")); sendDataToParent(form.getValues("items"));
}, [unitType]); }, [unitType]);
// helper untuk ambil id-ids per kategori aktif
const currentIds = () => {
if (unit === "Polda") return unitList.map((i) => String(i.id));
if (unit === "Satker") return satkerList.map((i) => String(i.id));
return polresList.map((i) => String(i.id));
};
const allCheckedByUnit =
unit === "Polda"
? isAllUnitChecked
: unit === "Satker"
? isAllSatkerChecked
: isAllPolresChecked;
return ( return (
<Dialog open={isOpen} onOpenChange={setIsOpen}> <Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger asChild> <DialogTrigger asChild>
@ -116,41 +144,48 @@ export function UnitMapping(props: {
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Checkbox <Checkbox
id={`all-${unit}`} id={`all-${unit}`}
checked={ checked={allCheckedByUnit}
unit === "Polda"
? isAllUnitChecked
: unit === "Satker"
? isAllSatkerChecked
: isAllPolresChecked
}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
const ids = currentIds();
if (checked) { if (checked) {
form.setValue( // gabungkan supaya kategori lain tidak hilang
"items", const merged = Array.from(new Set([...unitType, ...ids]));
unit === "Polda" form.setValue("items", merged, {
? unitList.map((item) => String(item.id)) shouldDirty: true,
: unit === "Satker" shouldTouch: true,
? satkerList.map((item) => String(item.id)) shouldValidate: true,
: polresList.map((item) => String(item.id)) });
);
} else { } else {
form.setValue("items", []); // hapus hanya id kategori aktif
const filtered = unitType.filter((v) => !ids.includes(v));
form.setValue("items", filtered, {
shouldDirty: true,
shouldTouch: true,
shouldValidate: true,
});
} }
}} }}
/> />
<label
<label htmlFor="all" className="text-sm text-black uppercase"> htmlFor={`all-${unit}`}
className="text-sm text-black uppercase"
>
SEMUA {unit} SEMUA {unit}
</label> </label>
</div> </div>
<FormField <FormField
control={form.control} control={form.control}
name="items" name="items"
render={() => ( render={() => (
<FormItem <FormItem
className={`grid grid-cols-${ className={`grid ${
unit === "Polda" ? "2" : unit === "Satker" ? "3" : "4" unit === "Polda"
}`} ? "grid-cols-2"
: unit === "Satker"
? "grid-cols-3"
: "grid-cols-4"
} gap-2`}
> >
{(unit === "Polda" {(unit === "Polda"
? unitList ? unitList
@ -162,33 +197,46 @@ export function UnitMapping(props: {
key={item.id} key={item.id}
control={form.control} control={form.control}
name="items" name="items"
render={({ field }) => { render={({ field }) => (
return ( <FormItem className="flex flex-row items-center space-x-3 space-y-0">
<FormItem <FormControl>
key={String(item.id)} <Checkbox
className="flex flex-row items-center space-x-3 space-y-0" checked={field.value?.includes(String(item.id))}
> onCheckedChange={(checked) => {
<FormControl> if (checked) {
<Checkbox form.setValue(
checked={field.value?.includes(String(item.id))} "items",
onCheckedChange={(checked) => { Array.from(
return checked new Set([
? field.onChange([ ...(field.value ?? []),
...field.value,
String(item.id), String(item.id),
]) ])
: field.onChange( ),
field.value?.filter( {
(value) => value !== String(item.id) shouldDirty: true,
) shouldTouch: true,
); shouldValidate: true,
}} }
/> );
</FormControl> } else {
<p className="text-sm text-black">{item.name}</p> form.setValue(
</FormItem> "items",
); (field.value ?? []).filter(
}} (v: string) => v !== String(item.id)
),
{
shouldDirty: true,
shouldTouch: true,
shouldValidate: true,
}
);
}
}}
/>
</FormControl>
<p className="text-sm text-black">{item.name}</p>
</FormItem>
)}
/> />
))} ))}
<FormMessage /> <FormMessage />