Skip to content

Commit d80ff05

Browse files
sunpietroŁukasz Serwatka
authored andcommitted
EZP-29746: Selected item blinking while loading its children in UDW (#111)
* EZP-29746: Selected item blinking while loading its children in UDW * fixup * fixup * fixup
1 parent 0c34718 commit d80ff05

File tree

11 files changed

+133
-131
lines changed

11 files changed

+133
-131
lines changed

Resources/public/js/MultiFileUpload.module.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/public/js/MultiFileUpload.module.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/public/js/SubItems.module.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/public/js/SubItems.module.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/public/js/UniversalDiscovery.module.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/public/js/UniversalDiscovery.module.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/universal-discovery/components/finder/finder.component.js

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
33

44
import FinderTreeBranchComponent from './finder.tree.branch.component';
55
import { loadPreselectedLocationData, QUERY_LIMIT } from '../../services/universal.discovery.service';
6+
import deepClone from '../../../common/helpers/deep.clone.helper';
67

78
import './css/finder.component.css';
89

@@ -13,6 +14,7 @@ export default class FinderComponent extends Component {
1314
this.state = {
1415
locationsMap: {},
1516
activeLocations: {},
17+
lastSelectedItem: null,
1618
limit: QUERY_LIMIT,
1719
};
1820

@@ -22,6 +24,8 @@ export default class FinderComponent extends Component {
2224
this.loadBranchLeaves = this.loadBranchLeaves.bind(this);
2325
this.onLoadMore = this.onLoadMore.bind(this);
2426
this.renderBranch = this.renderBranch.bind(this);
27+
this.setBranchContainerRef = this.setBranchContainerRef.bind(this);
28+
this.setPreselectedState = this.setPreselectedState.bind(this);
2529

2630
this.locationsMap = {};
2731
this.activeLocations = {};
@@ -39,7 +43,7 @@ export default class FinderComponent extends Component {
3943
this.loadPreselectedData(this.props.preselectedLocation, true);
4044
} else {
4145
this.props.findLocationsByParentLocationId(
42-
Object.assign({}, this.props.restInfo, { parentLocationId: this.props.startingLocationId }),
46+
{ ...this.props.restInfo, parentLocationId: this.props.startingLocationId },
4347
this.updateLocationsData
4448
);
4549
}
@@ -53,17 +57,14 @@ export default class FinderComponent extends Component {
5357
const isShowingUp = nextProps.isVisible && nextProps.isVisible !== this.props.isVisible;
5458

5559
if (this.preselectedItem && this.locationsMap && this.activeLocations && isShowingUp) {
56-
this.setState(
57-
(state) =>
58-
Object.assign({}, state, {
59-
locationsMap: this.locationsMap,
60-
activeLocations: this.activeLocations,
61-
}),
62-
() => nextProps.isVisible && this.props.onItemSelect(this.preselectedItem)
63-
);
60+
this.setState(this.setPreselectedState, () => nextProps.isVisible && this.props.onItemSelect(this.preselectedItem));
6461
}
6562
}
6663

64+
setPreselectedState() {
65+
return { locationsMap: this.locationsMap, activeLocations: this.activeLocations };
66+
}
67+
6768
/**
6869
* Load data of preselected location.
6970
*
@@ -105,10 +106,7 @@ export default class FinderComponent extends Component {
105106
};
106107

107108
if (subitems[1]) {
108-
const item = createItem({
109-
parent: 1,
110-
children: subitems[1],
111-
});
109+
const item = createItem({ parent: 1, children: subitems[1] });
112110

113111
this.locationsMap[1] = item;
114112
this.activeLocations[0] = item;
@@ -133,14 +131,7 @@ export default class FinderComponent extends Component {
133131
* @memberof FinderComponent
134132
*/
135133
setPreselectedLocationData() {
136-
this.setState(
137-
(state) =>
138-
Object.assign({}, state, {
139-
locationsMap: this.locationsMap,
140-
activeLocations: this.activeLocations,
141-
}),
142-
() => this.props.isVisible && this.props.onItemSelect(this.preselectedItem)
143-
);
134+
this.setState(this.setPreselectedState, () => this.props.isVisible && this.props.onItemSelect(this.preselectedItem));
144135
}
145136

146137
/**
@@ -152,21 +143,21 @@ export default class FinderComponent extends Component {
152143
*/
153144
updateLocationsData({ parentLocationId, data, offset }, location = null) {
154145
this.setState((state) => {
155-
const activeLocations = Object.assign({}, state.activeLocations);
146+
const activeLocations = deepClone(state.activeLocations);
156147
const locationBranch = {
157148
location,
158149
parent: parentLocationId,
159150
data: data.View.Result.searchHits.searchHit,
160151
count: data.View.Result.count,
161152
offset,
162153
};
163-
const locationsMap = Object.assign({}, state.locationsMap, { [parentLocationId]: locationBranch });
154+
const locationsMap = { ...deepClone(state.locationsMap), [parentLocationId]: locationBranch };
164155

165156
if (!Object.keys(activeLocations).length) {
166157
activeLocations[0] = locationBranch;
167158
}
168159

169-
return Object.assign({}, state, { activeLocations, locationsMap });
160+
return { activeLocations, locationsMap };
170161
});
171162
}
172163

@@ -194,10 +185,10 @@ export default class FinderComponent extends Component {
194185
onLoadMore(parentLocation) {
195186
const limit = this.state.limit;
196187
const offset = Object.values(this.state.activeLocations).find((location) => location.parent === parentLocation.id).offset + limit;
197-
198188
const sortClauses = this.getLocationSortClauses(parentLocation);
189+
199190
this.props.findLocationsByParentLocationId(
200-
Object.assign({}, this.props.restInfo, { parentLocationId: parentLocation.id, limit, offset, sortClauses }),
191+
{ ...this.props.restInfo, parentLocationId: parentLocation.id, limit, offset, sortClauses },
201192
this.appendMoreItems
202193
);
203194
}
@@ -211,8 +202,8 @@ export default class FinderComponent extends Component {
211202
*/
212203
appendMoreItems({ parentLocationId, offset, data }) {
213204
this.setState((state) => {
214-
const activeLocations = Object.assign({}, state.activeLocations);
215-
const locationsMap = Object.assign({}, state.locationsMap);
205+
const activeLocations = deepClone(state.activeLocations);
206+
const locationsMap = deepClone(state.locationsMap);
216207

217208
Object.keys(activeLocations).forEach((key) => {
218209
const location = activeLocations[key];
@@ -226,7 +217,7 @@ export default class FinderComponent extends Component {
226217
}
227218
});
228219

229-
return Object.assign({}, state, { activeLocations, locationsMap });
220+
return { activeLocations, locationsMap };
230221
});
231222
}
232223

@@ -241,7 +232,11 @@ export default class FinderComponent extends Component {
241232
const sortClauses = this.getLocationSortClauses(parentLocation);
242233
const promise = new Promise((resolve) =>
243234
this.props.findLocationsByParentLocationId(
244-
Object.assign({}, this.props.restInfo, { parentLocationId: parentLocation.id, sortClauses }),
235+
{
236+
...this.props.restInfo,
237+
parentLocationId: parentLocation.id,
238+
sortClauses,
239+
},
245240
resolve
246241
)
247242
);
@@ -260,12 +255,12 @@ export default class FinderComponent extends Component {
260255
* @memberof FinderComponent
261256
*/
262257
updateBranchActiveLocations(parent) {
263-
const activeLocations = Object.assign({}, this.state.activeLocations);
258+
const activeLocations = deepClone(this.state.activeLocations);
264259
const depth = Object.keys(activeLocations).find((locationDepth) => activeLocations[locationDepth].parent === parent);
265260

266261
activeLocations[depth] = this.state.locationsMap[parent];
267262

268-
this.setState((state) => Object.assign({}, state, { activeLocations }));
263+
this.setState(() => ({ activeLocations }));
269264
}
270265

271266
/**
@@ -285,25 +280,28 @@ export default class FinderComponent extends Component {
285280
return {};
286281
}
287282

288-
return {
289-
[sortField]: sortOrder,
290-
};
283+
return { [sortField]: sortOrder };
291284
}
292285

293286
/**
294287
* Finds location children (sub-items)
295288
*
296289
* @method findLocationChildren
297-
* @param {Object} params params hash containing: parent and location properties
290+
* @param {Object} params
291+
* @param {String} params.parent parent location id
292+
* @param {Object} params.location
293+
* @param {Function} params.onDataLoaded
298294
* @memberof FinderComponent
299295
*/
300-
findLocationChildren({ parent, location }) {
296+
findLocationChildren({ parent, location, onDataLoaded }) {
301297
if (this.props.allowedLocations.length === 1) {
302298
return;
303299
}
304300

301+
this.setState(() => ({ lastSelectedItem: parent }));
302+
305303
if (this.state.locationsMap[parent]) {
306-
this.updateSelectedBranches(location);
304+
this.updateSelectedBranches(location, onDataLoaded);
307305
this.props.onItemSelect(location);
308306

309307
return;
@@ -312,14 +310,19 @@ export default class FinderComponent extends Component {
312310
const sortClauses = this.getLocationSortClauses(location);
313311
const promise = new Promise((resolve) =>
314312
this.props.findLocationsByParentLocationId(
315-
Object.assign({}, this.props.restInfo, { parentLocationId: parent, sortClauses }),
313+
{
314+
...this.props.restInfo,
315+
parentLocationId: parent,
316+
sortClauses,
317+
},
316318
resolve
317319
)
318320
);
319321

320322
promise.then((response) => {
321323
this.updateLocationsData(response, location);
322-
this.updateSelectedBranches(location);
324+
this.updateSelectedBranches(location, onDataLoaded);
325+
323326
this.props.onItemSelect(location);
324327
});
325328
}
@@ -328,10 +331,11 @@ export default class FinderComponent extends Component {
328331
* Updates selected branches state
329332
*
330333
* @param {Object} location location struct
334+
* @param {Function} onDataLoaded
331335
* @memberof FinderComponent
332336
*/
333-
updateSelectedBranches(location) {
334-
this.setState(this.updateActiveLocations.bind(this, location));
337+
updateSelectedBranches(location, onDataLoaded) {
338+
this.setState(this.updateActiveLocations.bind(this, location), onDataLoaded);
335339
}
336340

337341
/**
@@ -357,7 +361,7 @@ export default class FinderComponent extends Component {
357361

358362
activeLocations[locationDepth] = state.locationsMap[location.id];
359363

360-
return Object.assign({}, state, { activeLocations });
364+
return { activeLocations };
361365
}
362366

363367
/**
@@ -369,6 +373,8 @@ export default class FinderComponent extends Component {
369373
* @memberof FinderComponent
370374
*/
371375
renderBranch({ parent, data, count, location }) {
376+
const { lastSelectedItem } = this.state;
377+
372378
if (!data || !count) {
373379
return null;
374380
}
@@ -382,6 +388,7 @@ export default class FinderComponent extends Component {
382388
parentLocation={location}
383389
items={data}
384390
total={count}
391+
lastSelectedItem={lastSelectedItem}
385392
selectedLocations={selectedLocations}
386393
onItemClick={this.findLocationChildren}
387394
onBranchClick={this.loadBranchLeaves}
@@ -399,6 +406,10 @@ export default class FinderComponent extends Component {
399406
);
400407
}
401408

409+
setBranchContainerRef(ref) {
410+
this._refBranchesContainer = ref;
411+
}
412+
402413
render() {
403414
const activeLocations = Object.values(this.state.activeLocations);
404415

@@ -408,7 +419,7 @@ export default class FinderComponent extends Component {
408419

409420
return (
410421
<div className="c-finder" style={{ maxHeight: `${this.props.maxHeight}px` }}>
411-
<div className="c-finder__branches" ref={(ref) => (this._refBranchesContainer = ref)}>
422+
<div className="c-finder__branches" ref={this.setBranchContainerRef}>
412423
{activeLocations.map(this.renderBranch)}
413424
</div>
414425
</div>

src/modules/universal-discovery/components/finder/finder.tree.branch.component.js

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,16 @@ export default class FinderTreeBranchComponent extends Component {
1111

1212
this.expandBranch = this.expandBranch.bind(this);
1313
this.onLoadMore = this.onLoadMore.bind(this);
14+
this.removeLoadingStateFromItem = this.removeLoadingStateFromItem.bind(this);
15+
this.updateSelectedLocations = this.updateSelectedLocations.bind(this);
16+
this.renderLeaf = this.renderLeaf.bind(this);
1417

1518
this.state = {
16-
selectedLocations: props.selectedLocations,
1719
currentlyLoadingLocationId: false,
20+
selectedLocationId: null,
1821
};
1922
}
2023

21-
UNSAFE_componentWillReceiveProps(props) {
22-
this.setState((state) =>
23-
Object.assign({}, state, {
24-
selectedLocations: props.selectedLocations,
25-
currentlyLoadingLocationId: false,
26-
})
27-
);
28-
}
29-
3024
/**
3125
* Updates selected locations state
3226
*
@@ -35,19 +29,19 @@ export default class FinderTreeBranchComponent extends Component {
3529
* @memberof FinderTreeBranchComponent
3630
*/
3731
updateSelectedLocations(location) {
38-
this.setState((state) => {
39-
const locations = [...state.selectedLocations, location.id];
40-
41-
return Object.assign({}, state, {
42-
selectedLocations: [...new Set(locations)],
43-
currentlyLoadingLocationId: location.id,
44-
});
45-
});
46-
47-
this.props.onItemClick({
48-
parent: location.id,
49-
location,
50-
});
32+
this.setState(
33+
() => ({ currentlyLoadingLocationId: location.id, selectedLocationId: location.id }),
34+
() =>
35+
this.props.onItemClick({
36+
parent: location.id,
37+
location,
38+
onDataLoaded: this.removeLoadingStateFromItem,
39+
})
40+
);
41+
}
42+
43+
removeLoadingStateFromItem() {
44+
this.setState(() => ({ currentlyLoadingLocationId: false }));
5145
}
5246

5347
expandBranch() {
@@ -69,13 +63,14 @@ export default class FinderTreeBranchComponent extends Component {
6963
const contentTypeHref = location.ContentInfo.Content.ContentType._href;
7064
const isContainer = contentTypesMap && contentTypesMap[contentTypeHref] && contentTypesMap[contentTypeHref].isContainer;
7165
const isSelectable = !(this.props.allowContainersOnly && !isContainer);
66+
const selected = location.id === this.state.selectedLocationId;
7267

7368
return (
7469
<FinderTreeLeafComponent
7570
key={location.remoteId}
7671
location={location}
77-
onClick={this.updateSelectedLocations.bind(this)}
78-
selected={this.state.selectedLocations.includes(location.id)}
72+
onClick={this.updateSelectedLocations}
73+
selected={selected}
7974
isLoadingChildren={isLoadingChildren}
8075
isSelectable={isSelectable}
8176
allowedLocations={this.props.allowedLocations}
@@ -130,7 +125,7 @@ export default class FinderTreeBranchComponent extends Component {
130125
return (
131126
<div {...attrs}>
132127
<div className="c-finder-tree-branch__list-wrapper">
133-
{this.props.items.map(this.renderLeaf.bind(this))}
128+
{this.props.items.map(this.renderLeaf)}
134129
{this.renderLoadMore()}
135130
</div>
136131
</div>

0 commit comments

Comments
 (0)