diff --git a/src/modals/ImportExportModal.js b/src/modals/ImportExportModal.js index ad87311..1891895 100644 --- a/src/modals/ImportExportModal.js +++ b/src/modals/ImportExportModal.js @@ -11,7 +11,7 @@ import Banner from "../components/Banner"; import { useAuth } from "../contexts/AuthContext"; -import DataSelectorModal from "./DataSelectorModal"; +import SelectDataModal from "./SelectDataModal"; import { getDatabase } from "../database"; @@ -156,6 +156,10 @@ function ImportExportModal({ isOpen, onRequestClose }) { return true; } } + // Allow all states so tokens can be checked against maps + if (table === "states") { + return true; + } return false; } @@ -241,7 +245,7 @@ function ImportExportModal({ isOpen, onRequestClose }) { - - { loadedMaps[map.id] = { name: map.name, id: map.id, checked: true }; }); + await db + .table("states") + .filter((state) => filter("states", state, state.mapId)) + .each((state) => { + loadedTokensByMap[state.mapId] = new Set( + Object.values(state.tokens).map( + (tokenState) => tokenState.tokenId + ) + ); + }); + await db .table("tokens") .filter((token) => filter("tokens", token, token.id)) @@ -48,6 +61,7 @@ function DataSelectorModal({ }); db.close(); setMaps(loadedMaps); + setTokensByMap(loadedTokensByMap); setTokens(loadedTokens); setIsLoading(false); } else { @@ -58,6 +72,34 @@ function DataSelectorModal({ loadData(); }, [isOpen, databaseName, filter]); + // An object mapping a tokenId to how many checked maps it is currently used in + const [tokenUsedCount, setTokenUsedCount] = useState({}); + useEffect(() => { + let tokensUsed = {}; + for (let mapId in maps) { + if (maps[mapId].checked && mapId in tokensByMap) { + for (let tokenId of tokensByMap[mapId]) { + if (tokenId in tokensUsed) { + tokensUsed[tokenId] += 1; + } else { + tokensUsed[tokenId] = 1; + } + } + } + } + setTokenUsedCount(tokensUsed); + // Update tokens to ensure used tokens are checked + setTokens((prevTokens) => { + let newTokens = { ...prevTokens }; + for (let id in newTokens) { + if (id in tokensUsed) { + newTokens[id].checked = true; + } + } + return newTokens; + }); + }, [maps, tokensByMap]); + function handleConfirm() { let checkedMaps = Object.values(maps).filter((map) => map.checked); let checkedTokens = Object.values(tokens).filter((token) => token.checked); @@ -140,13 +182,15 @@ function DataSelectorModal({ {Object.values(tokens).map((token) => ( - + + + {token.id in tokenUsedCount && ( + + Token used in {tokenUsedCount[token.id]} selected map + {tokenUsedCount[token.id] > 1 && "s"} + + )} + ))} )} @@ -200,11 +248,11 @@ function DataSelectorModal({ ); } -DataSelectorModal.defaultProps = { +SelectDataModal.defaultProps = { label: "Select data", confirmText: "Yes", filter: () => true, databaseName: "OwlbearRodeoDB", }; -export default DataSelectorModal; +export default SelectDataModal;