playbook_ui 12.26.0.pre.alpha.multiselectfixes797 → 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 +132 -184
- 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
|
|
@@ -59,68 +57,103 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
59
57
|
//this is essentially the return that the user will get when they use the kit
|
|
60
58
|
const [returnedArray, setReturnedArray] = useState([]);
|
|
61
59
|
//formattedData with checked and parent_id added
|
|
62
|
-
const [formattedData, setFormattedData] = useState(
|
|
63
|
-
//toggle chevron in dropdown
|
|
64
|
-
//@ts-ignore
|
|
65
|
-
const [isToggled, setIsToggled] = useState<{ [id: number]: boolean }>({});
|
|
60
|
+
const [formattedData, setFormattedData] = useState([]);
|
|
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
|
-
console.log("RETURN", returnedArray)
|
|
86
|
-
}, [returnedArray, defaultReturn]);
|
|
87
|
-
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
console.log("TREEDATA", treeData)
|
|
90
|
-
//Create new formattedData array for use
|
|
91
65
|
setFormattedData(addCheckedAndParentProperty(treeData));
|
|
92
|
-
//if any items already checked in first render, set return accordingly
|
|
93
|
-
const initialChecked = getCheckedItems(treeData)
|
|
94
|
-
console.log("INITIAl CHECKED", initialChecked)
|
|
95
|
-
const initialUnchecked = areAllCheckedFalse(treeData)
|
|
96
|
-
console.log("INIITAL UNCHECKED", initialUnchecked)
|
|
97
|
-
initialChecked && returnAllSelected && setReturnedArray(initialChecked)
|
|
98
|
-
initialChecked && !returnAllSelected && setDefaultReturn(initialChecked)
|
|
99
|
-
// initialUnchecked && returnAllSelected && setReturnedArray([])
|
|
100
|
-
// initialUnchecked && !returnAllSelected && setDefaultReturn([])
|
|
101
|
-
|
|
102
66
|
}, [treeData]);
|
|
103
67
|
|
|
104
|
-
useEffect(()=> {
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (returnAllSelected) {
|
|
70
|
+
setReturnedArray(getCheckedItems(formattedData));
|
|
71
|
+
} else {
|
|
72
|
+
setDefaultReturn(getDefaultCheckedItems(formattedData));
|
|
73
|
+
}
|
|
74
|
+
}, [formattedData]);
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
105
77
|
// Function to handle clicks outside the dropdown
|
|
106
78
|
const handleClickOutside = (event: any) => {
|
|
107
79
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
108
80
|
setIsClosed(true);
|
|
109
81
|
}
|
|
110
82
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},[])
|
|
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
|
+
};
|
|
118
151
|
|
|
119
152
|
//function to map over data and add parent_id + depth property to each item
|
|
120
153
|
const addCheckedAndParentProperty = (
|
|
121
154
|
treeData: { [key: string]: any }[],
|
|
122
155
|
parent_id: string = null,
|
|
123
|
-
depth: number = 0
|
|
156
|
+
depth: number = 0
|
|
124
157
|
) => {
|
|
125
158
|
if (!Array.isArray(treeData)) {
|
|
126
159
|
return;
|
|
@@ -132,10 +165,14 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
132
165
|
depth,
|
|
133
166
|
};
|
|
134
167
|
if (newItem.children && newItem.children.length > 0) {
|
|
168
|
+
const children =
|
|
169
|
+
item.checked && !returnAllSelected
|
|
170
|
+
? modifyRecursive(item.children, true)
|
|
171
|
+
: item.children;
|
|
135
172
|
newItem.children = addCheckedAndParentProperty(
|
|
136
|
-
|
|
173
|
+
children,
|
|
137
174
|
newItem.id,
|
|
138
|
-
depth + 1
|
|
175
|
+
depth + 1
|
|
139
176
|
);
|
|
140
177
|
}
|
|
141
178
|
return newItem;
|
|
@@ -146,37 +183,13 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
146
183
|
const handlePillClose = (event: any, clickedItem: { [key: string]: any }) => {
|
|
147
184
|
// prevents the dropdown from closing when clicking on the pill
|
|
148
185
|
event.stopPropagation();
|
|
186
|
+
const updatedTree = changeItem(clickedItem, false);
|
|
149
187
|
//logic for removing items from returnArray or defaultReturn when pills clicked
|
|
150
188
|
if (returnAllSelected) {
|
|
151
|
-
|
|
152
|
-
if (clickedItem.children && clickedItem.children.length > 0) {
|
|
153
|
-
const childrenOfChecked = getChildIds(clickedItem, returnedArray);
|
|
154
|
-
const updatedFiltered = returnedArray
|
|
155
|
-
.filter((item) => item !== clickedItem)
|
|
156
|
-
.filter((item) => !childrenOfChecked.includes(item.id));
|
|
157
|
-
setReturnedArray(updatedFiltered);
|
|
158
|
-
} else {
|
|
159
|
-
const updatedFiltered = returnedArray.filter(
|
|
160
|
-
(item) => item !== clickedItem
|
|
161
|
-
);
|
|
162
|
-
setReturnedArray(updatedFiltered);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
189
|
+
onSelect(getCheckedItems(updatedTree));
|
|
165
190
|
} else {
|
|
166
|
-
|
|
167
|
-
getAncestorsOfUnchecked(formattedData, clickedItem);
|
|
168
|
-
const newChecked = getCheckedItems(formattedData);
|
|
169
|
-
const filteredReturn = updateReturnItems(newChecked).filter(
|
|
170
|
-
(item) => item.id !== clickedItem.id
|
|
171
|
-
);
|
|
172
|
-
setDefaultReturn(filteredReturn);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (clickedItem.children && clickedItem.children.length > 0) {
|
|
176
|
-
unCheckedRecursive(clickedItem);
|
|
191
|
+
onSelect(getDefaultCheckedItems(updatedTree));
|
|
177
192
|
}
|
|
178
|
-
//logic to uncheck clickedItem in formattedData
|
|
179
|
-
unCheckIt(formattedData, clickedItem.id);
|
|
180
193
|
};
|
|
181
194
|
|
|
182
195
|
//handle click on input wrapper(entire div with pills, typeahead, etc) so it doesn't close when input or form pill is clicked
|
|
@@ -192,95 +205,36 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
192
205
|
};
|
|
193
206
|
|
|
194
207
|
//Main function to handle any click inside dropdown
|
|
195
|
-
const handledropdownItemClick = (e: any) => {
|
|
208
|
+
const handledropdownItemClick = (e: any, check: boolean) => {
|
|
196
209
|
const clickedItem = e.target.parentNode.id;
|
|
197
210
|
//setting filterItem to "" will clear textinput and clear typeahead
|
|
198
211
|
setFilterItem("");
|
|
199
212
|
|
|
200
213
|
const filtered = filterFormattedDataById(formattedData, clickedItem);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
checkedRecursive(item);
|
|
206
|
-
});
|
|
207
|
-
} else if (!filtered[0].checked) {
|
|
208
|
-
filtered[0].children.forEach((item: { [key: string]: any }) => {
|
|
209
|
-
unCheckedRecursive(item);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const checkedItems = getCheckedItems(formattedData);
|
|
215
|
-
|
|
216
|
-
//checking and unchecking items for returnAllSelected variant
|
|
217
|
-
if (returnedArray.includes(filtered[0])) {
|
|
218
|
-
if (!filtered[0].checked) {
|
|
219
|
-
if (filtered[0].children && filtered[0].children.length > 0) {
|
|
220
|
-
const childrenOfChecked = getChildIds(filtered[0], returnedArray);
|
|
221
|
-
const updatedFiltered = returnedArray
|
|
222
|
-
.filter((item) => item !== filtered[0])
|
|
223
|
-
.filter((item) => !childrenOfChecked.includes(item.id));
|
|
224
|
-
|
|
225
|
-
setReturnedArray(updatedFiltered);
|
|
226
|
-
} else {
|
|
227
|
-
const updatedFiltered = returnedArray.filter(
|
|
228
|
-
(item) => item !== filtered[0]
|
|
229
|
-
);
|
|
230
|
-
setReturnedArray(updatedFiltered);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
214
|
+
const updatedTree = changeItem(filtered[0], check);
|
|
215
|
+
console.log(updatedTree);
|
|
216
|
+
if (returnAllSelected) {
|
|
217
|
+
onSelect(getCheckedItems(updatedTree));
|
|
233
218
|
} else {
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
//when item is unchecked for default variant
|
|
238
|
-
if (!filtered[0].checked && !returnAllSelected) {
|
|
239
|
-
//uncheck parent and grandparent if any child unchecked
|
|
240
|
-
getAncestorsOfUnchecked(formattedData, filtered[0]);
|
|
241
|
-
|
|
242
|
-
const newChecked = getCheckedItems(formattedData);
|
|
243
|
-
//get all checked items, and filter to check if all children checked, if yes return only parent
|
|
244
|
-
const filteredReturn = updateReturnItems(newChecked);
|
|
245
|
-
setDefaultReturn(filteredReturn);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
//when item is checked for default variant
|
|
249
|
-
if (!returnAllSelected && filtered[0].checked) {
|
|
250
|
-
//if checked item has children
|
|
251
|
-
if (filtered[0].children && filtered[0].children.length > 0) {
|
|
252
|
-
removeChildrenIfParentChecked(
|
|
253
|
-
filtered[0],
|
|
254
|
-
defaultReturn,
|
|
255
|
-
setDefaultReturn
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
//if clicked item has parent_id, find parent and check if all children checked or not
|
|
260
|
-
if (filtered[0].parent_id !== null) {
|
|
261
|
-
recursiveReturnOnlyParent(
|
|
262
|
-
filtered[0],
|
|
263
|
-
formattedData,
|
|
264
|
-
defaultReturn,
|
|
265
|
-
setDefaultReturn
|
|
266
|
-
);
|
|
267
|
-
} else {
|
|
268
|
-
setDefaultReturn([filtered[0]]);
|
|
269
|
-
}
|
|
219
|
+
onSelect(getDefaultCheckedItems(updatedTree));
|
|
270
220
|
}
|
|
271
221
|
};
|
|
272
222
|
|
|
223
|
+
const isExpanded = (item: any) => expanded.indexOf(item.id) > -1;
|
|
224
|
+
|
|
273
225
|
//handle click on chevron toggles in dropdown
|
|
274
226
|
const handleToggleClick = (id: string, event: React.MouseEvent) => {
|
|
275
227
|
event.stopPropagation();
|
|
276
|
-
setIsToggled((prevState: { [id: string]: boolean }) => ({
|
|
277
|
-
...prevState,
|
|
278
|
-
[id]: !prevState[id],
|
|
279
|
-
}));
|
|
280
228
|
const clickedItem = filterFormattedDataById(formattedData, id);
|
|
281
|
-
|
|
282
229
|
if (clickedItem) {
|
|
283
|
-
|
|
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);
|
|
284
238
|
}
|
|
285
239
|
};
|
|
286
240
|
|
|
@@ -292,23 +246,23 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
292
246
|
items.map((item: { [key: string]: any }) => {
|
|
293
247
|
return (
|
|
294
248
|
<>
|
|
295
|
-
<li
|
|
296
|
-
key={item.id}
|
|
297
|
-
className="dropdown_item"
|
|
298
|
-
data-name={item.id}
|
|
299
|
-
>
|
|
249
|
+
<li key={item.id} className="dropdown_item" data-name={item.id}>
|
|
300
250
|
<div className="dropdown_item_checkbox_row">
|
|
301
251
|
<div
|
|
302
|
-
key={
|
|
303
|
-
item.expanded ? "chevron-down" : "chevron-right"
|
|
304
|
-
}
|
|
252
|
+
key={isExpanded(item) ? "chevron-down" : "chevron-right"}
|
|
305
253
|
>
|
|
306
254
|
<CircleIconButton
|
|
307
255
|
icon={
|
|
308
|
-
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)
|
|
309
265
|
}
|
|
310
|
-
className={item.children && item.children.length > 0 ? "" : "toggle_icon"}
|
|
311
|
-
onClick={(event) => handleToggleClick(item.id, event)}
|
|
312
266
|
variant="link"
|
|
313
267
|
/>
|
|
314
268
|
</div>
|
|
@@ -319,13 +273,12 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
319
273
|
name={item.label}
|
|
320
274
|
value={item.label}
|
|
321
275
|
onChange={(e) => {
|
|
322
|
-
|
|
323
|
-
handledropdownItemClick(e);
|
|
276
|
+
handledropdownItemClick(e, !item.checked);
|
|
324
277
|
}}
|
|
325
278
|
/>
|
|
326
279
|
</Checkbox>
|
|
327
280
|
</div>
|
|
328
|
-
{item
|
|
281
|
+
{isExpanded(item) &&
|
|
329
282
|
item.children &&
|
|
330
283
|
item.children.length > 0 &&
|
|
331
284
|
!filterItem && ( // Show children if expanded is true
|
|
@@ -350,25 +303,20 @@ const MultiLevelSelect = (props: MultiLevelSelectProps) => {
|
|
|
350
303
|
key={index}
|
|
351
304
|
text={item.label}
|
|
352
305
|
size="small"
|
|
353
|
-
onClick={(event) => handlePillClose(event, item)}
|
|
306
|
+
onClick={(event: any) => handlePillClose(event, item)}
|
|
354
307
|
/>
|
|
355
308
|
))
|
|
356
309
|
: null}
|
|
357
310
|
{!returnAllSelected &&
|
|
358
311
|
defaultReturn.length !== 0 &&
|
|
359
|
-
defaultReturn
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
text={item.label}
|
|
368
|
-
size="small"
|
|
369
|
-
onClick={(event) => handlePillClose(event, item)}
|
|
370
|
-
/>
|
|
371
|
-
))}
|
|
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
|
+
))}
|
|
372
320
|
{returnedArray.length !== 0 && returnAllSelected && <br />}
|
|
373
321
|
{defaultReturn.length !== 0 && !returnAllSelected && <br />}
|
|
374
322
|
<input
|