expensify-common 2.0.166 → 2.0.167
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.
|
@@ -193,22 +193,37 @@ class Combobox extends react_1.default.Component {
|
|
|
193
193
|
}
|
|
194
194
|
// eslint-disable-next-line react/no-unsafe
|
|
195
195
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
196
|
-
if (
|
|
197
|
-
|
|
196
|
+
if (nextProps.value && !(0, isEqual_1.default)(nextProps.value, this.state.currentValue)) {
|
|
197
|
+
this.setValue(nextProps.value);
|
|
198
198
|
}
|
|
199
|
-
this.setValue(nextProps.value);
|
|
200
199
|
if (nextProps.options !== undefined) {
|
|
201
200
|
// If the options have an id property, we use that to compare them and determine if they changed, if not
|
|
202
201
|
// we'll use the whole options array.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
const optionsChanged = (0, has_1.default)(nextProps.options, '0.id')
|
|
203
|
+
? nextProps.options.some((option, index) => !(0, isEqual_1.default)(option.id, this.props.options[index] && this.props.options[index].id))
|
|
204
|
+
: !(0, isEqual_1.default)(nextProps.options, this.props.options);
|
|
205
|
+
// Check if alreadySelectedOptions changed - compare by id if available, otherwise by value or full comparison
|
|
206
|
+
const hasAlreadySelectedId = nextProps.alreadySelectedOptions && nextProps.alreadySelectedOptions.length > 0 && (0, has_1.default)(nextProps.alreadySelectedOptions[0], 'id');
|
|
207
|
+
const alreadySelectedChanged = hasAlreadySelectedId
|
|
208
|
+
? nextProps.alreadySelectedOptions.length !== this.props.alreadySelectedOptions.length ||
|
|
209
|
+
nextProps.alreadySelectedOptions.some((alreadySelectedOption, index) => {
|
|
210
|
+
const prevOption = this.props.alreadySelectedOptions[index];
|
|
211
|
+
return !prevOption || !(0, isEqual_1.default)(alreadySelectedOption.id, prevOption.id);
|
|
212
|
+
})
|
|
213
|
+
: !(0, isEqual_1.default)(nextProps.alreadySelectedOptions, this.props.alreadySelectedOptions);
|
|
214
|
+
if (optionsChanged || alreadySelectedChanged) {
|
|
215
|
+
// If only alreadySelectedOptions changed and dropdown is open, just update options without resetting
|
|
216
|
+
if (!optionsChanged && alreadySelectedChanged && this.state.isDropdownOpen) {
|
|
217
|
+
const { currentValue } = this.state;
|
|
218
|
+
this.setState(() => ({
|
|
219
|
+
options: this.getTruncatedOptions(currentValue, nextProps.alreadySelectedOptions),
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Options changed or dropdown is closed - do full reset
|
|
206
224
|
this.reset(false, nextProps.options, nextProps.alreadySelectedOptions);
|
|
207
225
|
}
|
|
208
226
|
}
|
|
209
|
-
else if (!(0, isEqual_1.default)(nextProps.options, this.props.options) || !(0, isEqual_1.default)(nextProps.alreadySelectedOptions, this.props.alreadySelectedOptions)) {
|
|
210
|
-
this.reset(false, nextProps.options, nextProps.alreadySelectedOptions);
|
|
211
|
-
}
|
|
212
227
|
}
|
|
213
228
|
if (nextProps.openOnInit !== undefined && !(0, isEqual_1.default)(nextProps.openOnInit, this.props.openOnInit)) {
|
|
214
229
|
this.setState({
|
|
@@ -431,7 +446,7 @@ class Combobox extends react_1.default.Component {
|
|
|
431
446
|
const dividerIndex = this.options.findIndex(findDivider);
|
|
432
447
|
// Split into two arrays everything before and after the divider (if the divider does not exist then we'll return a single array)
|
|
433
448
|
const splitOptions = dividerIndex ? [this.options.slice(0, dividerIndex + 1), this.options.slice(dividerIndex + 1)] : [this.options];
|
|
434
|
-
const formatOption = (option) => (Object.assign({ focused: false, isSelected: option.selected && (
|
|
449
|
+
const formatOption = (option, index) => (Object.assign({ focused: false, isSelected: (option.selected && (0, isEqual_1.default)(option.value, currentValue)) || !!alreadySelected.find((item) => item.value === option.value), originalIndex: index }, option));
|
|
435
450
|
const sortByOption = (o) => {
|
|
436
451
|
// Unselectable text-only entries (isFake: true) go to the bottom and selected entries go to the top only if alwaysShowSelectedOnTop was passed
|
|
437
452
|
if (o.showLast) {
|
|
@@ -440,11 +455,24 @@ class Combobox extends react_1.default.Component {
|
|
|
440
455
|
return o.isSelected && this.props.alwaysShowSelectedOnTop ? 0 : 1;
|
|
441
456
|
};
|
|
442
457
|
// Take each array and format it, sort it, and move selected items to top (if applicable)
|
|
443
|
-
const formatOptions = (array) =>
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
458
|
+
const formatOptions = (array, arrayStartIndex) => {
|
|
459
|
+
return array
|
|
460
|
+
.map((option, index) => formatOption(option, arrayStartIndex + index))
|
|
461
|
+
.sort((a, b) => {
|
|
462
|
+
const sortDiff = sortByOption(a) - sortByOption(b);
|
|
463
|
+
// If sort priority is the same, preserve original order using originalIndex
|
|
464
|
+
return sortDiff !== 0 ? sortDiff : a.originalIndex - b.originalIndex;
|
|
465
|
+
})
|
|
466
|
+
.slice(0, this.props.maxItemsToShow);
|
|
467
|
+
};
|
|
468
|
+
let cumulativeIndex = 0;
|
|
469
|
+
const truncatedOptions = splitOptions
|
|
470
|
+
.map((array) => {
|
|
471
|
+
const result = formatOptions(array, cumulativeIndex);
|
|
472
|
+
cumulativeIndex += array.length;
|
|
473
|
+
return result;
|
|
474
|
+
})
|
|
475
|
+
.flat();
|
|
448
476
|
if (!truncatedOptions.length) {
|
|
449
477
|
truncatedOptions.push({
|
|
450
478
|
text: 'No items',
|