Skip to content

Commit f28442a

Browse files
committed
sortMenu adjustments
1 parent ff868ed commit f28442a

File tree

3 files changed

+77
-23
lines changed

3 files changed

+77
-23
lines changed

src/components/PanelMenuWrapper.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ class PanelsWithSidebar extends Component {
5151
const sections = [];
5252
const groupLookup = {};
5353
let groupIndex;
54-
const panels = React.Children.toArray(children);
54+
let childrenArray = React.Children.toArray(children);
5555

5656
if (menuPanelOrder) {
57-
sortMenu(panels, menuPanelOrder);
57+
childrenArray = sortMenu(childrenArray, menuPanelOrder);
5858
}
5959

60-
panels.forEach(child => {
60+
childrenArray.forEach(child => {
6161
if (!child) {
6262
return;
6363
}

src/lib/__tests__/sortMenu-test.js

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import sortMenu from '../sortMenu';
22

33
describe('sortMenu', () => {
4-
it('modifies original array to follow the group, then name order provided', () => {
4+
it('returns a new array of sorted children', () => {
55
const initialArray = [
66
{props: {group: 'DEV', name: 'Inspector'}},
77
{props: {group: 'DEV', name: 'JSON'}},
88
];
99
const orderProp = [{group: 'DEV', name: 'JSON'}, {group: 'DEV', name: 'Inspector'}];
10+
const newArray = sortMenu(initialArray, orderProp);
1011

11-
sortMenu(initialArray, orderProp);
1212
expect(initialArray).toEqual([
13+
{props: {group: 'DEV', name: 'Inspector'}},
14+
{props: {group: 'DEV', name: 'JSON'}},
15+
]);
16+
expect(newArray).toEqual([
1317
{props: {group: 'DEV', name: 'JSON'}},
1418
{props: {group: 'DEV', name: 'Inspector'}},
1519
]);
@@ -32,9 +36,9 @@ describe('sortMenu', () => {
3236
{group: 'Style', name: 'Color Bars'},
3337
{group: 'Style', name: 'Annotation'},
3438
];
39+
const newArray = sortMenu(initialArray, orderProp);
3540

36-
sortMenu(initialArray, orderProp);
37-
expect(initialArray).toEqual([
41+
expect(newArray).toEqual([
3842
{props: {group: 'DEV', name: 'JSON'}},
3943
{props: {group: 'DEV', name: 'Inspector'}},
4044
{props: {group: 'Structure', name: 'Subplots'}},
@@ -59,9 +63,9 @@ describe('sortMenu', () => {
5963
{group: 'Style', name: 'Color Bars'},
6064
{group: 'Style', name: 'Annotation'},
6165
];
66+
const newArray = sortMenu(initialArray, orderProp);
6267

63-
sortMenu(initialArray, orderProp);
64-
expect(initialArray).toEqual([
68+
expect(newArray).toEqual([
6569
{props: {group: 'Structure', name: 'Subplots'}},
6670
{props: {group: 'Structure', name: 'Create'}},
6771
{props: {group: 'Style', name: 'Color Bars'}},
@@ -79,9 +83,9 @@ describe('sortMenu', () => {
7983
{props: {group: 'Structure', name: 'Create'}},
8084
];
8185
const orderProp = [{group: 'Style', name: 'Traces'}];
86+
const newArray = sortMenu(initialArray, orderProp);
8287

83-
sortMenu(initialArray, orderProp);
84-
expect(initialArray).toEqual([
88+
expect(newArray).toEqual([
8589
{props: {group: 'Style', name: 'Traces'}},
8690
{props: {group: 'Style', name: 'Axes'}},
8791
{props: {group: 'Style', name: 'General'}},
@@ -96,16 +100,15 @@ describe('sortMenu', () => {
96100
{props: {group: 'Style', name: 'Color Bars'}},
97101
{props: {group: 'Style', name: 'Annotation'}},
98102
];
99-
100103
const orderProp = [
101104
{group: 'Non Existent', name: 'Subplots'},
102105
{group: 'Structure', name: 'Create'},
103106
{group: 'Style', name: 'Color Bars'},
104107
{group: 'Style', name: 'Annotation'},
105108
];
109+
const newArray = sortMenu(initialArray, orderProp);
106110

107-
sortMenu(initialArray, orderProp);
108-
expect(initialArray).toEqual([
111+
expect(newArray).toEqual([
109112
{props: {group: 'Structure', name: 'Create'}},
110113
{props: {group: 'Structure', name: 'Subplots'}},
111114
{props: {group: 'Style', name: 'Color Bars'}},
@@ -120,15 +123,14 @@ describe('sortMenu', () => {
120123
{props: {group: 'Style', name: 'Color Bars'}},
121124
{props: {group: 'Style', name: 'Annotation'}},
122125
];
123-
124126
const orderProp = [
125127
{group: 'Structure', name: 'Non Existent'},
126128
{group: 'Style', name: 'Color Bars'},
127129
{group: 'Style', name: 'Annotation'},
128130
];
131+
const newArray = sortMenu(initialArray, orderProp);
129132

130-
sortMenu(initialArray, orderProp);
131-
expect(initialArray).toEqual([
133+
expect(newArray).toEqual([
132134
{props: {group: 'Style', name: 'Color Bars'}},
133135
{props: {group: 'Style', name: 'Annotation'}},
134136
{props: {group: 'Structure', name: 'Create'}},
@@ -143,19 +145,43 @@ describe('sortMenu', () => {
143145
{props: {group: 'Style', name: 'Color Bars'}},
144146
{props: {group: 'Style', name: 'Annotation'}},
145147
];
146-
147148
const orderProp = [
148149
{group: 'Structure', name: 'Annotation'},
149150
{group: 'Style', name: 'Color Bars'},
150151
{group: 'Style', name: 'Annotation'},
151152
];
153+
const newArray = sortMenu(initialArray, orderProp);
152154

153-
sortMenu(initialArray, orderProp);
154-
expect(initialArray).toEqual([
155+
expect(newArray).toEqual([
155156
{props: {group: 'Style', name: 'Color Bars'}},
156157
{props: {group: 'Style', name: 'Annotation'}},
157158
{props: {group: 'Structure', name: 'Create'}},
158159
{props: {group: 'Structure', name: 'Subplots'}},
159160
]);
160161
});
162+
163+
it('does not sort children with no group or name props', () => {
164+
const initialArray = [
165+
{props: {type: 'Logo'}},
166+
{props: {group: 'A', name: 'A'}},
167+
{props: {group: 'Structure', name: 'Subplots'}},
168+
{props: {group: 'Structure', name: 'Create'}},
169+
{props: {type: 'ButtonA'}},
170+
{props: {type: 'ButtonB'}},
171+
];
172+
const orderProp = [
173+
{group: 'Structure', name: 'Create'},
174+
{group: 'Structure', name: 'Subplots'},
175+
];
176+
const newArray = sortMenu(initialArray, orderProp);
177+
178+
expect(newArray).toEqual([
179+
{props: {type: 'Logo'}},
180+
{props: {group: 'Structure', name: 'Create'}},
181+
{props: {group: 'Structure', name: 'Subplots'}},
182+
{props: {group: 'A', name: 'A'}},
183+
{props: {type: 'ButtonA'}},
184+
{props: {type: 'ButtonB'}},
185+
]);
186+
});
161187
});

src/lib/sortMenu.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,34 @@ function sortAlphabetically(a, b) {
88
return sortByGroup || sortByName;
99
}
1010

11-
export default function sortMenu(panels, order) {
12-
// validates order, if a desired panel matches no panel in the panels array,
13-
// it is excluded from ordering considerations
11+
export default function sortMenu(children, order) {
12+
// PART 1: only sorting panels (i.e. child with a group and name prop)
13+
// and not other elements (like Buttons, or Logo)
14+
let panelsStartIndex = null;
15+
let panelsEndIndex = null;
16+
for (let i = 0; i < children.length; i++) {
17+
if (children[i].props.group && children[i].props.name && !panelsStartIndex) {
18+
panelsStartIndex = i;
19+
break;
20+
}
21+
}
22+
for (let i = panelsStartIndex; i < children.length; i++) {
23+
if (!children[i].props.group && !children[i].props.name && !panelsEndIndex) {
24+
panelsEndIndex = i - 1;
25+
break;
26+
} else if (i === children.length - 1) {
27+
panelsEndIndex = i;
28+
}
29+
}
1430

31+
const prePanelsChildren = panelsStartIndex === 0 ? [] : children.slice(0, panelsStartIndex);
32+
const panels =
33+
panelsStartIndex !== panelsEndIndex ? children.slice(panelsStartIndex, panelsEndIndex + 1) : [];
34+
const postPanelsChildren =
35+
panelsEndIndex === children.length ? [] : children.slice(panelsEndIndex + 1);
36+
37+
// PART 2: validate order prop, if a desired panel specified in order, matches no actual panel rendered
38+
// in the panels array, it is excluded from ordering considerations
1539
// eslint-disable-next-line
1640
order = order.filter(desiredPanel =>
1741
panels.some(
@@ -24,6 +48,7 @@ export default function sortMenu(panels, order) {
2448
const desiredGroupOrder = order.map(panel => panel.group).filter(getUniqueValues);
2549
const desiredNameOrder = order.map(panel => panel.name).filter(getUniqueValues);
2650

51+
// PART 3: Sort panels
2752
panels.sort((a, b) => {
2853
const panelAHasGroupCustomOrder = desiredGroupOrder.includes(a.props.group);
2954
const panelBHasGroupCustomOrder = desiredGroupOrder.includes(b.props.group);
@@ -79,4 +104,7 @@ export default function sortMenu(panels, order) {
79104
}
80105
return 0;
81106
});
107+
108+
// PART 4: Return all children
109+
return prePanelsChildren.concat(panels).concat(postPanelsChildren);
82110
}

0 commit comments

Comments
 (0)