update : image detail approval
This commit is contained in:
parent
9fc973d151
commit
82bf3a8709
|
|
@ -171,11 +171,16 @@ export default function FormImageDetail() {
|
|||
satker: false,
|
||||
});
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [checkedLevels, setCheckedLevels] = useState<any>(new Set());
|
||||
const [checkedLevels, setCheckedLevels] = useState<Set<number>>(new Set());
|
||||
const [selectedTarget, setSelectedTarget] = useState("");
|
||||
const [files, setFiles] = useState<FileType[]>([]);
|
||||
const [rejectedFiles, setRejectedFiles] = useState<number[]>([]);
|
||||
const [expandedPolda, setExpandedPolda] = useState([{}]);
|
||||
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>({});
|
||||
|
||||
// State untuk melacak apakah perubahan berasal dari checkbox utama
|
||||
const [isUpdatingFromMainCheckbox, setIsUpdatingFromMainCheckbox] = useState(false);
|
||||
// State untuk melacak jenis perubahan spesifik
|
||||
const [mainCheckboxChangeType, setMainCheckboxChangeType] = useState<string>("");
|
||||
const [wilayahPublish, setWilayahPublish] = React.useState({
|
||||
semua: false,
|
||||
nasional: false,
|
||||
|
|
@ -240,30 +245,175 @@ export default function FormImageDetail() {
|
|||
fetchPoldaPolres();
|
||||
}, []);
|
||||
|
||||
// useEffect untuk sinkronisasi checkbox modal dengan checkbox utama
|
||||
useEffect(() => {
|
||||
const updated = new Set(checkedLevels);
|
||||
if (listDest.length > 0 && isUpdatingFromMainCheckbox && mainCheckboxChangeType) {
|
||||
syncModalWithMainCheckbox();
|
||||
}
|
||||
}, [isUpdatingFromMainCheckbox, mainCheckboxChangeType]);
|
||||
|
||||
if (unitSelection.polda) {
|
||||
listDest.forEach((polda) => {
|
||||
updated.add(polda.id); // hanya id polda
|
||||
// useEffect untuk update checkbox utama ketika pilihan modal berubah
|
||||
useEffect(() => {
|
||||
if (!isUpdatingFromMainCheckbox && listDest.length > 0) {
|
||||
updateMainCheckboxFromModal();
|
||||
}
|
||||
}, [checkedLevels, isUpdatingFromMainCheckbox]);
|
||||
|
||||
// Fungsi untuk update checkbox utama berdasarkan checkbox modal
|
||||
const updateMainCheckboxFromModal = () => {
|
||||
if (!isUpdatingFromMainCheckbox && 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 && item.name !== "SATKER POLRI") {
|
||||
// Hanya hitung sub-item dari POLDA (bukan dari SATKER POLRI)
|
||||
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 unitSelection berdasarkan yang dipilih di modal
|
||||
setUnitSelection(prev => {
|
||||
const newState = { ...prev };
|
||||
|
||||
// Update individual checkboxes
|
||||
newState.polda = hasSelectedPolda;
|
||||
newState.polres = hasSelectedPolres;
|
||||
newState.satker = hasSelectedSatker;
|
||||
|
||||
// Update checkbox "semua" berdasarkan semua checkbox yang aktif
|
||||
newState.semua = newState.nasional && newState.wilayah && newState.international && hasSelectedPolda && hasSelectedPolres && hasSelectedSatker;
|
||||
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (unitSelection.polres) {
|
||||
listDest.forEach((polda) => {
|
||||
polda?.subDestination?.forEach((polres: any) => {
|
||||
updated.add(polres.id); // hanya id polres
|
||||
// Fungsi untuk sinkronisasi checkbox modal dengan checkbox utama
|
||||
const syncModalWithMainCheckbox = () => {
|
||||
if (isUpdatingFromMainCheckbox) {
|
||||
const newCheckedLevels = new Set(checkedLevels);
|
||||
|
||||
// Handle checklist actions - menambahkan semua item ke modal
|
||||
if (mainCheckboxChangeType === "polda_checked") {
|
||||
// Checklist semua polda
|
||||
listDest.forEach((item: any) => {
|
||||
if (item.levelNumber === 2 && item.name !== "SATKER POLRI") {
|
||||
newCheckedLevels.add(Number(item.id));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (mainCheckboxChangeType === "polres_checked") {
|
||||
// Checklist semua polres, tapi hanya yang poldanya sudah di-checklist
|
||||
// Jangan checklist sub-item SATKER POLRI
|
||||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Tidak perlu menghapus SATKER ketika POLRES di-checklist
|
||||
// Biarkan keduanya bisa aktif bersamaan
|
||||
// SATKER dan POLRES adalah konsep yang berbeda:
|
||||
// - SATKER: unit-unit seperti ITWASUM, BAINTELKAM, dll.
|
||||
// - POLRES: unit-unit seperti POLRES METRO JAKARTA PUSAT, dll.
|
||||
} else if (mainCheckboxChangeType === "satker_checked") {
|
||||
// Checklist satker
|
||||
const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI");
|
||||
if (satkerItem) {
|
||||
newCheckedLevels.add(Number(satkerItem.id));
|
||||
// Checklist semua sub-item yang ada di bawah SATKER (bukan POLRES)
|
||||
if (satkerItem.subDestination) {
|
||||
satkerItem.subDestination.forEach((sub: any) => {
|
||||
newCheckedLevels.add(Number(sub.id));
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (mainCheckboxChangeType === "semua_checked") {
|
||||
// Checklist semua item
|
||||
listDest.forEach((item: any) => {
|
||||
newCheckedLevels.add(Number(item.id));
|
||||
// Checklist semua sub-item di bawah setiap item
|
||||
if (item.subDestination) {
|
||||
item.subDestination.forEach((sub: any) => {
|
||||
newCheckedLevels.add(Number(sub.id));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Handle unchecklist actions - menghapus item dari modal
|
||||
else if (mainCheckboxChangeType === "polres_unchecked") {
|
||||
// Clear polres dari checkedLevels, tapi jangan hapus sub-item SATKER POLRI
|
||||
listDest.forEach((item: any) => {
|
||||
if (item.subDestination && item.name !== "SATKER POLRI") {
|
||||
item.subDestination.forEach((polres: any) => {
|
||||
newCheckedLevels.delete(Number(polres.id));
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (mainCheckboxChangeType === "polda_unchecked") {
|
||||
// Clear polda dan polres dari checkedLevels, tapi jangan hapus SATKER POLRI
|
||||
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 (mainCheckboxChangeType === "satker_unchecked") {
|
||||
// Clear satker dan semua sub-item di bawahnya 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));
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (mainCheckboxChangeType === "semua_unchecked") {
|
||||
// Clear semua
|
||||
newCheckedLevels.clear();
|
||||
}
|
||||
|
||||
setCheckedLevels(newCheckedLevels);
|
||||
|
||||
// Reset flag setelah sinkronisasi selesai
|
||||
setIsUpdatingFromMainCheckbox(false);
|
||||
setMainCheckboxChangeType("");
|
||||
}
|
||||
|
||||
setCheckedLevels(updated);
|
||||
}, [unitSelection.polda, unitSelection.polres, listDest]);
|
||||
};
|
||||
|
||||
const handleUnitChange = (
|
||||
key: keyof typeof unitSelection,
|
||||
value: boolean
|
||||
) => {
|
||||
// Set flag bahwa perubahan berasal dari checkbox utama
|
||||
setIsUpdatingFromMainCheckbox(true);
|
||||
setMainCheckboxChangeType(key + (value ? "_checked" : "_unchecked"));
|
||||
|
||||
if (key === "semua") {
|
||||
// Jika klik Semua, set semua value ke true/false
|
||||
const newState = {
|
||||
|
|
@ -277,6 +427,28 @@ export default function FormImageDetail() {
|
|||
};
|
||||
setUnitSelection(newState);
|
||||
} else {
|
||||
// Validasi khusus untuk POLRES
|
||||
if (key === "polres" && value) {
|
||||
// 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
|
||||
setIsUpdatingFromMainCheckbox(false);
|
||||
setMainCheckboxChangeType("");
|
||||
return; // Batalkan perubahan
|
||||
}
|
||||
}
|
||||
|
||||
// Tidak ada validasi khusus untuk SATKER dan POLRES
|
||||
// Keduanya bisa aktif bersamaan
|
||||
|
||||
// Update salah satu saja
|
||||
const updatedSelection = {
|
||||
...unitSelection,
|
||||
|
|
@ -326,12 +498,38 @@ export default function FormImageDetail() {
|
|||
};
|
||||
|
||||
const handleCheckboxChangePlacement = (levelId: number) => {
|
||||
setCheckedLevels((prev: any) => {
|
||||
const updatedLevels = new Set(prev);
|
||||
if (updatedLevels.has(levelId)) {
|
||||
setCheckedLevels((prev: Set<number>) => {
|
||||
const updatedLevels = new Set<number>(prev);
|
||||
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.name !== "SATKER POLRI") {
|
||||
poldaItem.subDestination.forEach((polres: any) => {
|
||||
updatedLevels.delete(Number(polres.id));
|
||||
});
|
||||
}
|
||||
|
||||
// Jika ini adalah SATKER POLRI yang di-unchecklist, unchecklist juga semua sub-item di bawahnya
|
||||
if (poldaItem && poldaItem.name === "SATKER POLRI") {
|
||||
poldaItem.subDestination?.forEach((subItem: any) => {
|
||||
updatedLevels.delete(Number(subItem.id));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
updatedLevels.add(levelId);
|
||||
|
||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||
const satkerItem = listDest.find((item: any) => Number(item.id) === levelId) as any;
|
||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||
satkerItem.subDestination?.forEach((subItem: any) => {
|
||||
updatedLevels.add(Number(subItem.id));
|
||||
});
|
||||
}
|
||||
}
|
||||
return updatedLevels;
|
||||
});
|
||||
|
|
@ -395,7 +593,7 @@ export default function FormImageDetail() {
|
|||
setupPlacementCheck(details?.files?.length);
|
||||
|
||||
if (details?.assignedToLevel) {
|
||||
const levels = new Set(
|
||||
const levels = new Set<number>(
|
||||
details.assignedToLevel.split(",").map(Number)
|
||||
);
|
||||
setCheckedLevels(levels);
|
||||
|
|
@ -519,10 +717,23 @@ export default function FormImageDetail() {
|
|||
if (checked) {
|
||||
if (placement === "all") {
|
||||
temp[index] = ["all", "mabes", "polda", "international"];
|
||||
} else if (placement === "satker") {
|
||||
// Ketika satker di-checklist, HANYA tambahkan satker saja
|
||||
// JANGAN otomatis checklist polres
|
||||
const now = temp[index] || [];
|
||||
if (!now.includes("satker")) {
|
||||
now.push("satker");
|
||||
}
|
||||
temp[index] = now;
|
||||
} else {
|
||||
const now = temp[index];
|
||||
now?.push(placement);
|
||||
if (now.length === 3 && !now.includes("all")) {
|
||||
const now = temp[index] || [];
|
||||
if (!now.includes(placement)) {
|
||||
now.push(placement);
|
||||
}
|
||||
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
||||
// JANGAN include satker dalam perhitungan auto "all"
|
||||
const nonSatkerItems = now.filter(item => item !== "satker" && item !== "all");
|
||||
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
||||
now.push("all");
|
||||
}
|
||||
temp[index] = now;
|
||||
|
|
@ -534,9 +745,13 @@ export default function FormImageDetail() {
|
|||
const now = temp[index].filter((a) => a !== placement);
|
||||
console.log("now", now);
|
||||
temp[index] = now;
|
||||
if (now.length === 3 && now.includes("all")) {
|
||||
const newData = now.filter((b) => b !== "all");
|
||||
temp[index] = newData;
|
||||
// Hapus "all" jika tidak semua item ter-checklist
|
||||
if (now.includes("all")) {
|
||||
const nonSatkerItems = now.filter(item => item !== "satker" && item !== "all");
|
||||
if (nonSatkerItems.length < 3) {
|
||||
const newData = now.filter((b) => b !== "all");
|
||||
temp[index] = newData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1031,45 +1246,30 @@ export default function FormImageDetail() {
|
|||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
|
||||
{listDest.map((polda: any) => {
|
||||
const poldaChecked =
|
||||
unitSelection.polda;
|
||||
const polresChecked =
|
||||
unitSelection.polres;
|
||||
const isPoldaDisabled =
|
||||
poldaChecked;
|
||||
const isPolresDisabled =
|
||||
polresChecked;
|
||||
|
||||
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;
|
||||
handleCheckboxChangePlacement(
|
||||
polda.id
|
||||
);
|
||||
}}
|
||||
className="mr-3"
|
||||
/>
|
||||
{polda.name}
|
||||
<div className="flex items-center">
|
||||
<Label className="flex items-center flex-1">
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(Number(polda.id))}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChangePlacement(Number(polda.id))
|
||||
}
|
||||
className="mr-3"
|
||||
/>
|
||||
{polda.name}
|
||||
</Label>
|
||||
<button
|
||||
onClick={() =>
|
||||
toggleExpand(polda.id)
|
||||
}
|
||||
className="ml-2 focus:outline-none"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
toggleExpand(polda.id);
|
||||
}}
|
||||
className="ml-2 focus:outline-none p-1 hover:bg-gray-100 rounded"
|
||||
type="button"
|
||||
>
|
||||
{expandedPolda[polda.id] ? (
|
||||
<ChevronUp size={16} />
|
||||
|
|
@ -1077,46 +1277,76 @@ export default function FormImageDetail() {
|
|||
<ChevronDown size={16} />
|
||||
)}
|
||||
</button>
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
{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<number>(
|
||||
checkedLevels
|
||||
);
|
||||
|
||||
// Jika ini adalah SATKER POLRI, checklist juga sub-item di bawahnya
|
||||
if (polda.name === "SATKER POLRI") {
|
||||
if (isChecked) {
|
||||
updatedLevels.add(Number(polda.id));
|
||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||
polda?.subDestination?.forEach((subItem: any) => {
|
||||
updatedLevels.add(Number(subItem.id));
|
||||
});
|
||||
} else {
|
||||
updatedLevels.delete(Number(polda.id));
|
||||
// Unchecklist semua sub-item di bawah SATKER POLRI
|
||||
polda?.subDestination?.forEach((subItem: any) => {
|
||||
updatedLevels.delete(Number(subItem.id));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Untuk POLDA biasa, checklist/unchecklist polres
|
||||
polda?.subDestination?.forEach(
|
||||
(polres: any) => {
|
||||
if (isChecked) {
|
||||
updatedLevels.add(Number(polres.id));
|
||||
} else {
|
||||
updatedLevels.delete(Number(polres.id));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
setCheckedLevels(updatedLevels);
|
||||
}}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polda.name === "SATKER POLRI" ? "Pilih SATKER" : "Pilih Semua"}
|
||||
</Label>
|
||||
{polda?.subDestination?.map(
|
||||
(polres: any) => (
|
||||
<Label
|
||||
key={polres.id}
|
||||
className="block mt-1"
|
||||
>
|
||||
<Checkbox
|
||||
checked={
|
||||
polresChecked ||
|
||||
checkedLevels.has(
|
||||
polres.id
|
||||
)
|
||||
}
|
||||
disabled={
|
||||
isPolresDisabled
|
||||
}
|
||||
onCheckedChange={() => {
|
||||
if (
|
||||
isPolresDisabled
|
||||
)
|
||||
return;
|
||||
handleCheckboxChangePlacement(
|
||||
polres.id
|
||||
);
|
||||
}}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polres.name}
|
||||
<Checkbox
|
||||
checked={checkedLevels.has(Number(polres.id))}
|
||||
onCheckedChange={() =>
|
||||
handleCheckboxChangePlacement(Number(polres.id))
|
||||
}
|
||||
className="mr-2"
|
||||
/>
|
||||
{polres.name}
|
||||
</Label>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
|
|
|||
Loading…
Reference in New Issue