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