update : selection box user levels
This commit is contained in:
parent
24a5e2a5c1
commit
c12dbf1596
|
|
@ -118,9 +118,9 @@ export default function FormContestDetail() {
|
||||||
const [detail, setDetail] = useState<any>();
|
const [detail, setDetail] = useState<any>();
|
||||||
const [refresh] = useState(false);
|
const [refresh] = useState(false);
|
||||||
const [date, setDate] = useState<DateRange | undefined>();
|
const [date, setDate] = useState<DateRange | undefined>();
|
||||||
const [listDest, setListDest] = useState([]);
|
const [listDest, setListDest] = useState<any[]>([]);
|
||||||
const [checkedLevels, setCheckedLevels] = useState(new Set());
|
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
|
||||||
const [expandedPolda, setExpandedPolda] = useState([{}]);
|
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>({});
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [audioFile, setAudioFile] = useState<File | null>(null);
|
const [audioFile, setAudioFile] = useState<File | null>(null);
|
||||||
const [imageFiles, setImageFiles] = useState<FileWithPreview[]>([]);
|
const [imageFiles, setImageFiles] = useState<FileWithPreview[]>([]);
|
||||||
|
|
@ -153,6 +153,11 @@ export default function FormContestDetail() {
|
||||||
satker: false,
|
satker: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// State untuk melacak apakah perubahan berasal dari checkbox Pelaksana Tugas
|
||||||
|
const [isUpdatingFromPelaksana, setIsUpdatingFromPelaksana] = useState(false);
|
||||||
|
// State untuk melacak jenis perubahan spesifik
|
||||||
|
const [pelaksanaChangeType, setPelaksanaChangeType] = useState<string>("");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
|
|
@ -192,6 +197,16 @@ export default function FormContestDetail() {
|
||||||
fetchPoldaPolres();
|
fetchPoldaPolres();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// useEffect untuk sinkronisasi checkbox modal dengan Pelaksana Tugas
|
||||||
|
// Ketika unitSelection berubah dari checkbox Pelaksana Tugas:
|
||||||
|
// - Jika di-checklist: checklist semua item sesuai kategori di modal
|
||||||
|
// - Jika di-unchecklist: unchecklist semua item di modal
|
||||||
|
useEffect(() => {
|
||||||
|
if (listDest.length > 0) {
|
||||||
|
syncModalWithUnitSelection();
|
||||||
|
}
|
||||||
|
}, [unitSelection, listDest]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
@ -237,6 +252,61 @@ export default function FormContestDetail() {
|
||||||
}
|
}
|
||||||
}, [detail?.targetOutput]);
|
}, [detail?.targetOutput]);
|
||||||
|
|
||||||
|
// Fungsi untuk update unitSelection berdasarkan checkbox modal
|
||||||
|
// Checkbox di Pelaksana Tugas hanya akan aktif jika SEMUA item dalam kategori tersebut dichecklist
|
||||||
|
const updateUnitSelectionFromModal = (levelId: number) => {
|
||||||
|
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(item.id)
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
|
||||||
|
if (item.subDestination) {
|
||||||
|
return total + item.subDestination.filter((sub: any) => checkedLevels.has(sub.id)).length;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const checkedSatkerCount = satkerItem ? (
|
||||||
|
(checkedLevels.has(satkerItem.id) ? 1 : 0) +
|
||||||
|
(satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(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);
|
||||||
|
};
|
||||||
|
|
||||||
const handleCheckboxChange = (levelId: number) => {
|
const handleCheckboxChange = (levelId: number) => {
|
||||||
setCheckedLevels((prev) => {
|
setCheckedLevels((prev) => {
|
||||||
const updatedLevels = new Set(prev);
|
const updatedLevels = new Set(prev);
|
||||||
|
|
@ -247,6 +317,85 @@ export default function FormContestDetail() {
|
||||||
}
|
}
|
||||||
return updatedLevels;
|
return updatedLevels;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update unitSelection berdasarkan perubahan di modal
|
||||||
|
updateUnitSelectionFromModal(levelId);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk sinkronisasi checkbox modal dengan Pelaksana Tugas
|
||||||
|
const syncModalWithUnitSelection = () => {
|
||||||
|
// Hanya jalankan sinkronisasi jika perubahan berasal dari checkbox Pelaksana Tugas
|
||||||
|
if (isUpdatingFromPelaksana) {
|
||||||
|
// Khusus untuk unchecklist POLRES: hanya unchecklist polres, pertahankan polda
|
||||||
|
if (pelaksanaChangeType === "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(polres.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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(item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika satker dichecklist, checklist SATKER POLRI dan sub-itemnya
|
||||||
|
if (unitSelection.satker && item.name === "SATKER POLRI") {
|
||||||
|
newCheckedLevels.add(item.id);
|
||||||
|
if (item.subDestination) {
|
||||||
|
item.subDestination.forEach((sub: any) => {
|
||||||
|
newCheckedLevels.add(sub.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika polres dichecklist
|
||||||
|
if (unitSelection.polres && item.subDestination) {
|
||||||
|
// Jika checkbox POLDA di Pelaksana Tugas juga aktif, checklist semua polres
|
||||||
|
if (unitSelection.polda && item.levelNumber === 2 && item.name !== "SATKER POLRI") {
|
||||||
|
item.subDestination.forEach((polres: any) => {
|
||||||
|
newCheckedLevels.add(polres.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Jika checkbox POLDA di Pelaksana 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(item.id)) {
|
||||||
|
// Jika ya, checklist semua polres dari POLDA ini
|
||||||
|
item.subDestination.forEach((polres: any) => {
|
||||||
|
newCheckedLevels.add(polres.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setCheckedLevels(newCheckedLevels);
|
||||||
|
} else {
|
||||||
|
// Jika tidak ada unitSelection yang aktif, unchecklist semua item di modal
|
||||||
|
// Setelah itu user bisa checklist secara manual
|
||||||
|
setCheckedLevels(new Set<number>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset flag setelah sinkronisasi selesai
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsUpdatingFromPelaksana(false);
|
||||||
|
setPelaksanaChangeType("");
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePoldaPolresChange = () => {
|
const handlePoldaPolresChange = () => {
|
||||||
|
|
@ -706,6 +855,10 @@ export default function FormContestDetail() {
|
||||||
id={key}
|
id={key}
|
||||||
checked={unitSelection[key as keyof typeof unitSelection]}
|
checked={unitSelection[key as keyof typeof unitSelection]}
|
||||||
onCheckedChange={(value) => {
|
onCheckedChange={(value) => {
|
||||||
|
// Set flag bahwa perubahan berasal dari checkbox Pelaksana Tugas
|
||||||
|
setIsUpdatingFromPelaksana(true);
|
||||||
|
setPelaksanaChangeType(key + (value ? "_checked" : "_unchecked"));
|
||||||
|
|
||||||
if (key === "allUnit") {
|
if (key === "allUnit") {
|
||||||
const newValue = Boolean(value);
|
const newValue = Boolean(value);
|
||||||
setUnitSelection({
|
setUnitSelection({
|
||||||
|
|
@ -716,6 +869,22 @@ export default function FormContestDetail() {
|
||||||
satker: newValue,
|
satker: newValue,
|
||||||
});
|
});
|
||||||
} else {
|
} 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(item.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasCheckedPolda) {
|
||||||
|
// Jika tidak ada POLDA yang dichecklist di modal, tampilkan peringatan dan batalkan
|
||||||
|
alert("Harap pilih POLDA di Modal List terlebih dahulu sebelum mengaktifkan checkbox POLRES.");
|
||||||
|
return; // Batalkan perubahan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setUnitSelection((prev) => {
|
setUnitSelection((prev) => {
|
||||||
const updated = { ...prev, [key]: Boolean(value) };
|
const updated = { ...prev, [key]: Boolean(value) };
|
||||||
// Update 'allUnit' jika semua sub-checkbox true
|
// Update 'allUnit' jika semua sub-checkbox true
|
||||||
|
|
@ -758,7 +927,12 @@ export default function FormContestDetail() {
|
||||||
/>
|
/>
|
||||||
{polda.name}
|
{polda.name}
|
||||||
<button
|
<button
|
||||||
onClick={() => toggleExpand(polda.id)}
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
toggleExpand(polda.id);
|
||||||
|
}}
|
||||||
className="ml-2 focus:outline-none"
|
className="ml-2 focus:outline-none"
|
||||||
>
|
>
|
||||||
{expandedPolda[polda.id] ? (
|
{expandedPolda[polda.id] ? (
|
||||||
|
|
@ -790,10 +964,60 @@ export default function FormContestDetail() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
setCheckedLevels(updatedLevels);
|
setCheckedLevels(updatedLevels);
|
||||||
|
|
||||||
|
// Update unitSelection berdasarkan perubahan
|
||||||
|
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" &&
|
||||||
|
updatedLevels.has(item.id)
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
|
||||||
|
if (item.subDestination) {
|
||||||
|
return total + item.subDestination.filter((sub: any) => updatedLevels.has(sub.id)).length;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const checkedSatkerCount = satkerItem ? (
|
||||||
|
(updatedLevels.has(satkerItem.id) ? 1 : 0) +
|
||||||
|
(satkerItem.subDestination?.filter((sub: any) => updatedLevels.has(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;
|
||||||
|
|
||||||
|
setUnitSelection(prev => ({
|
||||||
|
...prev,
|
||||||
|
polda: hasCheckedPolda,
|
||||||
|
polres: hasCheckedPolres,
|
||||||
|
satker: hasCheckedSatker,
|
||||||
|
allUnit: hasCheckedPolda && hasCheckedPolres && hasCheckedSatker
|
||||||
|
}));
|
||||||
|
}, 0);
|
||||||
}}
|
}}
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
/>
|
/>
|
||||||
Pilih Semua Polres
|
Pilih Semua
|
||||||
</Label>
|
</Label>
|
||||||
{polda?.subDestination?.map((polres: any) => (
|
{polda?.subDestination?.map((polres: any) => (
|
||||||
<Label key={polres.id} className="block mt-1">
|
<Label key={polres.id} className="block mt-1">
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue