Skip to content

Commit 7eb66be

Browse files
authored
Merge pull request #108 from badgerloop-software/user/beckw/graph-select-all-checkbox
User/beckw/graph select all checkbox Added subcategory checkboxes
2 parents 4046dcd + 4a44fc3 commit 7eb66be

1 file changed

Lines changed: 74 additions & 26 deletions

File tree

Frontend/src/Components/Graph/GraphSelectModal.js

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,34 @@ import {
1616
SliderThumb,
1717
SliderTrack,
1818
VStack,
19-
useColorMode
19+
useColorMode,
2020
} from "@chakra-ui/react";
2121
import { useState } from "react";
2222
import { useReducer } from "react";
2323
import GraphData from "./graph-data.json";
2424
import Expandable from "./ExpandableContent";
25-
import getColor from "../Shared/colors"
25+
import getColor from "../Shared/colors";
2626

2727
/**
2828
* The reducer for the dataKeys state variable
2929
*
3030
* @param {string[]} state the previous list of selected data keys
31-
* @param {{action: string, key: string}}} new the action to perform and the key to add or remove
31+
* @param {{action: string, key: string, keys: string[]}}} new the action to perform and the key to add or remove
3232
* @returns the new state (or list of selected data keys)
3333
*/
34-
const dataKeysReducer = (state, { action, key }) => {
34+
const dataKeysReducer = (state, { action, key, keys }) => {
3535
switch (action) {
3636
case "add":
3737
return state.concat([key]);
3838
case "remove":
3939
const index = state.indexOf(key);
4040
return state.slice(0, index).concat(state.slice(index + 1));
41+
//subcategory actions: adds or removes an entire subcategory of keys
42+
case "addSubcategory":
43+
return [...new Set([...state, ...keys])];
44+
case "removeSubcategory":
45+
return state.filter((k) => !keys.includes(k));
46+
4147
default:
4248
console.warn("DEFAULT CASE REACHED IN GRAPH MODAL");
4349
return [];
@@ -79,8 +85,8 @@ function GraphSelectModal(props) {
7985
const { isOpen, onClose, initialDatasets, initialHistoryLength, onSave } =
8086
props;
8187

82-
const {colorMode} = useColorMode()
83-
const contentBg = getColor('contentBg', colorMode);
88+
const { colorMode } = useColorMode();
89+
const contentBg = getColor("contentBg", colorMode);
8490

8591
// a state variable that keeps track of which datasets are selected to be shown
8692
const [dataKeys, changeDataKeys] = useReducer(
@@ -98,36 +104,78 @@ function GraphSelectModal(props) {
98104
<ModalCloseButton />
99105
<ModalBody>
100106
<VStack align="stretch">
101-
<hr/>
107+
<hr />
102108
{GraphData.Output.map((category) => (
103109
<VStack align="stretch" key={category.category}>
104-
<Expandable label={category.category} contentBg={contentBg} size="md">
105-
{category.subcategories.map((subcategory) => (
106-
<VStack align="strech" key={subcategory.subcategory}>
107-
<Heading pt="2" size="sm">{subcategory.subcategory}</Heading>
108-
<SimpleGrid columns={2}>
109-
{subcategory.values.map((value) => (
110+
<Expandable
111+
label={category.category}
112+
contentBg={contentBg}
113+
size="md"
114+
>
115+
{category.subcategories.map((subcategory) => {
116+
//Find keys for this subcategory.
117+
const childKeys = subcategory.values.map(
118+
(value) => value.key
119+
);
120+
//Check if all child checkboxes are selected.
121+
const allSelected = childKeys.every((key) =>
122+
dataKeys.includes(key)
123+
);
124+
// Check if some (but not all) child checkboxes are selected.
125+
const someSelected = childKeys.some((key) =>
126+
dataKeys.includes(key)
127+
);
128+
return (
129+
<VStack align="stretch" key={subcategory.subcategory}>
130+
<Heading pt="2" size="sm">
110131
<Checkbox
111-
defaultChecked={dataKeys.includes(value.key)}
112-
onInput={(e) => {
132+
isChecked={allSelected}
133+
isIndeterminate={someSelected && !allSelected}
134+
onChange={(e) => {
113135
if (e.target.checked) {
114-
// checked => add to checked datasets
115-
changeDataKeys({ action: "add", key: value.key });
136+
changeDataKeys({
137+
action: "addSubcategory",
138+
keys: childKeys,
139+
});
116140
} else {
117-
// unchecked => remove from checked datasets
118-
changeDataKeys({ action: "remove", key: value.key });
141+
changeDataKeys({
142+
action: "removeSubcategory",
143+
keys: childKeys,
144+
});
119145
}
120146
}}
121-
key={value.key}
122147
>
123-
{value.name}
148+
{subcategory.subcategory}
124149
</Checkbox>
125-
))}
126-
</SimpleGrid>
127-
</VStack>
128-
))}
150+
</Heading>
151+
<SimpleGrid columns={2}>
152+
{subcategory.values.map((value) => (
153+
<Checkbox
154+
isChecked={dataKeys.includes(value.key)}
155+
onChange={(e) => {
156+
if (e.target.checked) {
157+
changeDataKeys({
158+
action: "add",
159+
key: value.key,
160+
});
161+
} else {
162+
changeDataKeys({
163+
action: "remove",
164+
key: value.key,
165+
});
166+
}
167+
}}
168+
key={value.key}
169+
>
170+
{value.name}
171+
</Checkbox>
172+
))}
173+
</SimpleGrid>
174+
</VStack>
175+
);
176+
})}
129177
</Expandable>
130-
<hr/>
178+
<hr />
131179
</VStack>
132180
))}
133181
<VStack align="stretch" pb={5}>

0 commit comments

Comments
 (0)