@samitouri / QOS-React-2 / commits / f6ec82553d

Support toggling Suspense from within owners list

Brian Vaughn committed Jun 12, 2019 at 15:13 UTC f6ec82553de20e39576e5a46a70205c4ad4b0df6
3 files changed +216 -4
src/__tests__/__snapshots__/treeContext-test.js.snap
+153
@@ -1,5 +1,158 @@
1 // Jest Snapshot v1, https://goo.gl/fbAQLP
2
3 +exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 0: mount 1`] = `
4 +[root]
5 + ▾ <Parent>
6 + ▾ <Suspense>
7 + ▾ <Child>
8 + ▾ <Suspense>
9 + <Grandchild>
10 +`;
11 +
12 +exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 1: initial state 1`] = `
13 +Object {
14 + "inspectedElementID": null,
15 + "numElements": 5,
16 + "ownerFlatTree": null,
17 + "ownerID": null,
18 + "searchIndex": null,
19 + "searchResults": Array [],
20 + "searchText": "",
21 + "selectedElementID": null,
22 + "selectedElementIndex": null,
23 +}
24 +`;
25 +
26 +exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 2: child owners tree 1`] = `
27 +Object {
28 + "inspectedElementID": 4,
29 + "numElements": 3,
30 + "ownerFlatTree": Array [
31 + Object {
32 + "children": Array [
33 + 5,
34 + ],
35 + "depth": 0,
36 + "displayName": "Child",
37 + "hocDisplayNames": null,
38 + "id": 4,
39 + "isCollapsed": false,
40 + "key": null,
41 + "ownerID": 2,
42 + "parentID": 3,
43 + "type": 5,
44 + "weight": 3,
45 + },
46 + Object {
47 + "children": Array [
48 + 6,
49 + ],
50 + "depth": 1,
51 + "displayName": "Suspense",
52 + "hocDisplayNames": null,
53 + "id": 5,
54 + "isCollapsed": false,
55 + "key": null,
56 + "ownerID": 4,
57 + "parentID": 4,
58 + "type": 12,
59 + "weight": 2,
60 + },
61 + Object {
62 + "children": Array [],
63 + "depth": 2,
64 + "displayName": "Grandchild",
65 + "hocDisplayNames": null,
66 + "id": 6,
67 + "isCollapsed": false,
68 + "key": null,
69 + "ownerID": 4,
70 + "parentID": 5,
71 + "type": 5,
72 + "weight": 1,
73 + },
74 + ],
75 + "ownerID": 4,
76 + "searchIndex": null,
77 + "searchResults": Array [],
78 + "searchText": "",
79 + "selectedElementID": 4,
80 + "selectedElementIndex": 0,
81 +}
82 +`;
83 +
84 +exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 3: child owners tree 1`] = `
85 +Object {
86 + "inspectedElementID": 5,
87 + "numElements": 3,
88 + "ownerFlatTree": Array [
89 + Object {
90 + "children": Array [
91 + 5,
92 + ],
93 + "depth": 0,
94 + "displayName": "Child",
95 + "hocDisplayNames": null,
96 + "id": 4,
97 + "isCollapsed": false,
98 + "key": null,
99 + "ownerID": 2,
100 + "parentID": 3,
101 + "type": 5,
102 + "weight": 3,
103 + },
104 + Object {
105 + "children": Array [
106 + 6,
107 + ],
108 + "depth": 1,
109 + "displayName": "Suspense",
110 + "hocDisplayNames": null,
111 + "id": 5,
112 + "isCollapsed": false,
113 + "key": null,
114 + "ownerID": 4,
115 + "parentID": 4,
116 + "type": 12,
117 + "weight": 2,
118 + },
119 + Object {
120 + "children": Array [],
121 + "depth": 2,
122 + "displayName": "Grandchild",
123 + "hocDisplayNames": null,
124 + "id": 6,
125 + "isCollapsed": false,
126 + "key": null,
127 + "ownerID": 4,
128 + "parentID": 5,
129 + "type": 5,
130 + "weight": 1,
131 + },
132 + ],
133 + "ownerID": 4,
134 + "searchIndex": null,
135 + "searchResults": Array [],
136 + "searchText": "",
137 + "selectedElementID": 5,
138 + "selectedElementIndex": 1,
139 +}
140 +`;
141 +
142 +exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 4: main tree 1`] = `
143 +Object {
144 + "inspectedElementID": 5,
145 + "numElements": 5,
146 + "ownerFlatTree": null,
147 + "ownerID": null,
148 + "searchIndex": null,
149 + "searchResults": Array [],
150 + "searchText": "",
151 + "selectedElementID": 5,
152 + "selectedElementIndex": 1,
153 +}
154 +`;
155 +
156 exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 0: mount 1`] = `
157 [root]
158 ▾ <Parent>
src/__tests__/treeContext-test.js
+47
@@ -546,5 +546,52 @@ describe('TreeListContext', () => {
546
547 done();
548 });
549 +
550 + // This tests ensures support for toggling Suspense boundaries outside of the active owners list.
551 + it('should exit the owners list if an element outside the list is selected', () => {
552 + const Grandchild = () => null;
553 + const Child = () => (
554 + <React.Suspense fallback="Loading">
555 + <Grandchild />
556 + </React.Suspense>
557 + );
558 + const Parent = () => (
559 + <React.Suspense fallback="Loading">
560 + <Child />
561 + </React.Suspense>
562 + );
563 +
564 + const container = document.createElement('div');
565 + utils.act(() => ReactDOM.render(<Parent />, container));
566 +
567 + expect(store).toMatchSnapshot('0: mount');
568 +
569 + let renderer;
570 + utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
571 + expect(state).toMatchSnapshot('1: initial state');
572 +
573 + const outerSuspenseID = ((store.getElementIDAtIndex(1): any): number);
574 + const childID = ((store.getElementIDAtIndex(2): any): number);
575 + const innerSuspenseID = ((store.getElementIDAtIndex(3): any): number);
576 + const grandchildID = ((store.getElementIDAtIndex(4): any): number);
577 +
578 + utils.act(() => dispatch({ type: 'SELECT_OWNER', payload: childID }));
579 + utils.act(() => renderer.update(<Contexts />));
580 + expect(state).toMatchSnapshot('2: child owners tree');
581 +
582 + // Toggling a Suspense boundary inside of the flat list should update selected index
583 + utils.act(() =>
584 + dispatch({ type: 'SELECT_ELEMENT_BY_ID', payload: innerSuspenseID })
585 + );
586 + utils.act(() => renderer.update(<Contexts />));
587 + expect(state).toMatchSnapshot('3: child owners tree');
588 +
589 + // Toggling a Suspense boundary outside of the flat list should exit owners list and update index
590 + utils.act(() =>
591 + dispatch({ type: 'SELECT_ELEMENT_BY_ID', payload: outerSuspenseID })
592 + );
593 + utils.act(() => renderer.update(<Contexts />));
594 + expect(state).toMatchSnapshot('4: main tree');
595 + });
596 });
597 });
src/devtools/views/Components/TreeContext.js
+16 -4
@@ -488,10 +488,22 @@ function reduceOwnersState(store: Store, state: State, action: Action): State {
488 case 'SELECT_ELEMENT_BY_ID':
489 if (ownerFlatTree !== null) {
490 const payload = (action: ACTION_SELECT_ELEMENT_BY_ID).payload;
491 - selectedElementIndex =
492 - payload === null
493 - ? null
494 - : ownerFlatTree.findIndex(element => element.id === payload);
491 + if (payload === null) {
492 + selectedElementIndex = null;
493 + } else {
494 + selectedElementIndex = ownerFlatTree.findIndex(
495 + element => element.id === payload
496 + );
497 +
498 + // If the selected element is outside of the current owners list,
499 + // exit the list and select the element in the main tree.
500 + // This supports features like toggling Suspense.
501 + if (selectedElementIndex !== null && selectedElementIndex < 0) {
502 + ownerID = null;
503 + ownerFlatTree = null;
504 + selectedElementIndex = store.getIndexOfElementID(payload);
505 + }
506 + }
507 }
508 break;
509 case 'SELECT_NEXT_ELEMENT_IN_TREE':