update : selection box user levels on agenda-settings and task

This commit is contained in:
hanif salafi 2025-08-19 10:01:29 +07:00
parent 78239c5f9d
commit 9fc973d151
2 changed files with 638 additions and 95 deletions

View File

@ -108,8 +108,8 @@ const EventModal = ({
const router = useRouter();
const pathname = usePathname();
const [isLoading, setIsLoading] = useState(false);
const [checkedLevels, setCheckedLevels] = useState(new Set());
const [expandedPolda, setExpandedPolda] = useState([{}]);
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>({});
const [audioFile, setAudioFile] = useState<File | null>(null);
const [isRecording, setIsRecording] = useState(false);
const [timer, setTimer] = useState<number>(120);
@ -151,7 +151,13 @@ const EventModal = ({
satker: false,
international: false,
});
const levelNumber = getCookiesDecrypt("ulne");
// State untuk melacak apakah perubahan berasal dari checkbox Jenis Agenda
const [isUpdatingFromJenisAgenda, setIsUpdatingFromJenisAgenda] = useState(false);
// State untuk melacak jenis perubahan spesifik
const [jenisAgendaChangeType, setJenisAgendaChangeType] = useState<string>("");
const levelNumber = Number(getCookiesDecrypt("ulne")) || 0;
const userLevelId = getCookiesDecrypt("ulie");
const poldaState = Cookies.get("state");
const [agendaType, setAgendaType] = React.useState("");
@ -253,15 +259,242 @@ const EventModal = ({
fetchDetailData();
}, [event, setValue]);
// useEffect untuk sinkronisasi checkbox modal dengan Jenis Agenda
useEffect(() => {
if (listDest.length > 0 && isUpdatingFromJenisAgenda && jenisAgendaChangeType) {
syncModalWithJenisAgenda();
}
}, [isUpdatingFromJenisAgenda, jenisAgendaChangeType]);
// useEffect untuk update wilayahPublish ketika pilihan modal berubah
useEffect(() => {
if (!isUpdatingFromJenisAgenda && listDest.length > 0) {
updateWilayahPublishFromModal();
}
}, [checkedLevels, isUpdatingFromJenisAgenda]);
// Fungsi untuk update wilayahPublish berdasarkan checkbox modal
const updateWilayahPublishFromModal = () => {
// Hanya update jika tidak sedang dalam proses update dari Jenis Agenda
if (!isUpdatingFromJenisAgenda && listDest.length > 0) {
// Hitung item yang dipilih berdasarkan checkedLevels
const checkedPoldaCount = listDest.filter((item: any) =>
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
checkedLevels.has(Number(item.id))
).length;
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
if (item.subDestination) {
return total + item.subDestination.filter((sub: any) => checkedLevels.has(Number(sub.id))).length;
}
return total;
}, 0);
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
const checkedSatkerCount = satkerItem ? (
(checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
(satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(Number(sub.id))).length || 0)
) : 0;
// Checkbox aktif jika ADA item yang dipilih dalam kategori tersebut
const hasSelectedPolda = checkedPoldaCount > 0;
const hasSelectedPolres = checkedPolresCount > 0;
const hasSelectedSatker = checkedSatkerCount > 0;
// Update arrays untuk backend
const newSelectedPolda = listDest
.filter((item: any) =>
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
checkedLevels.has(Number(item.id))
)
.map((item: any) => String(item.id));
const newSelectedPolres: string[] = [];
listDest.forEach((item: any) => {
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
if (checkedLevels.has(Number(sub.id))) {
newSelectedPolres.push(String(sub.id));
}
});
}
});
const newSelectedSatker: string[] = [];
if (satkerItem) {
if (checkedLevels.has(Number(satkerItem.id))) {
newSelectedSatker.push(String(satkerItem.id));
}
if (satkerItem.subDestination) {
satkerItem.subDestination.forEach((sub: any) => {
if (checkedLevels.has(Number(sub.id))) {
newSelectedSatker.push(String(sub.id));
}
});
}
}
// Update state arrays
setSelectedPolda(newSelectedPolda);
setSelectedPolres(newSelectedPolres);
setSelectedSatker(newSelectedSatker);
// Update wilayahPublish berdasarkan yang dipilih di modal
setWilayahPublish(prev => {
const newState = { ...prev };
// Update individual checkboxes
newState.polda = hasSelectedPolda;
newState.polres = hasSelectedPolres;
newState.satker = hasSelectedSatker;
// Update checkbox "semua" berdasarkan level user
if (levelNumber === 1) {
// Level 1: semua checkbox harus aktif (nasional, polda, polres, satker, international)
newState.semua = newState.nasional && hasSelectedPolda && hasSelectedPolres && hasSelectedSatker && newState.international;
} else if (levelNumber === 2) {
// Level 2: hanya polres yang perlu aktif
newState.semua = hasSelectedPolres;
} else {
newState.semua = false;
}
return newState;
});
// Update agendaType berdasarkan checkbox yang aktif
const selectedKeys = [];
if (hasSelectedPolda) selectedKeys.push(wilayahValueMap.polda);
if (hasSelectedPolres) selectedKeys.push(wilayahValueMap.polres);
if (hasSelectedSatker) selectedKeys.push(wilayahValueMap.satker);
setAgendaType(selectedKeys.join(","));
}
};
// Fungsi untuk sinkronisasi checkbox modal dengan Jenis Agenda
const syncModalWithJenisAgenda = () => {
// Hanya jalankan sinkronisasi jika perubahan berasal dari checkbox Jenis Agenda
if (isUpdatingFromJenisAgenda) {
const newCheckedLevels = new Set(checkedLevels);
// Handle checklist actions - menambahkan semua item ke modal
if (jenisAgendaChangeType === "polda_checked") {
// Checklist semua polda
listDest.forEach((item: any) => {
if (item.levelNumber === 2 && item.name !== "SATKER POLRI") {
newCheckedLevels.add(Number(item.id));
}
});
} else if (jenisAgendaChangeType === "polres_checked") {
// Checklist semua polres, tapi hanya yang poldanya sudah di-checklist
listDest.forEach((item: any) => {
if (item.levelNumber === 2 && item.name !== "SATKER POLRI" && newCheckedLevels.has(Number(item.id))) {
if (item.subDestination) {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.add(Number(polres.id));
});
}
}
});
} else if (jenisAgendaChangeType === "satker_checked") {
// Checklist satker
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
if (satkerItem) {
newCheckedLevels.add(Number(satkerItem.id));
if (satkerItem.subDestination) {
satkerItem.subDestination.forEach((sub: any) => {
newCheckedLevels.add(Number(sub.id));
});
}
}
}
// Handle unchecklist actions - menghapus item dari modal
else if (jenisAgendaChangeType === "polres_unchecked") {
// Clear polres dari checkedLevels
listDest.forEach((item: any) => {
if (item.subDestination) {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.delete(Number(polres.id));
});
}
});
} else if (jenisAgendaChangeType === "polda_unchecked") {
// Clear polda dan polres dari checkedLevels
listDest.forEach((item: any) => {
if (item.levelNumber === 2 && item.name !== "SATKER POLRI") {
newCheckedLevels.delete(Number(item.id));
// Juga clear polres dari polda ini
if (item.subDestination) {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.delete(Number(polres.id));
});
}
}
});
setWilayahPublish(prev => ({ ...prev, polres: false }));
} else if (jenisAgendaChangeType === "satker_unchecked") {
// Clear satker dari checkedLevels
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
if (satkerItem) {
newCheckedLevels.delete(Number(satkerItem.id));
if (satkerItem.subDestination) {
satkerItem.subDestination.forEach((sub: any) => {
newCheckedLevels.delete(Number(sub.id));
});
}
}
}
setCheckedLevels(newCheckedLevels);
// Reset flag setelah sinkronisasi selesai
setIsUpdatingFromJenisAgenda(false);
setJenisAgendaChangeType("");
}
};
useEffect(() => {
setIsDatePickerOpen(false);
}, [onClose]);
useEffect(() => {
async function fetchPoldaPolres() {
try {
const response = await getUserLevelForAssignments();
setListDest(response?.data?.data.list);
const initialExpandedState = response?.data?.data.list.reduce(
(acc: any, polda: any) => {
acc[polda.id] = false;
return acc;
},
{}
);
setExpandedPolda(initialExpandedState);
} catch (error) {
console.error("Error fetching Polda/Polres data:", error);
}
}
fetchPoldaPolres();
}, []);
const handleCheckboxChange = (levelId: number) => {
setCheckedLevels((prev) => {
const updatedLevels = new Set(prev);
if (updatedLevels.has(levelId)) {
const isCurrentlyChecked = updatedLevels.has(levelId);
if (isCurrentlyChecked) {
updatedLevels.delete(levelId);
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
const poldaItem = listDest.find((item: any) => Number(item.id) === levelId) as any;
if (poldaItem && poldaItem.subDestination) {
poldaItem.subDestination.forEach((polres: any) => {
updatedLevels.delete(Number(polres.id));
});
}
} else {
updatedLevels.add(levelId);
}
@ -279,6 +512,10 @@ const EventModal = ({
};
const toggleWilayah = (key: string) => {
// Set flag bahwa perubahan berasal dari checkbox Jenis Agenda
setIsUpdatingFromJenisAgenda(true);
setJenisAgendaChangeType(key + (wilayahPublish[key as keyof typeof wilayahPublish] ? "_unchecked" : "_checked"));
setWilayahPublish((prev: any) => {
let newState = { ...prev };
if (key === "semua") {
@ -294,15 +531,96 @@ const EventModal = ({
if (newChecked) {
setAgendaType("0,1,2,3,4,5");
// Checklist semua item di modal ketika "semua" di-checklist
const allCheckedLevels = new Set<number>();
listDest.forEach((item: any) => {
allCheckedLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
allCheckedLevels.add(Number(sub.id));
});
}
});
setCheckedLevels(allCheckedLevels);
} else {
setAgendaType("");
// Clear semua pilihan modal ketika "semua" di-unchecklist
setCheckedLevels(new Set());
}
return newState;
}
// Validasi khusus untuk POLRES
if (key === "polres" && !prev[key]) {
// Cek apakah ada POLDA yang sudah dipilih di modal
const hasSelectedPolda = listDest.some((item: any) =>
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
checkedLevels.has(Number(item.id))
);
if (!hasSelectedPolda) {
// Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan
alert("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.");
// Reset flag karena perubahan dibatalkan
setIsUpdatingFromJenisAgenda(false);
setJenisAgendaChangeType("");
return prev; // Batalkan perubahan
}
}
newState[key] = !prev[key];
// Jika checkbox di-unchecklist, clear pilihan modal yang sesuai
if (prev[key]) {
const newCheckedLevels = new Set(checkedLevels);
if (key === "polda") {
// Clear polda dan polres
listDest.forEach((item: any) => {
if (item.levelNumber === 2 && item.name !== "SATKER POLRI") {
newCheckedLevels.delete(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.delete(Number(polres.id));
});
}
}
});
} else if (key === "polres") {
// Clear polres
listDest.forEach((item: any) => {
if (item.subDestination) {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.delete(Number(polres.id));
});
}
});
} else if (key === "satker") {
// Clear satker
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
if (satkerItem) {
newCheckedLevels.delete(Number(satkerItem.id));
if (satkerItem.subDestination) {
satkerItem.subDestination.forEach((sub: any) => {
newCheckedLevels.delete(Number(sub.id));
});
}
}
}
setCheckedLevels(newCheckedLevels);
}
// Update checkbox "semua" berdasarkan status semua checkbox lainnya
// Untuk level 1: semua, nasional, polda, polres, satker, international harus aktif
// Untuk level 2: semua, polres harus aktif
if (levelNumber === 1) {
newState.semua = newState.nasional && newState.polda && newState.polres && newState.satker && newState.international;
} else if (levelNumber === 2) {
newState.semua = newState.polres;
} else {
newState.semua = false;
}
const selectedKeys = Object.entries(newState)
.filter(([k, v]) => v && k !== "semua")
@ -452,7 +770,7 @@ const EventModal = ({
const onDeleteEventAction = async () => {
try {
} catch (error) {}
} catch (error) { }
};
const handleOpenDeleteModal = (eventId: string) => {
@ -632,7 +950,7 @@ const EventModal = ({
);
};
const handleRemoveFile = (id: number) => {};
const handleRemoveFile = (id: number) => { };
async function doDelete(id: any) {
loading();
@ -800,7 +1118,8 @@ const EventModal = ({
</label>
</div>
{roleId === 1 && (
{levelNumber === 1 && (
<>
<div>
<Checkbox
id="nasional"
@ -811,8 +1130,6 @@ const EventModal = ({
Nasional
</label>
</div>
)}
<div>
<Checkbox
id="polda"
@ -822,18 +1139,11 @@ const EventModal = ({
<label htmlFor="polda" className="mx-2 text-sm mr-2">
Polda
</label>
{wilayahPublish.polda && (
<UnitMapping
unit="Polda"
isDetail={isDetailMode}
initData={selectedPolda}
sendDataToParent={(data: any) =>
setSelectedPolda(data)
}
/>
)}
</div>
{(roleId === 1 || roleId === 4 || roleId === 3) && (
</>
)}
{(levelNumber === 1 || levelNumber === 2) && (
<div>
<Checkbox
id="polres"
@ -843,19 +1153,11 @@ const EventModal = ({
<label htmlFor="polres" className="ml-2 text-sm mr-2">
Polres
</label>
{wilayahPublish.polres && (
<UnitMapping
unit="Polres"
isDetail={isDetailMode}
initData={selectedPolres}
sendDataToParent={(data: any) =>
setSelectedPolres(data)
}
/>
)}
</div>
)}
{(roleId === 1 || roleId === 2) && (
{levelNumber === 1 && (
<>
<div>
<Checkbox
id="satker"
@ -865,19 +1167,7 @@ const EventModal = ({
<label htmlFor="satker" className="mx-2 text-sm mr-2">
Satker
</label>
{wilayahPublish.satker && (
<UnitMapping
unit="Satker"
isDetail={isDetailMode}
initData={selectedSatker}
sendDataToParent={(data: any) =>
setSelectedSatker(data)
}
/>
)}
</div>
)}
{roleId === 1 && (
<div>
<Checkbox
id="international"
@ -891,7 +1181,97 @@ const EventModal = ({
Internasional
</label>
</div>
</>
)}
<div className="pl-1">
<Dialog>
<DialogTrigger asChild>
<Button variant="soft" size="sm" color="primary">
[Kustom]
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px] md:max-w-[500px] lg:max-w-[1500px]">
<DialogHeader>
<DialogTitle>
Daftar Wilayah Polda dan Polres
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
{listDest?.map((polda: any) => (
<div key={polda.id} className="border p-2">
<Label className="flex items-center">
<Checkbox
checked={checkedLevels.has(Number(polda.id))}
onCheckedChange={() =>
handleCheckboxChange(Number(polda.id))
}
className="mr-3"
/>
{polda.name}
<button
type="button"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(polda.id);
}}
className="ml-2 focus:outline-none"
>
{expandedPolda[polda.id] ? (
<ChevronUp size={16} />
) : (
<ChevronDown size={16} />
)}
</button>
</Label>
{expandedPolda[polda.id] && (
<div className="ml-6 mt-2">
<Label className="block">
<Checkbox
checked={polda?.subDestination?.every(
(polres: any) =>
checkedLevels.has(Number(polres.id))
)}
onCheckedChange={(isChecked) => {
const updatedLevels = new Set(
checkedLevels
);
polda?.subDestination?.forEach(
(polres: any) => {
if (isChecked) {
updatedLevels.add(Number(polres.id));
} else {
updatedLevels.delete(Number(polres.id));
}
}
);
setCheckedLevels(updatedLevels);
}}
className="mr-2"
/>
Pilih Semua
</Label>
{polda?.subDestination?.map((polres: any) => (
<Label key={polres.id} className="block mt-1">
<Checkbox
checked={checkedLevels.has(Number(polres.id))}
onCheckedChange={() =>
handleCheckboxChange(Number(polres.id))
}
className="mr-2"
/>
{polres.name}
</Label>
))}
</div>
)}
</div>
))}
</div>
</DialogContent>
</Dialog>
</div>
</div>
</div>
@ -1102,8 +1482,7 @@ const EventModal = ({
type="button"
onClick={onPlayPause}
disabled={isPlaying}
className={`flex items-center gap-2 ${
isPlaying
className={`flex items-center gap-2 ${isPlaying
? "bg-gray-300 cursor-not-allowed"
: "bg-primary text-white"
} p-2 rounded`}

View File

@ -122,7 +122,7 @@ export default function FormTask() {
const [detail, setDetail] = useState<taskDetail>();
const [refresh] = useState(false);
// const [listDest, setListDest] = useState([]);
const [checkedLevels, setCheckedLevels] = useState(new Set());
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
const [expandedPolda, setExpandedPolda] = useState([{}]);
const [isLoading, setIsLoading] = useState(false);
const [audioFile, setAudioFile] = useState<File | null>(null);
@ -146,6 +146,12 @@ export default function FormTask() {
polres: false,
satker: false,
});
// State untuk melacak apakah perubahan berasal dari checkbox Penerima Tugas
const [isUpdatingFromPenerimaTugas, setIsUpdatingFromPenerimaTugas] = useState(false);
// State untuk melacak jenis perubahan spesifik
const [penerimaTugasChangeType, setPenerimaTugasChangeType] = useState<string>("");
const [links, setLinks] = useState<string[]>([""]);
const {
register,
@ -194,13 +200,26 @@ export default function FormTask() {
const handleCheckboxChange = (levelId: number) => {
setCheckedLevels((prev) => {
const updatedLevels = new Set(prev);
if (updatedLevels.has(levelId)) {
const isCurrentlyChecked = updatedLevels.has(levelId);
if (isCurrentlyChecked) {
updatedLevels.delete(levelId);
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
const poldaItem = listDest.find((item: any) => Number(item.id) === levelId);
if (poldaItem && poldaItem.subDestination) {
poldaItem.subDestination.forEach((polres: any) => {
updatedLevels.delete(Number(polres.id));
});
}
} else {
updatedLevels.add(levelId);
}
return updatedLevels;
});
// Update unitSelection berdasarkan perubahan di modal
updateUnitSelectionFromModal();
};
const handlePoldaPolresChange = () => {
@ -211,6 +230,10 @@ export default function FormTask() {
key: keyof typeof unitSelection,
value: boolean
) => {
// Set flag bahwa perubahan berasal dari checkbox Penerima Tugas
setIsUpdatingFromPenerimaTugas(true);
setPenerimaTugasChangeType(key + (value ? "_checked" : "_unchecked"));
if (key === "allUnit") {
const newState = {
allUnit: value,
@ -220,8 +243,23 @@ export default function FormTask() {
satker: value,
};
setUnitSelection(newState);
console.log("QQQ", newState);
} else {
// Validasi khusus untuk POLRES
if (key === "polres" && value) {
// Cek apakah ada POLDA yang sudah dichecklist di modal
const hasCheckedPolda = listDest.some((item: any) =>
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
checkedLevels.has(Number(item.id))
);
if (!hasCheckedPolda) {
// Jika tidak ada POLDA yang dichecklist di modal, tampilkan peringatan dan batalkan
alert("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.");
return; // Batalkan perubahan
}
}
const updatedSelection = {
...unitSelection,
[key]: value,
@ -234,7 +272,6 @@ export default function FormTask() {
updatedSelection.allUnit = allChecked;
setUnitSelection(updatedSelection);
console.log("AAA", updatedSelection);
}
};
@ -348,25 +385,141 @@ export default function FormTask() {
}
};
// useEffect untuk sinkronisasi checkbox modal dengan Penerima Tugas
useEffect(() => {
const updated = new Set(checkedLevels);
if (listDest.length > 0) {
syncModalWithPenerimaTugas();
}
}, [unitSelection, listDest]);
if (unitSelection.polda) {
listDest.forEach((polda) => {
updated.add(polda.id); // hanya id polda
// Fungsi untuk update unitSelection berdasarkan checkbox modal
const updateUnitSelectionFromModal = () => {
setTimeout(() => {
// Hitung total item yang tersedia untuk setiap kategori
const totalPolda = listDest.filter((item: any) =>
item.levelNumber === 2 && item.name !== "SATKER POLRI"
).length;
const totalPolres = listDest.reduce((total: number, item: any) => {
if (item.subDestination) {
return total + item.subDestination.length;
}
return total;
}, 0);
const satkerItem = listDest.find((item: any) => item.name === "SATKER POLRI");
const totalSatker = satkerItem ? (1 + (satkerItem.subDestination?.length || 0)) : 0;
// Hitung item yang dichecklist untuk setiap kategori
const checkedPoldaCount = listDest.filter((item: any) =>
item.levelNumber === 2 &&
item.name !== "SATKER POLRI" &&
checkedLevels.has(Number(item.id))
).length;
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
if (item.subDestination) {
return total + item.subDestination.filter((sub: any) => checkedLevels.has(Number(sub.id))).length;
}
return total;
}, 0);
const checkedSatkerCount = satkerItem ? (
(checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
(satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(Number(sub.id))).length || 0)
) : 0;
// Checkbox hanya aktif jika SEMUA item dalam kategori tersebut dichecklist
const hasCheckedPolda = totalPolda > 0 && checkedPoldaCount === totalPolda;
const hasCheckedPolres = totalPolres > 0 && checkedPolresCount === totalPolres;
const hasCheckedSatker = totalSatker > 0 && checkedSatkerCount === totalSatker;
// Update unitSelection berdasarkan checkbox yang aktif di modal
setUnitSelection(prev => ({
...prev,
polda: hasCheckedPolda,
polres: hasCheckedPolres,
satker: hasCheckedSatker,
// allUnit hanya true jika semua kategori terpenuhi
allUnit: hasCheckedPolda && hasCheckedPolres && hasCheckedSatker
}));
}, 0);
};
// Fungsi untuk sinkronisasi checkbox modal dengan Penerima Tugas
const syncModalWithPenerimaTugas = () => {
// Hanya jalankan sinkronisasi jika perubahan berasal dari checkbox Penerima Tugas
if (isUpdatingFromPenerimaTugas) {
// Khusus untuk unchecklist POLRES: hanya unchecklist polres, pertahankan polda
if (penerimaTugasChangeType === "polres_unchecked") {
const newCheckedLevels = new Set<number>(checkedLevels);
// Hapus semua polres dari modal, tapi pertahankan polda
listDest.forEach((item: any) => {
if (item.subDestination && item.levelNumber === 2 && item.name !== "SATKER POLRI") {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.delete(Number(polres.id));
});
}
});
if (unitSelection.polres) {
listDest.forEach((polda) => {
polda?.subDestination?.forEach((polres: any) => {
updated.add(polres.id); // hanya id polres
});
});
setCheckedLevels(newCheckedLevels);
}
// Untuk perubahan lainnya, jalankan logika normal
else if (unitSelection.polda || unitSelection.polres || unitSelection.satker) {
// Mulai dengan checkbox yang sudah ada untuk mempertahankan pilihan manual user
const newCheckedLevels = new Set<number>(checkedLevels);
listDest.forEach((item: any) => {
// Jika polda dichecklist, checklist semua polda (levelNumber 2, bukan SATKER POLRI)
if (unitSelection.polda && item.levelNumber === 2 && item.name !== "SATKER POLRI") {
newCheckedLevels.add(Number(item.id));
}
setCheckedLevels(updated);
}, [unitSelection.polda, unitSelection.polres, listDest]);
// Jika satker dichecklist, checklist SATKER POLRI dan sub-itemnya
if (unitSelection.satker && item.name === "SATKER POLRI") {
newCheckedLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
newCheckedLevels.add(Number(sub.id));
});
}
}
// Jika polres dichecklist
if (unitSelection.polres && item.subDestination) {
// Jika checkbox POLDA di Penerima Tugas juga aktif, checklist semua polres
if (unitSelection.polda && item.levelNumber === 2 && item.name !== "SATKER POLRI") {
item.subDestination.forEach((polres: any) => {
newCheckedLevels.add(Number(polres.id));
});
}
// Jika checkbox POLDA di Penerima Tugas tidak aktif, tapi ada POLDA yang dichecklist di modal
else if (!unitSelection.polda && item.levelNumber === 2 && item.name !== "SATKER POLRI") {
// Cek apakah POLDA ini sudah dichecklist di modal
if (checkedLevels.has(Number(item.id))) {
// Jika ya, checklist semua polres dari POLDA ini
item.subDestination.forEach((polres: any) => {
newCheckedLevels.add(Number(polres.id));
});
}
}
}
});
setCheckedLevels(newCheckedLevels);
} else {
// Jika tidak ada unitSelection yang aktif, unchecklist semua item di modal
setCheckedLevels(new Set<number>());
}
// Reset flag setelah sinkronisasi selesai
setTimeout(() => {
setIsUpdatingFromPenerimaTugas(false);
setPenerimaTugasChangeType("");
}, 100);
}
};
const onSubmit = (data: TaskSchema) => {
MySwal.fire({
@ -604,7 +757,6 @@ export default function FormTask() {
</div>
<div className="flex flex-wrap gap-3 mt-5 lg:pt-7 lg:ml-3 ">
{Object.keys(unitSelection).map((key) => {
const isDisabled = key === "polres" && !unitSelection.polda;
return (
<div className="flex items-center gap-2" key={key}>
<Checkbox
@ -612,7 +764,6 @@ export default function FormTask() {
checked={
unitSelection[key as keyof typeof unitSelection]
}
disabled={isDisabled}
onCheckedChange={(value) =>
handleUnitChange(
key as keyof typeof unitSelection,
@ -621,7 +772,7 @@ export default function FormTask() {
}
/>
<Label htmlFor={key}>
{key.charAt(0).toUpperCase() + key.slice(1)}
{key === "allUnit" ? "Semua Unit" : key.charAt(0).toUpperCase() + key.slice(1)}
</Label>
</div>
);
@ -639,30 +790,22 @@ export default function FormTask() {
<DialogTitle>Daftar Wilayah Polda dan Polres</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
{listDest.map((polda: any) => {
const poldaChecked = unitSelection.polda; // kontrol polda luar
const polresChecked = unitSelection.polres; // kontrol polres luar
const isPoldaDisabled = poldaChecked; // lock checkbox polda dialog jika polda luar dicentang
const isPolresDisabled = polresChecked; // lock checkbox polres dialog jika polres luar dicentang
return (
{listDest.map((polda: any) => (
<div key={polda.id} className="border p-2">
<Label className="flex items-center">
<Checkbox
checked={
poldaChecked || checkedLevels.has(polda.id)
}
disabled={isPoldaDisabled}
onCheckedChange={() => {
if (isPoldaDisabled) return;
handleCheckboxChange(polda.id);
}}
checked={checkedLevels.has(Number(polda.id))}
onCheckedChange={() => handleCheckboxChange(Number(polda.id))}
className="mr-3"
/>
{polda.name}
<button
onClick={() => toggleExpand(polda.id)}
type="button"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(polda.id);
}}
className="ml-2 focus:outline-none"
>
{expandedPolda[polda.id] ? (
@ -672,21 +815,43 @@ export default function FormTask() {
)}
</button>
</Label>
{expandedPolda[polda.id] && (
<div className="ml-6 mt-2">
<Label className="block">
<Checkbox
checked={polda?.subDestination?.every(
(polres: any) =>
checkedLevels.has(Number(polres.id))
)}
onCheckedChange={(isChecked) => {
const updatedLevels = new Set(
checkedLevels
);
polda?.subDestination?.forEach(
(polres: any) => {
if (isChecked) {
updatedLevels.add(Number(polres.id));
} else {
updatedLevels.delete(Number(polres.id));
}
}
);
setCheckedLevels(updatedLevels);
// Update unitSelection berdasarkan perubahan
updateUnitSelectionFromModal();
}}
className="mr-2"
/>
Pilih Semua
</Label>
{polda?.subDestination?.map((polres: any) => (
<Label key={polres.id} className="block mt-1">
<Checkbox
checked={
polresChecked ||
checkedLevels.has(polres.id)
checked={checkedLevels.has(Number(polres.id))}
onCheckedChange={() =>
handleCheckboxChange(Number(polres.id))
}
disabled={isPolresDisabled}
onCheckedChange={() => {
if (isPolresDisabled) return;
handleCheckboxChange(polres.id);
}}
className="mr-2"
/>
{polres.name}
@ -695,8 +860,7 @@ export default function FormTask() {
</div>
)}
</div>
);
})}
))}
</div>
</DialogContent>
</Dialog>