// Rôle : fournit l'outil checklist avec quantités, catégories et échange texte. import { useState } from "react"; import { Icon } from "../../../components/Icon.jsx"; import { useGroupedReorder, moveItem } from "../../../hooks/useGroupedReorder.js"; import { ChecklistSection } from "./ChecklistParts.jsx"; import { TextExchangeActions } from "./TextExchangeActions.jsx"; import { appendChecklistItems, getChecklistReorderItems, isSectionComplete, keepChecklistSection, moveChecklistItem, moveChecklistItemToCategory, renameChecklistSection, updateChecklistItem } from "./checklistUtils.js"; export function ChecklistModule({ toolboxId, moduleId, context, editing, textExchangeOpen }) { const data = context.normalizeChecklistData(context.getModuleData(toolboxId, moduleId, { items: [] })); const textContent = context.moduleText?.checklist || {}; const [label, setLabel] = useState(""); const [sectionTitle, setSectionTitle] = useState(""); const [qty, setQty] = useState(1); const namedSections = data.sections.filter((section) => section.title); const completedSectionsMode = data.hideCompletedSectionsFully ? "hidden" : data.hideCompletedSections ? "reduced" : "visible"; const reorderItems = getChecklistReorderItems(data.sections); const { itemReorder, groupReorder, getItemProps, getGroupProps, getGroupBoundaryProps, isItemDragging, isItemDropTarget, isGroupDragging, isGroupDropTarget, isBoundaryDropTarget, getDropPlacement, shouldShowGroupBoundaries } = useGroupedReorder({ namespace: `checklist-${moduleId}`, items: reorderItems, getItemId: (item) => item.id, getItemGroup: (item) => item.sectionId, getEffectiveGroup: (item) => item.sectionId, reorderFeatures: { item: { groupChange: true, boundaryDrop: true }, group: { reorder: true, boundaryDrop: true } }, onItemMove: (operation) => save(moveChecklistItem(data.sections, operation, context)), onGroupMove: (operation) => save(moveItem(data.sections, operation.sourceId, operation.targetId, operation.placement)) }); const reorder = { itemReorder, groupReorder, getItemProps, getGroupProps, getGroupBoundaryProps, isItemDragging, isItemDropTarget, isGroupDragging, isGroupDropTarget, isBoundaryDropTarget, getDropPlacement, shouldShowGroupBoundaries }; const showBoundaryDropZones = reorder.shouldShowGroupBoundaries(); const visibleSections = data.sections.filter((section) => !(section.title && data.hideCompletedSectionsFully && isSectionComplete(section, context))); function save(sections, settings = {}) { context.setModuleData(toolboxId, moduleId, { ...data, ...settings, sections }); } function addItem(event) { event.preventDefault(); const cleanLabel = label.trim(); if (!cleanLabel) return; const nextItem = { id: context.uid("item"), label: cleanLabel, qtyTarget: Math.max(1, Number(qty) || 1), qtyCurrent: 0 }; save(appendChecklistItems(data.sections, sectionTitle, [nextItem], context)); setLabel(""); setQty(1); } function setCompletedSectionsMode(mode) { save(data.sections.map((section) => ({ ...section, hideWhenComplete: undefined })), { hideCompletedSections: mode === "reduced", hideCompletedSectionsFully: mode === "hidden" }); } function updateSection(sectionId, updater) { save(data.sections.map((section) => section.id === sectionId ? updater(section) : section).filter(keepChecklistSection)); } function renameSection(sectionId, title) { save(renameChecklistSection(data.sections, sectionId, title)); } function updateItem(itemId, updater) { save(updateChecklistItem(data.sections, itemId, updater)); } function moveItemToCategory(itemId, title) { save(moveChecklistItemToCategory(data.sections, itemId, title, context)); } function deleteItem(itemId) { save(data.sections.map((section) => ({ ...section, items: section.items.filter((item) => item.id !== itemId) })).filter(keepChecklistSection)); } return ( <> {editing && (