From 3215efffa323a7325f22c4dad8c72ebead9030c6 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Thu, 1 Oct 2020 15:05:30 +1000 Subject: [PATCH] Added map group support --- src/components/map/MapTiles.js | 71 ++++++++++++------ src/contexts/MapDataContext.js | 1 + src/database.js | 15 +++- src/icons/GroupIcon.js | 18 +++++ src/modals/EditGroupModal.js | 65 ++++++++++++++++ src/modals/SelectMapModal.js | 132 +++++++++++++++++++++++++++------ 6 files changed, 252 insertions(+), 50 deletions(-) create mode 100644 src/icons/GroupIcon.js create mode 100644 src/modals/EditGroupModal.js diff --git a/src/components/map/MapTiles.js b/src/components/map/MapTiles.js index 0b18ee8..2abfb75 100644 --- a/src/components/map/MapTiles.js +++ b/src/components/map/MapTiles.js @@ -1,13 +1,15 @@ import React, { useContext } from "react"; -import { Flex, Box, Text, IconButton, Close } from "theme-ui"; +import { Flex, Box, Text, IconButton, Close, Label } from "theme-ui"; import SimpleBar from "simplebar-react"; import { useMedia } from "react-media"; +import Case from "case"; import AddIcon from "../../icons/AddIcon"; import RemoveMapIcon from "../../icons/RemoveMapIcon"; import ResetMapIcon from "../../icons/ResetMapIcon"; import SelectMultipleIcon from "../../icons/SelectMultipleIcon"; import SelectSingleIcon from "../../icons/SelectSingleIcon"; +import GroupIcon from "../../icons/GroupIcon"; import RadioIconButton from "./controls/RadioIconButton"; @@ -19,6 +21,7 @@ import DatabaseContext from "../../contexts/DatabaseContext"; function MapTiles({ maps, + groups, selectedMaps, selectedMapStates, onMapSelect, @@ -31,6 +34,7 @@ function MapTiles({ onSelectModeChange, search, onSearchChange, + onMapsGroup, }) { const { databaseStatus } = useContext(DatabaseContext); const isSmallScreen = useMedia({ query: "(max-width: 500px)" }); @@ -55,6 +59,26 @@ function MapTiles({ } } + function mapToTile(map) { + const isSelected = selectedMaps.includes(map); + return ( + + ); + } + + const multipleSelected = selectedMaps.length > 1; + return ( onMapSelect()} > - {maps.map((map) => { - const isSelected = selectedMaps.includes(map); - return ( - - ); - })} + {/* Render ungrouped maps, grouped maps then default maps */} + {groups.map((group) => ( + + + {maps[group].map(mapToTile)} + + ))} {databaseStatus === "disabled" && ( @@ -176,16 +191,24 @@ function MapTiles({ /> onMapsGroup()} + disabled={hasSelectedDefaultMap} + > + + + onMapsReset()} disabled={!hasMapState} > onMapsRemove()} disabled={hasSelectedDefaultMap} > diff --git a/src/contexts/MapDataContext.js b/src/contexts/MapDataContext.js index 9576dfe..fe25424 100644 --- a/src/contexts/MapDataContext.js +++ b/src/contexts/MapDataContext.js @@ -48,6 +48,7 @@ export function MapDataProvider({ children }) { gridType: "grid", showGrid: false, snapToGrid: true, + group: "default", }); // Add a state for the map if there isn't one already const state = await database.table("states").get(id); diff --git a/src/database.js b/src/database.js index 26d82ce..91be7af 100644 --- a/src/database.js +++ b/src/database.js @@ -187,7 +187,7 @@ function loadVersions(db) { // v1.5.2 - Added automatic cache invalidation to maps db.version(11) .stores({}) - .upgrade(async (tx) => { + .upgrade((tx) => { return tx .table("maps") .toCollection() @@ -198,7 +198,7 @@ function loadVersions(db) { // v1.5.2 - Added automatic cache invalidation to tokens db.version(12) .stores({}) - .upgrade(async (tx) => { + .upgrade((tx) => { return tx .table("tokens") .toCollection() @@ -206,6 +206,17 @@ function loadVersions(db) { token.lastUsed = token.lastModified; }); }); + // v1.6.0 - Added map grouping + db.version(13) + .stores({}) + .upgrade((tx) => { + return tx + .table("maps") + .toCollection() + .modify((map) => { + map.group = ""; + }); + }); } // Get the dexie database used in DatabaseContext diff --git a/src/icons/GroupIcon.js b/src/icons/GroupIcon.js new file mode 100644 index 0000000..1285cfb --- /dev/null +++ b/src/icons/GroupIcon.js @@ -0,0 +1,18 @@ +import React from "react"; + +function GroupIcon() { + return ( + + + + + ); +} + +export default GroupIcon; diff --git a/src/modals/EditGroupModal.js b/src/modals/EditGroupModal.js new file mode 100644 index 0000000..a990bd0 --- /dev/null +++ b/src/modals/EditGroupModal.js @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from "react"; +import { Box, Button, Label, Flex } from "theme-ui"; + +import Modal from "../components/Modal"; +import Select from "../components/Select"; + +function EditGroupModal({ + isOpen, + onRequestClose, + onChange, + groups, + defaultGroup, +}) { + const [value, setValue] = useState(); + const [options, setOptions] = useState([]); + + useEffect(() => { + if (defaultGroup) { + setValue({ value: defaultGroup, label: defaultGroup }); + } else { + setValue(); + } + }, [defaultGroup]); + + useEffect(() => { + setOptions(groups.map((group) => ({ value: group, label: group }))); + }, [groups]); + + function handleCreate(group) { + const newOption = { value: group, label: group }; + setValue(newOption); + setOptions((prev) => [...prev, newOption]); + } + + function handleChange() { + onChange(value ? value.value : ""); + } + + return ( + + + +