diff --git a/src/modals/SelectDataModal.js b/src/modals/SelectDataModal.js
index 5cd94ff..e0dd3fa 100644
--- a/src/modals/SelectDataModal.js
+++ b/src/modals/SelectDataModal.js
@@ -1,9 +1,10 @@
import React, { useEffect, useState } from "react";
-import { Box, Label, Flex, Button, Text, Checkbox, Divider } from "theme-ui";
+import { Box, Label, Flex, Button, Text, Checkbox } from "theme-ui";
import SimpleBar from "simplebar-react";
import Modal from "../components/Modal";
import LoadingOverlay from "../components/LoadingOverlay";
+import Divider from "../components/Divider";
import { getDatabase } from "../database";
@@ -17,8 +18,10 @@ function SelectDataModal({
filter,
}) {
const [maps, setMaps] = useState({});
+ const [mapGroups, setMapGroups] = useState([]);
const [tokensByMap, setTokensByMap] = useState({});
const [tokens, setTokens] = useState({});
+ const [tokenGroups, setTokenGroups] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const hasMaps = Object.values(maps).length > 0;
@@ -36,7 +39,12 @@ function SelectDataModal({
.table("maps")
.filter((map) => filter("maps", map, map.id))
.each((map) => {
- loadedMaps[map.id] = { name: map.name, id: map.id, checked: true };
+ loadedMaps[map.id] = {
+ name: map.name,
+ id: map.id,
+ type: map.type,
+ checked: true,
+ };
});
await db
.table("states")
@@ -56,17 +64,27 @@ function SelectDataModal({
loadedTokens[token.id] = {
name: token.name,
id: token.id,
+ type: token.type,
checked: true,
};
});
+
+ const mapGroup = await db.table("groups").get("maps");
+ const tokenGroup = await db.table("groups").get("tokens");
+
db.close();
setMaps(loadedMaps);
+ setMapGroups(mapGroup.items);
setTokensByMap(loadedTokensByMap);
+ setTokenGroups(tokenGroup.items);
setTokens(loadedTokens);
setIsLoading(false);
} else {
setMaps({});
setTokens({});
+ setTokenGroups([]);
+ setMapGroups([]);
+ setTokensByMap({});
}
}
loadData();
@@ -92,7 +110,7 @@ function SelectDataModal({
setTokens((prevTokens) => {
let newTokens = { ...prevTokens };
for (let id in newTokens) {
- if (id in tokensUsed) {
+ if (id in tokensUsed && newTokens[id].type !== "default") {
newTokens[id].checked = true;
}
}
@@ -106,11 +124,11 @@ function SelectDataModal({
onConfirm(checkedMaps, checkedTokens);
}
- function handleSelectMapsChanged(event) {
+ function handleMapsChanged(event, maps) {
setMaps((prevMaps) => {
let newMaps = { ...prevMaps };
- for (let id in newMaps) {
- newMaps[id].checked = event.target.checked;
+ for (let map of maps) {
+ newMaps[map.id].checked = event.target.checked;
}
return newMaps;
});
@@ -118,26 +136,17 @@ function SelectDataModal({
if (!event.target.checked && !tokensSelectChecked) {
setTokens((prevTokens) => {
let newTokens = { ...prevTokens };
+ let tempUsedCount = { ...tokenUsedCount };
for (let id in newTokens) {
- newTokens[id].checked = false;
- }
- return newTokens;
- });
- }
- }
-
- function handleMapChange(event, map) {
- setMaps((prevMaps) => ({
- ...prevMaps,
- [map.id]: { ...map, checked: event.target.checked },
- }));
- // If all token select is unchecked then ensure tokens assosiated to this map are unchecked
- if (!event.target.checked && !tokensSelectChecked) {
- setTokens((prevTokens) => {
- let newTokens = { ...prevTokens };
- for (let id in newTokens) {
- if (tokensByMap[map.id].has(id) && tokenUsedCount[id] === 1) {
- newTokens[id].checked = false;
+ for (let map of maps) {
+ if (tokensByMap[map.id].has(id)) {
+ if (tempUsedCount[id] > 1) {
+ tempUsedCount[id] -= 1;
+ } else if (tempUsedCount[id] === 1) {
+ tempUsedCount[id] = 0;
+ newTokens[id].checked = false;
+ }
+ }
}
}
return newTokens;
@@ -145,31 +154,126 @@ function SelectDataModal({
}
}
- function handleSelectTokensChange(event) {
+ function handleTokensChanged(event, tokens) {
setTokens((prevTokens) => {
let newTokens = { ...prevTokens };
- for (let id in newTokens) {
- if (!(id in tokenUsedCount)) {
- newTokens[id].checked = event.target.checked;
+ for (let token of tokens) {
+ if (!(token.id in tokenUsedCount) || token.type === "default") {
+ newTokens[token.id].checked = event.target.checked;
}
}
return newTokens;
});
}
- function handleTokenChange(event, token) {
- setTokens((prevTokens) => ({
- ...prevTokens,
- [token.id]: { ...token, checked: event.target.checked },
- }));
- }
-
// Some tokens are checked not by maps or all tokens are checked by maps
const tokensSelectChecked =
Object.values(tokens).some(
(token) => !(token.id in tokenUsedCount) && token.checked
) || Object.values(tokens).every((token) => token.id in tokenUsedCount);
+ function renderGroupContainer(group, checked, renderItem, onGroupChange) {
+ return (
+
+
+
+ {group.items.map(renderItem)}
+
+
+
+
+
+ );
+ }
+
+ function renderMapGroup(group) {
+ if (group.type === "item") {
+ const map = maps[group.id];
+ return (
+
+ );
+ } else {
+ return renderGroupContainer(
+ group,
+ group.items.some((item) => maps[item.id].checked),
+ renderMapGroup,
+ (e, group) =>
+ handleMapsChanged(
+ e,
+ group.items.map((group) => maps[group.id])
+ )
+ );
+ }
+ }
+
+ function renderTokenGroup(group) {
+ if (group.type === "item") {
+ const token = tokens[group.id];
+ return (
+
+
+ {token.id in tokenUsedCount && token.type !== "default" && (
+
+ Token used in {tokenUsedCount[token.id]} selected map
+ {tokenUsedCount[token.id] > 1 && "s"}
+
+ )}
+
+ );
+ } else {
+ const checked =
+ group.items.some(
+ (item) => !(item.id in tokenUsedCount) && tokens[item.id].checked
+ ) || group.items.every((item) => item.id in tokenUsedCount);
+ return renderGroupContainer(
+ group,
+ checked,
+ renderTokenGroup,
+ (e, group) =>
+ handleTokensChanged(
+ e,
+ group.items.map((group) => tokens[group.id])
+ )
+ );
+ }
+ }
+
return (
map.checked)}
- onChange={handleSelectMapsChanged}
+ onChange={(e) =>
+ handleMapsChanged(e, Object.values(maps))
+ }
/>
Maps
- {Object.values(maps).map((map) => (
-
- ))}
+ {mapGroups.map(renderMapGroup)}
>
)}
- {hasMaps && hasTokens && }
+ {hasMaps && hasTokens && }
{hasTokens && (
<>
- {Object.values(tokens).map((token) => (
-
-
- {token.id in tokenUsedCount && (
-
- Token used in {tokenUsedCount[token.id]} selected map
- {tokenUsedCount[token.id] > 1 && "s"}
-
- )}
-
- ))}
+ {tokenGroups.map(renderTokenGroup)}
>
)}