sokko-g/website/src/features/toolboxes/modules/CombosModule.jsx
Shinuwa 808610dcf2
All checks were successful
Deploy Sokko G / deploy (push) Successful in 18s
Add planner-aware memos and unified tool configuration panels
2026-10-03 15:58:33 +02:00

109 lines
4.7 KiB
JavaScript

// Rôle : fournit l'outil Combos avec palettes d'inputs, rendu visuel et échange texte.
import { toggleListValue } from "../../../utils/collectionUtils.js";
import { getGroupedEntries } from "../../../hooks/useGroupedReorder.js";
import { ModuleTextExchangeConfiguration } from "./ModuleConfiguration.jsx";
import { CombosEditor } from "./CombosEditor.jsx";
import { CombosList } from "./CombosList.jsx";
import {
getComboCategory
} from "./combosUtils.js";
import { useCombosEditorState } from "./useCombosEditorState.js";
import { useCombosReorder } from "./useCombosReorder.js";
export function CombosModule({ toolboxId, moduleId, context, editing, configurationTarget }) {
const data = context.normalizeCombosData(context.getModuleData(toolboxId, moduleId, { combos: [] }));
const textContent = context.moduleText?.combos || {};
const categoryOptions = [
...data.categoryOrder,
...data.combos.map(getComboCategory).filter(Boolean).filter((category) => !data.categoryOrder.includes(category))
];
const entries = getGroupedEntries(data.combos, {
groupOrder: data.categoryOrder,
getItemGroup: getComboCategory,
groupIdKey: "category",
groupItemKey: "combos"
});
function save(nextData) {
context.setModuleData(toolboxId, moduleId, nextData, "combos");
}
const editorState = useCombosEditorState({ data, context, textContent, save });
const reorder = useCombosReorder({ data, moduleId, save });
function updateCombo(comboId, updater) {
save({ ...data, combos: data.combos.map((combo) => combo.id === comboId ? updater(combo) : combo).filter((combo) => combo.name || combo.inputs.length) });
}
function deleteCombo(comboId) {
updateCombo(comboId, () => ({ name: "", inputs: [] }));
if (editorState.editingComboId === comboId) editorState.cancelComboEdit();
}
function toggleCategoryCollapsed(category) {
const collapsedCategories = toggleListValue(data.collapsedCategories, category);
save({ ...data, collapsedCategories });
}
return (
<div className="combos-module">
{(editing || editorState.editingComboId) && (
<CombosEditor
data={data}
textContent={textContent}
categoryOptions={categoryOptions}
comboCategory={editorState.comboCategory}
comboName={editorState.comboName}
customKey={editorState.customKey}
keyboardLayout={editorState.keyboardLayout}
paletteColumns={editorState.paletteColumns}
draftInputs={editorState.draftInputs}
cleanDraftInputs={editorState.cleanDraftInputs}
activeStepIndex={editorState.activeStepIndex}
selectedInput={editorState.selectedInput}
selectedDraftInput={editorState.selectedDraftInput}
simultaneousMode={editorState.simultaneousMode}
editingComboId={editorState.editingComboId}
onDeviceChange={editorState.updateDevice}
onKeyboardLayoutChange={editorState.setKeyboardLayout}
onComboCategoryChange={editorState.setComboCategory}
onComboNameChange={editorState.setComboName}
onCustomKeyChange={editorState.setCustomKey}
onCustomKeyAdd={editorState.addCustomKey}
onComboSave={editorState.saveCombo}
onDraftInputAdd={editorState.addDraftInput}
onPaletteInputDrag={editorState.dragPaletteInput}
onDraftInputDrag={editorState.dragDraftInput}
onInputDrop={editorState.dropInputOnStep}
onNewStepDrop={editorState.dropInputAsNewStep}
onStepSelect={editorState.selectDraftStep}
onInputSelect={editorState.selectDraftInput}
onSelectedInputHoldToggle={editorState.toggleSelectedInputHold}
onSelectedInputHoldChange={editorState.updateSelectedInputHold}
onSimultaneousModeToggle={editorState.toggleSimultaneousMode}
onLastInputRemove={editorState.removeLastInput}
onActiveStepRemove={editorState.removeActiveStep}
onComboEditCancel={editorState.cancelComboEdit}
/>
)}
<ModuleTextExchangeConfiguration target={configurationTarget} title={context.moduleConfigurationText?.dataTitle} type="combos" data={data} context={context} textContent={textContent} onImport={(nextData) => save(nextData)} />
{!data.combos.length && (
<p className="empty-state">{textContent.emptyCombos || "Aucun combo enregistré."}</p>
)}
<CombosList
entries={entries}
data={data}
textContent={textContent}
reorder={{
...reorder
}}
onComboUpdate={updateCombo}
onComboEdit={editorState.startComboEdit}
onComboDelete={deleteCombo}
onCategoryToggle={toggleCategoryCollapsed}
/>
</div>
);
}