playbook_ui 12.26.0.pre.alpha.multiselectfixes798 → 12.26.0.pre.alpha.multiselectfixes821
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +46 -146
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +131 -180
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +61 -727
- data/dist/playbook-rails.js +5 -5
- data/lib/playbook/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3921a5868e63be4fc845ce62bf461e9a529105ca767a7bf08a6e59750afd1a7e
|
4
|
+
data.tar.gz: a8fdd12e4f31427f8bafafd74cadb518e8904c91ddf05dd611b511b3b365d415
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e18e3d7e15956c2847c3fa8584db5696f19e8e82a1614786c8f7af71587d6a44872efc2f0cd10a62d2400a55ae7d1a0300e3f5437712be859f34a3dcdfa314a
|
7
|
+
data.tar.gz: f1778abccb8f3e4006b3c814b29c8c3a90368f5db3eac1b1875ad67d2164e7a2913c4de4e5f8c84078a70cbd104c84e2122c7cac404dad1c63eb37498377764a
|
@@ -1,58 +1,16 @@
|
|
1
|
-
//function for unchecking items in formattedData
|
2
|
-
export const unCheckIt = (
|
3
|
-
formattedData: { [key: string]: any }[],
|
4
|
-
id: string
|
5
|
-
) => {
|
6
|
-
formattedData.map((item: { [key: string]: any }) => {
|
7
|
-
if (item.id === id && item.checked) {
|
8
|
-
item.checked = false;
|
9
|
-
}
|
10
|
-
if (item.children && item.children.length > 0) {
|
11
|
-
unCheckIt(item.children, id);
|
12
|
-
}
|
13
|
-
return item;
|
14
|
-
});
|
15
|
-
};
|
16
|
-
|
17
1
|
//function to retrieve all ancestors of unchecked item and set checked to false
|
18
2
|
export const getAncestorsOfUnchecked = (
|
19
|
-
|
3
|
+
data: { [key: string]: any }[],
|
20
4
|
item: { [key: string]: any }
|
21
5
|
) => {
|
22
6
|
if (item.parent_id) {
|
23
|
-
const
|
24
|
-
|
25
|
-
|
26
|
-
if (ancestors[0].parent_id) {
|
27
|
-
getAncestorsOfUnchecked(formattedData, ancestors[0]);
|
28
|
-
}
|
7
|
+
const ancestor = filterFormattedDataById(data, item.parent_id);
|
8
|
+
ancestor[0].checked = false;
|
9
|
+
ancestor[0].parent_id && getAncestorsOfUnchecked(data, ancestor[0])
|
29
10
|
}
|
11
|
+
return data;
|
30
12
|
};
|
31
|
-
|
32
|
-
//recursively check all child and grandchild items if parent checked
|
33
|
-
export const checkedRecursive = (item: { [key: string]: any }) => {
|
34
|
-
if (!item.checked) {
|
35
|
-
item.checked = true;
|
36
|
-
}
|
37
|
-
if (item.children && item.children.length > 0) {
|
38
|
-
item.children.forEach((childItem: { [key: string]: any }) => {
|
39
|
-
checkedRecursive(childItem);
|
40
|
-
});
|
41
|
-
}
|
42
|
-
};
|
43
|
-
|
44
|
-
//recursively uncheck all child and grandchild items if parent unchecked
|
45
|
-
export const unCheckedRecursive = (item: { [key: string]: any }) => {
|
46
|
-
if (item.checked) {
|
47
|
-
item.checked = false;
|
48
|
-
}
|
49
|
-
if (item.children && item.children.length > 0) {
|
50
|
-
item.children.forEach((childItem: { [key: string]: any }) => {
|
51
|
-
unCheckedRecursive(childItem);
|
52
|
-
});
|
53
|
-
}
|
54
|
-
};
|
55
|
-
|
13
|
+
|
56
14
|
//function is going over formattedData and returning all objects that match the
|
57
15
|
//id of the clicked item from the dropdown
|
58
16
|
export const filterFormattedDataById = (
|
@@ -64,6 +22,7 @@ export const filterFormattedDataById = (
|
|
64
22
|
for (const item of data) {
|
65
23
|
if (item.id.toLowerCase() === (term.toLowerCase())) {
|
66
24
|
matched.push(item);
|
25
|
+
return
|
67
26
|
}
|
68
27
|
|
69
28
|
if (item.children && item.children.length > 0) {
|
@@ -116,116 +75,57 @@ export const getCheckedItems = (
|
|
116
75
|
});
|
117
76
|
return checkedItems;
|
118
77
|
};
|
78
|
+
|
79
|
+
export const getDefaultCheckedItems = (treeData:{ [key: string]: any }[]) => {
|
80
|
+
const checkedDefault: { [key: string]: any }[] = [];
|
81
|
+
|
82
|
+
const traverseTree = (items:{ [key: string]: any }[]) => {
|
83
|
+
items.forEach((item:{ [key: string]: any }) => {
|
84
|
+
if (item.checked) {
|
85
|
+
if (item.children && item.children.length > 0) {
|
86
|
+
const uncheckedChildren = item.children.filter((child:{ [key: string]: any }) => !child.checked);
|
87
|
+
if (uncheckedChildren.length === 0) {
|
88
|
+
checkedDefault.push(item);
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
} else {
|
92
|
+
const parent = items.find((parentItem:{ [key: string]: any }) => parentItem.id === item.parentId);
|
93
|
+
if (!parent || !parent.checked) {
|
94
|
+
checkedDefault.push(item);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
119
98
|
|
120
|
-
|
121
|
-
|
122
|
-
defaultArray: { [key: string]: any }[]
|
123
|
-
) => {
|
124
|
-
let childIds: string[] = [];
|
125
|
-
item.children.forEach((child: { [key: string]: any }) => {
|
126
|
-
childIds.push(child.id);
|
127
|
-
if (child.children && child.children.length > 0) {
|
128
|
-
const childChildIds = getChildIds(child, defaultArray);
|
129
|
-
childIds.push(...childChildIds);
|
130
|
-
}
|
131
|
-
});
|
132
|
-
return childIds;
|
133
|
-
};
|
134
|
-
|
135
|
-
export const updateReturnItems = (newChecked: { [key: string]: any }[]) => {
|
136
|
-
const updatedCheckedItems: { [key: string]: any }[] = [];
|
137
|
-
for (const item of newChecked) {
|
138
|
-
if (item.children && item.children.length > 0) {
|
139
|
-
const allChildrenChecked = item.children.every(
|
140
|
-
(child: { [key: string]: any }) => child.checked
|
141
|
-
);
|
142
|
-
if (allChildrenChecked) {
|
143
|
-
updatedCheckedItems.push(item);
|
99
|
+
if (item.children && item.children.length > 0) {
|
100
|
+
traverseTree(item.children);
|
144
101
|
}
|
145
|
-
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
const filteredReturn = updatedCheckedItems.filter((item) => {
|
152
|
-
return !updatedCheckedItems.find(
|
153
|
-
(otherItem) => otherItem.id === item.parent_id
|
154
|
-
);
|
155
|
-
});
|
156
|
-
return filteredReturn;
|
102
|
+
});
|
103
|
+
};
|
104
|
+
|
105
|
+
traverseTree(treeData);
|
106
|
+
|
107
|
+
return checkedDefault;
|
157
108
|
};
|
158
109
|
|
159
|
-
export const
|
160
|
-
|
161
|
-
|
162
|
-
defaultReturn: { [key: string]: any }[],
|
163
|
-
setDefaultReturn: any
|
110
|
+
export const recursiveCheckParent = (
|
111
|
+
item: { [key: string]: any },
|
112
|
+
data:any
|
164
113
|
) => {
|
165
|
-
|
114
|
+
if (item.parent_id !== null) {
|
115
|
+
const parent = filterFormattedDataById(data, item.parent_id);
|
166
116
|
const allChildrenChecked = parent[0].children.every(
|
167
117
|
(child: { [key: string]: any }) => child.checked
|
168
118
|
);
|
169
119
|
if (allChildrenChecked) {
|
170
|
-
// Only return the parent and remove its children from defaultReturn
|
171
120
|
parent[0].checked = true;
|
172
|
-
const filteredDefaultReturn = defaultReturn.filter((item) => {
|
173
|
-
// Remove children of the specific parent
|
174
|
-
if (
|
175
|
-
parent[0].children.find(
|
176
|
-
(child: { [key: string]: any }) => child.id === item.id
|
177
|
-
)
|
178
|
-
) {
|
179
|
-
return false;
|
180
|
-
}
|
181
|
-
});
|
182
|
-
setDefaultReturn([...filteredDefaultReturn, parent[0]]);
|
183
|
-
// Check if the parent has a parent and its children are all checked
|
184
121
|
const parentHasParent = parent[0].parent_id !== null;
|
185
122
|
if (parentHasParent) {
|
186
|
-
|
123
|
+
recursiveCheckParent(
|
187
124
|
parent[0],
|
188
|
-
|
189
|
-
filteredDefaultReturn,
|
190
|
-
setDefaultReturn
|
125
|
+
data
|
191
126
|
);
|
192
127
|
}
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
const updatedDefaultReturn = [...defaultReturn, ...checkedChildren];
|
198
|
-
setDefaultReturn(updatedDefaultReturn);
|
199
|
-
}
|
200
|
-
};
|
201
|
-
|
202
|
-
export const removeChildrenIfParentChecked = (
|
203
|
-
items: { [key: string]: any },
|
204
|
-
defaultReturn: { [key: string]: any }[],
|
205
|
-
setDefaultReturn: any
|
206
|
-
) => {
|
207
|
-
const childIds = getChildIds(items, defaultReturn);
|
208
|
-
const filteredDefaultArray = defaultReturn.filter(
|
209
|
-
(item: { [key: string]: any }) => childIds !== item.id
|
210
|
-
);
|
211
|
-
setDefaultReturn([...filteredDefaultArray, items]);
|
212
|
-
};
|
213
|
-
|
214
|
-
export const areAllCheckedFalse = (data:any) => {
|
215
|
-
if (!Array.isArray(data)) {
|
216
|
-
return;
|
217
|
-
}
|
218
|
-
for (const item of data) {
|
219
|
-
if (item.checked !== false) {
|
220
|
-
return false; // Return false if any item is not checked: false
|
221
|
-
}
|
222
|
-
|
223
|
-
if (item.children && item.children.length > 0) {
|
224
|
-
if (!areAllCheckedFalse(item.children)) {
|
225
|
-
return false; // Return false if any nested item is not checked: false
|
226
|
-
}
|
227
|
-
}
|
228
|
-
}
|
229
|
-
|
230
|
-
return true; // Return true if all items are checked: false
|
231
|
-
};
|
128
|
+
}
|
129
|
+
}
|
130
|
+
return data;
|
131
|
+
}
|
@@ -6,19 +6,15 @@ import Icon from "../pb_icon/_icon";
|
|
6
6
|
import Checkbox from "../pb_checkbox/_checkbox";
|
7
7
|
import FormPill from "../pb_form_pill/_form_pill";
|
8
8
|
import CircleIconButton from "../pb_circle_icon_button/_circle_icon_button";
|
9
|
+
import { cloneDeep } from "lodash";
|
10
|
+
|
9
11
|
import {
|
10
|
-
unCheckIt,
|
11
12
|
getAncestorsOfUnchecked,
|
12
|
-
unCheckedRecursive,
|
13
|
-
checkedRecursive,
|
14
13
|
filterFormattedDataById,
|
15
14
|
findByFilter,
|
16
15
|
getCheckedItems,
|
17
|
-
|
18
|
-
|
19
|
-
removeChildrenIfParentChecked,
|
20
|
-
getChildIds,
|
21
|
-
areAllCheckedFalse
|
16
|
+
getDefaultCheckedItems,
|
17
|
+
recursiveCheckParent,
|
22
18
|
} from "./_helper_functions";
|
23
19
|
|
24
20
|
type MultiLevelSelectProps = {
|
@@ -52,6 +48,8 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
52
48
|
|
53
49
|
const dropdownRef = useRef(null);
|
54
50
|
|
51
|
+
//state for expanded property
|
52
|
+
const [expanded, setExpanded] = useState([]);
|
55
53
|
//state for whether dropdown is open or closed
|
56
54
|
const [isClosed, setIsClosed] = useState(true);
|
57
55
|
//state from onchange for textinput, to use for filtering to create typeahead
|
@@ -60,64 +58,102 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
60
58
|
const [returnedArray, setReturnedArray] = useState([]);
|
61
59
|
//formattedData with checked and parent_id added
|
62
60
|
const [formattedData, setFormattedData] = useState([]);
|
63
|
-
//toggle chevron in dropdown
|
64
|
-
//@ts-ignore
|
65
|
-
const [isToggled, setIsToggled] = useState<{ [id: number]: boolean }>({});
|
66
61
|
//state for return for default
|
67
62
|
const [defaultReturn, setDefaultReturn] = useState([]);
|
68
63
|
|
69
64
|
useEffect(() => {
|
70
|
-
let el = document.getElementById(`pb_data_wrapper_${id}`);
|
71
|
-
if (el) {
|
72
|
-
el.setAttribute(
|
73
|
-
"data-tree",
|
74
|
-
JSON.stringify(returnAllSelected ? returnedArray : defaultReturn)
|
75
|
-
);
|
76
|
-
}
|
77
|
-
returnAllSelected
|
78
|
-
? onSelect(returnedArray)
|
79
|
-
: onSelect(
|
80
|
-
defaultReturn.filter(
|
81
|
-
(item, index, self) =>
|
82
|
-
index === self.findIndex((obj) => obj.id === item.id)
|
83
|
-
)
|
84
|
-
);
|
85
|
-
}, [returnedArray, defaultReturn]);
|
86
|
-
|
87
|
-
useEffect(() => {
|
88
|
-
console.log("TREEDATA", treeData)
|
89
|
-
//Create new formattedData array for use
|
90
65
|
setFormattedData(addCheckedAndParentProperty(treeData));
|
91
|
-
//if any items already checked in first render, set return accordingly
|
92
|
-
const initialChecked = getCheckedItems(treeData)
|
93
|
-
console.log("INITIAl CHECKED", initialChecked)
|
94
|
-
const initialUnchecked = areAllCheckedFalse(treeData)
|
95
|
-
console.log("INIITAL UNCHECKED", initialUnchecked)
|
96
|
-
initialChecked && returnAllSelected && setReturnedArray(initialChecked)
|
97
|
-
initialChecked && !returnAllSelected && setDefaultReturn(initialChecked)
|
98
|
-
|
99
66
|
}, [treeData]);
|
100
67
|
|
101
|
-
useEffect(()=> {
|
68
|
+
useEffect(() => {
|
69
|
+
if (returnAllSelected) {
|
70
|
+
setReturnedArray(getCheckedItems(formattedData));
|
71
|
+
} else {
|
72
|
+
setDefaultReturn(getDefaultCheckedItems(formattedData));
|
73
|
+
}
|
74
|
+
}, [formattedData]);
|
75
|
+
|
76
|
+
useEffect(() => {
|
102
77
|
// Function to handle clicks outside the dropdown
|
103
78
|
const handleClickOutside = (event: any) => {
|
104
79
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
105
80
|
setIsClosed(true);
|
106
81
|
}
|
107
82
|
};
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
},[])
|
83
|
+
// Attach the event listener
|
84
|
+
window.addEventListener("click", handleClickOutside);
|
85
|
+
// Clean up the event listener on unmount
|
86
|
+
return () => {
|
87
|
+
window.removeEventListener("click", handleClickOutside);
|
88
|
+
};
|
89
|
+
}, []);
|
90
|
+
|
91
|
+
const modifyRecursive = (tree: { [key: string]: any }[], check: boolean) => {
|
92
|
+
if (!Array.isArray(tree)) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
return tree.map((item: { [key: string]: any }) => {
|
96
|
+
item.checked = check;
|
97
|
+
item.children = modifyRecursive(item.children, check);
|
98
|
+
return item;
|
99
|
+
});
|
100
|
+
};
|
101
|
+
|
102
|
+
//iterate over tree, find item and set checked or unchecked
|
103
|
+
const modifyValue = (
|
104
|
+
id: string,
|
105
|
+
tree: { [key: string]: any }[],
|
106
|
+
check: boolean
|
107
|
+
) => {
|
108
|
+
if (!Array.isArray(tree)) {
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
return tree.map((item: any) => {
|
112
|
+
if (item.id != id) item.children = modifyValue(id, item.children, check);
|
113
|
+
else {
|
114
|
+
item.checked = check;
|
115
|
+
item.children = modifyRecursive(item.children, check);
|
116
|
+
}
|
117
|
+
|
118
|
+
return item;
|
119
|
+
});
|
120
|
+
};
|
121
|
+
|
122
|
+
//clone tree, check items + children
|
123
|
+
const checkItem = (item: { [key: string]: any }) => {
|
124
|
+
const tree = cloneDeep(formattedData);
|
125
|
+
if (returnAllSelected) {
|
126
|
+
return modifyValue(item.id, tree, true);
|
127
|
+
} else {
|
128
|
+
const checkedTree = modifyValue(item.id, tree, true);
|
129
|
+
return recursiveCheckParent(item, checkedTree);
|
130
|
+
}
|
131
|
+
};
|
132
|
+
|
133
|
+
//clone tree, uncheck items + children
|
134
|
+
const unCheckItem = (item: { [key: string]: any }) => {
|
135
|
+
const tree = cloneDeep(formattedData);
|
136
|
+
if (returnAllSelected) {
|
137
|
+
return modifyValue(item.id, tree, false);
|
138
|
+
} else {
|
139
|
+
const uncheckedTree = modifyValue(item.id, tree, false);
|
140
|
+
return getAncestorsOfUnchecked(uncheckedTree, item);
|
141
|
+
}
|
142
|
+
};
|
143
|
+
|
144
|
+
//setformattedData with proper properties
|
145
|
+
const changeItem = (item: { [key: string]: any }, check: boolean) => {
|
146
|
+
const tree = check ? checkItem(item) : unCheckItem(item);
|
147
|
+
setFormattedData(tree);
|
148
|
+
|
149
|
+
return tree;
|
150
|
+
};
|
115
151
|
|
116
152
|
//function to map over data and add parent_id + depth property to each item
|
117
153
|
const addCheckedAndParentProperty = (
|
118
154
|
treeData: { [key: string]: any }[],
|
119
155
|
parent_id: string = null,
|
120
|
-
depth: number = 0
|
156
|
+
depth: number = 0
|
121
157
|
) => {
|
122
158
|
if (!Array.isArray(treeData)) {
|
123
159
|
return;
|
@@ -129,10 +165,14 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
129
165
|
depth,
|
130
166
|
};
|
131
167
|
if (newItem.children && newItem.children.length > 0) {
|
168
|
+
const children =
|
169
|
+
item.checked && !returnAllSelected
|
170
|
+
? modifyRecursive(item.children, true)
|
171
|
+
: item.children;
|
132
172
|
newItem.children = addCheckedAndParentProperty(
|
133
|
-
|
173
|
+
children,
|
134
174
|
newItem.id,
|
135
|
-
depth + 1
|
175
|
+
depth + 1
|
136
176
|
);
|
137
177
|
}
|
138
178
|
return newItem;
|
@@ -143,37 +183,13 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
143
183
|
const handlePillClose = (event: any, clickedItem: { [key: string]: any }) => {
|
144
184
|
// prevents the dropdown from closing when clicking on the pill
|
145
185
|
event.stopPropagation();
|
186
|
+
const updatedTree = changeItem(clickedItem, false);
|
146
187
|
//logic for removing items from returnArray or defaultReturn when pills clicked
|
147
188
|
if (returnAllSelected) {
|
148
|
-
|
149
|
-
if (clickedItem.children && clickedItem.children.length > 0) {
|
150
|
-
const childrenOfChecked = getChildIds(clickedItem, returnedArray);
|
151
|
-
const updatedFiltered = returnedArray
|
152
|
-
.filter((item) => item !== clickedItem)
|
153
|
-
.filter((item) => !childrenOfChecked.includes(item.id));
|
154
|
-
setReturnedArray(updatedFiltered);
|
155
|
-
} else {
|
156
|
-
const updatedFiltered = returnedArray.filter(
|
157
|
-
(item) => item !== clickedItem
|
158
|
-
);
|
159
|
-
setReturnedArray(updatedFiltered);
|
160
|
-
}
|
161
|
-
}
|
189
|
+
onSelect(getCheckedItems(updatedTree));
|
162
190
|
} else {
|
163
|
-
|
164
|
-
getAncestorsOfUnchecked(formattedData, clickedItem);
|
165
|
-
const newChecked = getCheckedItems(formattedData);
|
166
|
-
const filteredReturn = updateReturnItems(newChecked).filter(
|
167
|
-
(item) => item.id !== clickedItem.id
|
168
|
-
);
|
169
|
-
setDefaultReturn(filteredReturn);
|
170
|
-
}
|
171
|
-
}
|
172
|
-
if (clickedItem.children && clickedItem.children.length > 0) {
|
173
|
-
unCheckedRecursive(clickedItem);
|
191
|
+
onSelect(getDefaultCheckedItems(updatedTree));
|
174
192
|
}
|
175
|
-
//logic to uncheck clickedItem in formattedData
|
176
|
-
unCheckIt(formattedData, clickedItem.id);
|
177
193
|
};
|
178
194
|
|
179
195
|
//handle click on input wrapper(entire div with pills, typeahead, etc) so it doesn't close when input or form pill is clicked
|
@@ -189,95 +205,36 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
189
205
|
};
|
190
206
|
|
191
207
|
//Main function to handle any click inside dropdown
|
192
|
-
const handledropdownItemClick = (e: any) => {
|
208
|
+
const handledropdownItemClick = (e: any, check: boolean) => {
|
193
209
|
const clickedItem = e.target.parentNode.id;
|
194
210
|
//setting filterItem to "" will clear textinput and clear typeahead
|
195
211
|
setFilterItem("");
|
196
212
|
|
197
213
|
const filtered = filterFormattedDataById(formattedData, clickedItem);
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
checkedRecursive(item);
|
203
|
-
});
|
204
|
-
} else if (!filtered[0].checked) {
|
205
|
-
filtered[0].children.forEach((item: { [key: string]: any }) => {
|
206
|
-
unCheckedRecursive(item);
|
207
|
-
});
|
208
|
-
}
|
209
|
-
}
|
210
|
-
|
211
|
-
const checkedItems = getCheckedItems(formattedData);
|
212
|
-
|
213
|
-
//checking and unchecking items for returnAllSelected variant
|
214
|
-
if (returnedArray.includes(filtered[0])) {
|
215
|
-
if (!filtered[0].checked) {
|
216
|
-
if (filtered[0].children && filtered[0].children.length > 0) {
|
217
|
-
const childrenOfChecked = getChildIds(filtered[0], returnedArray);
|
218
|
-
const updatedFiltered = returnedArray
|
219
|
-
.filter((item) => item !== filtered[0])
|
220
|
-
.filter((item) => !childrenOfChecked.includes(item.id));
|
221
|
-
|
222
|
-
setReturnedArray(updatedFiltered);
|
223
|
-
} else {
|
224
|
-
const updatedFiltered = returnedArray.filter(
|
225
|
-
(item) => item !== filtered[0]
|
226
|
-
);
|
227
|
-
setReturnedArray(updatedFiltered);
|
228
|
-
}
|
229
|
-
}
|
214
|
+
const updatedTree = changeItem(filtered[0], check);
|
215
|
+
console.log(updatedTree);
|
216
|
+
if (returnAllSelected) {
|
217
|
+
onSelect(getCheckedItems(updatedTree));
|
230
218
|
} else {
|
231
|
-
|
232
|
-
}
|
233
|
-
|
234
|
-
//when item is unchecked for default variant
|
235
|
-
if (!filtered[0].checked && !returnAllSelected) {
|
236
|
-
//uncheck parent and grandparent if any child unchecked
|
237
|
-
getAncestorsOfUnchecked(formattedData, filtered[0]);
|
238
|
-
|
239
|
-
const newChecked = getCheckedItems(formattedData);
|
240
|
-
//get all checked items, and filter to check if all children checked, if yes return only parent
|
241
|
-
const filteredReturn = updateReturnItems(newChecked);
|
242
|
-
setDefaultReturn(filteredReturn);
|
243
|
-
}
|
244
|
-
|
245
|
-
//when item is checked for default variant
|
246
|
-
if (!returnAllSelected && filtered[0].checked) {
|
247
|
-
//if checked item has children
|
248
|
-
if (filtered[0].children && filtered[0].children.length > 0) {
|
249
|
-
removeChildrenIfParentChecked(
|
250
|
-
filtered[0],
|
251
|
-
defaultReturn,
|
252
|
-
setDefaultReturn
|
253
|
-
);
|
254
|
-
}
|
255
|
-
|
256
|
-
//if clicked item has parent_id, find parent and check if all children checked or not
|
257
|
-
if (filtered[0].parent_id !== null) {
|
258
|
-
recursiveReturnOnlyParent(
|
259
|
-
filtered[0],
|
260
|
-
formattedData,
|
261
|
-
defaultReturn,
|
262
|
-
setDefaultReturn
|
263
|
-
);
|
264
|
-
} else {
|
265
|
-
setDefaultReturn([filtered[0]]);
|
266
|
-
}
|
219
|
+
onSelect(getDefaultCheckedItems(updatedTree));
|
267
220
|
}
|
268
221
|
};
|
269
222
|
|
223
|
+
const isExpanded = (item: any) => expanded.indexOf(item.id) > -1;
|
224
|
+
|
270
225
|
//handle click on chevron toggles in dropdown
|
271
226
|
const handleToggleClick = (id: string, event: React.MouseEvent) => {
|
272
227
|
event.stopPropagation();
|
273
|
-
setIsToggled((prevState: { [id: string]: boolean }) => ({
|
274
|
-
...prevState,
|
275
|
-
[id]: !prevState[id],
|
276
|
-
}));
|
277
228
|
const clickedItem = filterFormattedDataById(formattedData, id);
|
278
|
-
|
279
229
|
if (clickedItem) {
|
280
|
-
|
230
|
+
let expandedArray = [...expanded];
|
231
|
+
const itemExpanded = isExpanded(clickedItem[0]);
|
232
|
+
|
233
|
+
if (itemExpanded)
|
234
|
+
expandedArray = expandedArray.filter((i) => i != clickedItem[0].id);
|
235
|
+
else expandedArray.push(clickedItem[0].id);
|
236
|
+
|
237
|
+
setExpanded(expandedArray);
|
281
238
|
}
|
282
239
|
};
|
283
240
|
|
@@ -289,23 +246,23 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
289
246
|
items.map((item: { [key: string]: any }) => {
|
290
247
|
return (
|
291
248
|
<>
|
292
|
-
<li
|
293
|
-
key={item.id}
|
294
|
-
className="dropdown_item"
|
295
|
-
data-name={item.id}
|
296
|
-
>
|
249
|
+
<li key={item.id} className="dropdown_item" data-name={item.id}>
|
297
250
|
<div className="dropdown_item_checkbox_row">
|
298
251
|
<div
|
299
|
-
key={
|
300
|
-
item.expanded ? "chevron-down" : "chevron-right"
|
301
|
-
}
|
252
|
+
key={isExpanded(item) ? "chevron-down" : "chevron-right"}
|
302
253
|
>
|
303
254
|
<CircleIconButton
|
304
255
|
icon={
|
305
|
-
item
|
256
|
+
isExpanded(item) ? "chevron-down" : "chevron-right"
|
257
|
+
}
|
258
|
+
className={
|
259
|
+
item.children && item.children.length > 0
|
260
|
+
? ""
|
261
|
+
: "toggle_icon"
|
262
|
+
}
|
263
|
+
onClick={(event: any) =>
|
264
|
+
handleToggleClick(item.id, event)
|
306
265
|
}
|
307
|
-
className={item.children && item.children.length > 0 ? "" : "toggle_icon"}
|
308
|
-
onClick={(event) => handleToggleClick(item.id, event)}
|
309
266
|
variant="link"
|
310
267
|
/>
|
311
268
|
</div>
|
@@ -316,13 +273,12 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
316
273
|
name={item.label}
|
317
274
|
value={item.label}
|
318
275
|
onChange={(e) => {
|
319
|
-
|
320
|
-
handledropdownItemClick(e);
|
276
|
+
handledropdownItemClick(e, !item.checked);
|
321
277
|
}}
|
322
278
|
/>
|
323
279
|
</Checkbox>
|
324
280
|
</div>
|
325
|
-
{item
|
281
|
+
{isExpanded(item) &&
|
326
282
|
item.children &&
|
327
283
|
item.children.length > 0 &&
|
328
284
|
!filterItem && ( // Show children if expanded is true
|
@@ -347,25 +303,20 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
347
303
|
key={index}
|
348
304
|
text={item.label}
|
349
305
|
size="small"
|
350
|
-
onClick={(event) => handlePillClose(event, item)}
|
306
|
+
onClick={(event: any) => handlePillClose(event, item)}
|
351
307
|
/>
|
352
308
|
))
|
353
309
|
: null}
|
354
310
|
{!returnAllSelected &&
|
355
311
|
defaultReturn.length !== 0 &&
|
356
|
-
defaultReturn
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
text={item.label}
|
365
|
-
size="small"
|
366
|
-
onClick={(event) => handlePillClose(event, item)}
|
367
|
-
/>
|
368
|
-
))}
|
312
|
+
defaultReturn.map((item, index) => (
|
313
|
+
<FormPill
|
314
|
+
key={index}
|
315
|
+
text={item.label}
|
316
|
+
size="small"
|
317
|
+
onClick={(event: any) => handlePillClose(event, item)}
|
318
|
+
/>
|
319
|
+
))}
|
369
320
|
{returnedArray.length !== 0 && returnAllSelected && <br />}
|
370
321
|
{defaultReturn.length !== 0 && !returnAllSelected && <br />}
|
371
322
|
<input
|