@crystaldesign/diva-navigator 26.10.0-beta.21 → 26.10.0-beta.23
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.
- package/build/esm/index.js +323 -232
- package/build/types/navigator/src/OrgTreeSelect/orgSearch.d.ts +24 -0
- package/build/types/navigator/src/OrgTreeSelect/orgSearch.d.ts.map +1 -0
- package/build/types/navigator/src/OrgTreeSelect/useTreeSearch.d.ts +2 -2
- package/build/types/navigator/src/OrgTreeSelect/useTreeSearch.d.ts.map +1 -1
- package/build/types/navigator/src/tests/unit/OrgTreeSelect/orgSearch.test.d.ts +2 -0
- package/build/types/navigator/src/tests/unit/OrgTreeSelect/orgSearch.test.d.ts.map +1 -0
- package/build/types/navigator/src/tests/unit/OrgTreeSelect/useTreeSearch.test.d.ts +2 -0
- package/build/types/navigator/src/tests/unit/OrgTreeSelect/useTreeSearch.test.d.ts.map +1 -0
- package/package.json +4 -4
package/build/esm/index.js
CHANGED
|
@@ -347,16 +347,16 @@ function HeaderDropdownPopper(_ref) {
|
|
|
347
347
|
|
|
348
348
|
function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
349
349
|
function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
350
|
-
function _createForOfIteratorHelper$
|
|
351
|
-
function _unsupportedIterableToArray$
|
|
352
|
-
function _arrayLikeToArray$
|
|
350
|
+
function _createForOfIteratorHelper$4(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$4(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
351
|
+
function _unsupportedIterableToArray$4(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$4(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$4(r, a) : void 0; } }
|
|
352
|
+
function _arrayLikeToArray$4(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
353
353
|
/**
|
|
354
354
|
* Returns path of node ids from root to target (inclusive), or null if not found.
|
|
355
355
|
* Use `new Set(result)` for membership checks, or `result.slice(0, -1)` for ancestors only.
|
|
356
356
|
*/
|
|
357
357
|
function findPathToNode(nodes, targetId) {
|
|
358
358
|
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
359
|
-
var _iterator = _createForOfIteratorHelper$
|
|
359
|
+
var _iterator = _createForOfIteratorHelper$4(nodes),
|
|
360
360
|
_step;
|
|
361
361
|
try {
|
|
362
362
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -375,7 +375,7 @@ function findPathToNode(nodes, targetId) {
|
|
|
375
375
|
return null;
|
|
376
376
|
}
|
|
377
377
|
function findNodeInTree(nodes, targetId) {
|
|
378
|
-
var _iterator2 = _createForOfIteratorHelper$
|
|
378
|
+
var _iterator2 = _createForOfIteratorHelper$4(nodes),
|
|
379
379
|
_step2;
|
|
380
380
|
try {
|
|
381
381
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -396,7 +396,7 @@ function findNodeInTree(nodes, targetId) {
|
|
|
396
396
|
function flattenDisplayOrder(nodes, expandedIds) {
|
|
397
397
|
var ids = [];
|
|
398
398
|
var _walk = function walk(list) {
|
|
399
|
-
var _iterator3 = _createForOfIteratorHelper$
|
|
399
|
+
var _iterator3 = _createForOfIteratorHelper$4(list),
|
|
400
400
|
_step3;
|
|
401
401
|
try {
|
|
402
402
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
@@ -423,7 +423,7 @@ function flattenDisplayOrder(nodes, expandedIds) {
|
|
|
423
423
|
*/
|
|
424
424
|
function computeEffectiveScores(nodes, scoreMap) {
|
|
425
425
|
var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Map();
|
|
426
|
-
var _iterator4 = _createForOfIteratorHelper$
|
|
426
|
+
var _iterator4 = _createForOfIteratorHelper$4(nodes),
|
|
427
427
|
_step4;
|
|
428
428
|
try {
|
|
429
429
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
@@ -432,7 +432,7 @@ function computeEffectiveScores(nodes, scoreMap) {
|
|
|
432
432
|
var best = (_scoreMap$get = scoreMap.get(node._id)) !== null && _scoreMap$get !== void 0 ? _scoreMap$get : Infinity;
|
|
433
433
|
if (node.children) {
|
|
434
434
|
computeEffectiveScores(node.children, scoreMap, result);
|
|
435
|
-
var _iterator5 = _createForOfIteratorHelper$
|
|
435
|
+
var _iterator5 = _createForOfIteratorHelper$4(node.children),
|
|
436
436
|
_step5;
|
|
437
437
|
try {
|
|
438
438
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
@@ -477,7 +477,7 @@ function sortTree(nodes, selectedPath, effectiveScores) {
|
|
|
477
477
|
function collectTypes(nodes) {
|
|
478
478
|
var types = new Set();
|
|
479
479
|
var _walk2 = function walk(list) {
|
|
480
|
-
var _iterator6 = _createForOfIteratorHelper$
|
|
480
|
+
var _iterator6 = _createForOfIteratorHelper$4(list),
|
|
481
481
|
_step6;
|
|
482
482
|
try {
|
|
483
483
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
@@ -497,9 +497,9 @@ function collectTypes(nodes) {
|
|
|
497
497
|
|
|
498
498
|
function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
499
499
|
function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
500
|
-
function _createForOfIteratorHelper$
|
|
501
|
-
function _unsupportedIterableToArray$
|
|
502
|
-
function _arrayLikeToArray$
|
|
500
|
+
function _createForOfIteratorHelper$3(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$3(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
501
|
+
function _unsupportedIterableToArray$3(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$3(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$3(r, a) : void 0; } }
|
|
502
|
+
function _arrayLikeToArray$3(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
503
503
|
function treeReducer(state, action) {
|
|
504
504
|
switch (action.type) {
|
|
505
505
|
case 'SET_TREE':
|
|
@@ -509,7 +509,7 @@ function treeReducer(state, action) {
|
|
|
509
509
|
var path = findPathToNode(action.tree, action.selectedId);
|
|
510
510
|
if (path) {
|
|
511
511
|
var ancestors = path.slice(0, -1);
|
|
512
|
-
var _iterator = _createForOfIteratorHelper$
|
|
512
|
+
var _iterator = _createForOfIteratorHelper$3(ancestors),
|
|
513
513
|
_step;
|
|
514
514
|
try {
|
|
515
515
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -535,7 +535,7 @@ function treeReducer(state, action) {
|
|
|
535
535
|
case 'SET_EXPANDED':
|
|
536
536
|
{
|
|
537
537
|
var next = new Set(state.expandedIds);
|
|
538
|
-
var _iterator2 = _createForOfIteratorHelper$
|
|
538
|
+
var _iterator2 = _createForOfIteratorHelper$3(action.nodeIds),
|
|
539
539
|
_step2;
|
|
540
540
|
try {
|
|
541
541
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -632,13 +632,290 @@ function useOrgTree(onSelect) {
|
|
|
632
632
|
};
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
+
function _createForOfIteratorHelper$2(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$2(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
636
|
+
function _unsupportedIterableToArray$2(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$2(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$2(r, a) : void 0; } }
|
|
637
|
+
function _arrayLikeToArray$2(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
638
|
+
|
|
639
|
+
/** Minimal org shape the search operates on, produced by flattening the org tree. */
|
|
640
|
+
|
|
641
|
+
var WORD_BOUNDARY = /[\s\-_./,()&]/;
|
|
642
|
+
/** Added per token that appears left of its predecessor. Affects ranking only, never inclusion. */
|
|
643
|
+
var ORDER_PENALTY = 0.5;
|
|
644
|
+
/** Turns the name length into a sub-rank tie-breaker so shorter names win. */
|
|
645
|
+
var NAME_LENGTH_TIEBREAK = 1000;
|
|
646
|
+
/** Score for a node whose id was pasted verbatim; ranks above every name match. */
|
|
647
|
+
var EXACT_ID_SCORE = -1;
|
|
648
|
+
var FUZZY_THRESHOLD = 0.3;
|
|
649
|
+
/** Below this length the fuzzy error ratio matches almost anything, so short tokens are skipped. */
|
|
650
|
+
var MIN_FUZZY_TOKEN_LENGTH = 4;
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Lowercases and strips diacritics while emitting exactly one character per input
|
|
654
|
+
* character, so positions found in the folded text stay valid indices into the
|
|
655
|
+
* original string and can be used for highlighting.
|
|
656
|
+
*/
|
|
657
|
+
function foldForSearch(text) {
|
|
658
|
+
var folded = '';
|
|
659
|
+
for (var i = 0; i < text.length; i++) {
|
|
660
|
+
var _char = text[i];
|
|
661
|
+
var lower = _char.toLowerCase();
|
|
662
|
+
if (lower.length !== 1) {
|
|
663
|
+
folded += _char;
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
var decomposed = lower.normalize('NFD');
|
|
667
|
+
folded += decomposed.length > 1 ? decomposed[0] : lower;
|
|
668
|
+
}
|
|
669
|
+
return folded;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/** Splits a raw query into folded, non-empty tokens. */
|
|
673
|
+
function tokenizeQuery(query) {
|
|
674
|
+
return foldForSearch(query).trim().split(/\s+/).filter(Boolean);
|
|
675
|
+
}
|
|
676
|
+
function findOccurrences(haystack, token) {
|
|
677
|
+
var positions = [];
|
|
678
|
+
var from = 0;
|
|
679
|
+
for (;;) {
|
|
680
|
+
var at = haystack.indexOf(token, from);
|
|
681
|
+
if (at === -1) return positions;
|
|
682
|
+
positions.push(at);
|
|
683
|
+
from = at + 1;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/** 0 = match at the start of the name, 1 = at the start of a word, 2 = inside a word. */
|
|
688
|
+
function positionRank(haystack, at) {
|
|
689
|
+
if (at === 0) return 0;
|
|
690
|
+
return WORD_BOUNDARY.test(haystack[at - 1]) ? 1 : 2;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Requires every token to occur in the name, in any order and with any number of
|
|
694
|
+
* words in between. Returns null as soon as one token is missing.
|
|
695
|
+
*/
|
|
696
|
+
function matchAllTokens(displayName, tokens) {
|
|
697
|
+
var haystack = foldForSearch(displayName);
|
|
698
|
+
var ranges = [];
|
|
699
|
+
var bestPositions = [];
|
|
700
|
+
var positionScore = 0;
|
|
701
|
+
var _iterator = _createForOfIteratorHelper$2(tokens),
|
|
702
|
+
_step;
|
|
703
|
+
try {
|
|
704
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
705
|
+
var token = _step.value;
|
|
706
|
+
var positions = findOccurrences(haystack, token);
|
|
707
|
+
if (positions.length === 0) return null;
|
|
708
|
+
var bestRank = positionRank(haystack, positions[0]);
|
|
709
|
+
var bestPosition = positions[0];
|
|
710
|
+
var _iterator2 = _createForOfIteratorHelper$2(positions),
|
|
711
|
+
_step2;
|
|
712
|
+
try {
|
|
713
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
714
|
+
var at = _step2.value;
|
|
715
|
+
ranges.push([at, at + token.length - 1]);
|
|
716
|
+
var rank = positionRank(haystack, at);
|
|
717
|
+
if (rank < bestRank) {
|
|
718
|
+
bestRank = rank;
|
|
719
|
+
bestPosition = at;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
} catch (err) {
|
|
723
|
+
_iterator2.e(err);
|
|
724
|
+
} finally {
|
|
725
|
+
_iterator2.f();
|
|
726
|
+
}
|
|
727
|
+
positionScore += bestRank;
|
|
728
|
+
bestPositions.push(bestPosition);
|
|
729
|
+
}
|
|
730
|
+
} catch (err) {
|
|
731
|
+
_iterator.e(err);
|
|
732
|
+
} finally {
|
|
733
|
+
_iterator.f();
|
|
734
|
+
}
|
|
735
|
+
var outOfOrder = 0;
|
|
736
|
+
for (var i = 1; i < bestPositions.length; i++) {
|
|
737
|
+
if (bestPositions[i] < bestPositions[i - 1]) outOfOrder++;
|
|
738
|
+
}
|
|
739
|
+
var score = positionScore / tokens.length + outOfOrder * ORDER_PENALTY + displayName.length / NAME_LENGTH_TIEBREAK;
|
|
740
|
+
return {
|
|
741
|
+
ranges: ranges,
|
|
742
|
+
score: score
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/** Creates the Fuse index for the typo-tolerant fallback. Memoize this per item list. */
|
|
747
|
+
function createOrgFuse(items) {
|
|
748
|
+
return new Fuse(items, {
|
|
749
|
+
keys: ['displayName'],
|
|
750
|
+
getFn: function getFn(item) {
|
|
751
|
+
return foldForSearch(item.displayName);
|
|
752
|
+
},
|
|
753
|
+
threshold: FUZZY_THRESHOLD,
|
|
754
|
+
ignoreLocation: true,
|
|
755
|
+
includeScore: true
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Typo-tolerant fallback. Intersects the per-token hits so a multi-word query still
|
|
761
|
+
* narrows, and returns no scores at all when any token has no fuzzy hit.
|
|
762
|
+
*/
|
|
763
|
+
function searchFuzzy(fuse, tokens) {
|
|
764
|
+
var _intersection;
|
|
765
|
+
var usableTokens = tokens.filter(function (token) {
|
|
766
|
+
return token.length >= MIN_FUZZY_TOKEN_LENGTH;
|
|
767
|
+
});
|
|
768
|
+
if (usableTokens.length === 0) return new Map();
|
|
769
|
+
var summedScores = new Map();
|
|
770
|
+
var intersection = null;
|
|
771
|
+
var _iterator3 = _createForOfIteratorHelper$2(usableTokens),
|
|
772
|
+
_step3;
|
|
773
|
+
try {
|
|
774
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
775
|
+
var token = _step3.value;
|
|
776
|
+
var hits = new Map();
|
|
777
|
+
var _iterator5 = _createForOfIteratorHelper$2(fuse.search(token)),
|
|
778
|
+
_step5;
|
|
779
|
+
try {
|
|
780
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
781
|
+
var _result$score;
|
|
782
|
+
var _result = _step5.value;
|
|
783
|
+
hits.set(_result.item._id, (_result$score = _result.score) !== null && _result$score !== void 0 ? _result$score : 1);
|
|
784
|
+
}
|
|
785
|
+
} catch (err) {
|
|
786
|
+
_iterator5.e(err);
|
|
787
|
+
} finally {
|
|
788
|
+
_iterator5.f();
|
|
789
|
+
}
|
|
790
|
+
if (hits.size === 0) return new Map();
|
|
791
|
+
var _iterator6 = _createForOfIteratorHelper$2(hits),
|
|
792
|
+
_step6;
|
|
793
|
+
try {
|
|
794
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
795
|
+
var _summedScores$get;
|
|
796
|
+
var _step6$value = _slicedToArray(_step6.value, 2),
|
|
797
|
+
_id = _step6$value[0],
|
|
798
|
+
score = _step6$value[1];
|
|
799
|
+
summedScores.set(_id, ((_summedScores$get = summedScores.get(_id)) !== null && _summedScores$get !== void 0 ? _summedScores$get : 0) + score);
|
|
800
|
+
}
|
|
801
|
+
} catch (err) {
|
|
802
|
+
_iterator6.e(err);
|
|
803
|
+
} finally {
|
|
804
|
+
_iterator6.f();
|
|
805
|
+
}
|
|
806
|
+
if (intersection === null) {
|
|
807
|
+
intersection = new Set(hits.keys());
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
for (var _i = 0, _arr = _toConsumableArray(intersection); _i < _arr.length; _i++) {
|
|
811
|
+
var id = _arr[_i];
|
|
812
|
+
if (!hits.has(id)) intersection["delete"](id);
|
|
813
|
+
}
|
|
814
|
+
if (intersection.size === 0) return new Map();
|
|
815
|
+
}
|
|
816
|
+
} catch (err) {
|
|
817
|
+
_iterator3.e(err);
|
|
818
|
+
} finally {
|
|
819
|
+
_iterator3.f();
|
|
820
|
+
}
|
|
821
|
+
var result = new Map();
|
|
822
|
+
var _iterator4 = _createForOfIteratorHelper$2((_intersection = intersection) !== null && _intersection !== void 0 ? _intersection : []),
|
|
823
|
+
_step4;
|
|
824
|
+
try {
|
|
825
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
826
|
+
var _summedScores$get2;
|
|
827
|
+
var _id2 = _step4.value;
|
|
828
|
+
result.set(_id2, (_summedScores$get2 = summedScores.get(_id2)) !== null && _summedScores$get2 !== void 0 ? _summedScores$get2 : 1);
|
|
829
|
+
}
|
|
830
|
+
} catch (err) {
|
|
831
|
+
_iterator4.e(err);
|
|
832
|
+
} finally {
|
|
833
|
+
_iterator4.f();
|
|
834
|
+
}
|
|
835
|
+
return result;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Matches orgs by display name: every query token must occur in the name, in any
|
|
840
|
+
* order and with any words in between. A single-token query also matches an org id
|
|
841
|
+
* verbatim. Fuzzy matching runs only when nothing matched literally, so a typo
|
|
842
|
+
* still finds its org without letting fuzzy noise into normal results.
|
|
843
|
+
*/
|
|
844
|
+
function searchOrgs(items, query, fuse) {
|
|
845
|
+
var matchedIds = new Set();
|
|
846
|
+
var matchIndicesMap = new Map();
|
|
847
|
+
var scoreMap = new Map();
|
|
848
|
+
var tokens = tokenizeQuery(query);
|
|
849
|
+
if (tokens.length === 0) return {
|
|
850
|
+
matchedIds: matchedIds,
|
|
851
|
+
matchIndicesMap: matchIndicesMap,
|
|
852
|
+
scoreMap: scoreMap
|
|
853
|
+
};
|
|
854
|
+
var _iterator7 = _createForOfIteratorHelper$2(items),
|
|
855
|
+
_step7;
|
|
856
|
+
try {
|
|
857
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
858
|
+
var _item = _step7.value;
|
|
859
|
+
var match = matchAllTokens(_item.displayName, tokens);
|
|
860
|
+
if (!match) continue;
|
|
861
|
+
matchedIds.add(_item._id);
|
|
862
|
+
matchIndicesMap.set(_item._id, match.ranges);
|
|
863
|
+
scoreMap.set(_item._id, match.score);
|
|
864
|
+
}
|
|
865
|
+
} catch (err) {
|
|
866
|
+
_iterator7.e(err);
|
|
867
|
+
} finally {
|
|
868
|
+
_iterator7.f();
|
|
869
|
+
}
|
|
870
|
+
if (tokens.length === 1) {
|
|
871
|
+
var _iterator8 = _createForOfIteratorHelper$2(items),
|
|
872
|
+
_step8;
|
|
873
|
+
try {
|
|
874
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
875
|
+
var item = _step8.value;
|
|
876
|
+
if (foldForSearch(item._id) !== tokens[0]) continue;
|
|
877
|
+
matchedIds.add(item._id);
|
|
878
|
+
scoreMap.set(item._id, EXACT_ID_SCORE);
|
|
879
|
+
}
|
|
880
|
+
} catch (err) {
|
|
881
|
+
_iterator8.e(err);
|
|
882
|
+
} finally {
|
|
883
|
+
_iterator8.f();
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
if (matchedIds.size > 0) return {
|
|
887
|
+
matchedIds: matchedIds,
|
|
888
|
+
matchIndicesMap: matchIndicesMap,
|
|
889
|
+
scoreMap: scoreMap
|
|
890
|
+
};
|
|
891
|
+
var _iterator9 = _createForOfIteratorHelper$2(searchFuzzy(fuse, tokens)),
|
|
892
|
+
_step9;
|
|
893
|
+
try {
|
|
894
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
895
|
+
var _step9$value = _slicedToArray(_step9.value, 2),
|
|
896
|
+
id = _step9$value[0],
|
|
897
|
+
score = _step9$value[1];
|
|
898
|
+
matchedIds.add(id);
|
|
899
|
+
scoreMap.set(id, score);
|
|
900
|
+
}
|
|
901
|
+
} catch (err) {
|
|
902
|
+
_iterator9.e(err);
|
|
903
|
+
} finally {
|
|
904
|
+
_iterator9.f();
|
|
905
|
+
}
|
|
906
|
+
return {
|
|
907
|
+
matchedIds: matchedIds,
|
|
908
|
+
matchIndicesMap: matchIndicesMap,
|
|
909
|
+
scoreMap: scoreMap
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
|
|
635
913
|
function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
636
914
|
function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
637
915
|
function _createForOfIteratorHelper$1(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$1(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
638
916
|
function _unsupportedIterableToArray$1(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$1(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0; } }
|
|
639
917
|
function _arrayLikeToArray$1(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
640
918
|
function flattenTree(nodes) {
|
|
641
|
-
var ancestors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
642
919
|
var result = [];
|
|
643
920
|
var _iterator = _createForOfIteratorHelper$1(nodes),
|
|
644
921
|
_step;
|
|
@@ -647,11 +924,10 @@ function flattenTree(nodes) {
|
|
|
647
924
|
var node = _step.value;
|
|
648
925
|
result.push({
|
|
649
926
|
_id: node._id,
|
|
650
|
-
displayName: node.displayName
|
|
651
|
-
ancestorIds: ancestors
|
|
927
|
+
displayName: node.displayName
|
|
652
928
|
});
|
|
653
929
|
if (node.children) {
|
|
654
|
-
result.push.apply(result, _toConsumableArray(flattenTree(node.children
|
|
930
|
+
result.push.apply(result, _toConsumableArray(flattenTree(node.children)));
|
|
655
931
|
}
|
|
656
932
|
}
|
|
657
933
|
} catch (err) {
|
|
@@ -681,33 +957,30 @@ function annotateSubtree(nodes, matchedIds, matchIndicesMap) {
|
|
|
681
957
|
}
|
|
682
958
|
|
|
683
959
|
/**
|
|
684
|
-
*
|
|
685
|
-
*
|
|
960
|
+
* Reduces the tree to matched nodes (keeping their full subtrees) plus the
|
|
961
|
+
* ancestors needed to keep the surrounding structure visible.
|
|
686
962
|
*/
|
|
687
|
-
function filterTree(nodes,
|
|
688
|
-
var hasTextSearch = matchedIds != null && matchIndicesMap != null;
|
|
963
|
+
function filterTree(nodes, matchedIds, matchIndicesMap) {
|
|
689
964
|
var result = [];
|
|
690
965
|
var _iterator2 = _createForOfIteratorHelper$1(nodes),
|
|
691
966
|
_step2;
|
|
692
967
|
try {
|
|
693
968
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
694
969
|
var node = _step2.value;
|
|
695
|
-
|
|
696
|
-
var directMatch = hasTextSearch ? matchedIds.has(node._id) && typeOk : typeFilters.has(node.orgType);
|
|
697
|
-
if (directMatch) {
|
|
970
|
+
if (matchedIds.has(node._id)) {
|
|
698
971
|
result.push(_objectSpread$2(_objectSpread$2({}, node), {}, {
|
|
699
972
|
matched: true,
|
|
700
|
-
matchIndices:
|
|
701
|
-
children: node.children ? annotateSubtree(node.children,
|
|
973
|
+
matchIndices: matchIndicesMap.get(node._id),
|
|
974
|
+
children: node.children ? annotateSubtree(node.children, matchedIds, matchIndicesMap) : undefined
|
|
975
|
+
}));
|
|
976
|
+
continue;
|
|
977
|
+
}
|
|
978
|
+
var filteredChildren = node.children ? filterTree(node.children, matchedIds, matchIndicesMap) : undefined;
|
|
979
|
+
if (filteredChildren && filteredChildren.length > 0) {
|
|
980
|
+
result.push(_objectSpread$2(_objectSpread$2({}, node), {}, {
|
|
981
|
+
matched: false,
|
|
982
|
+
children: filteredChildren
|
|
702
983
|
}));
|
|
703
|
-
} else {
|
|
704
|
-
var filteredChildren = node.children ? filterTree(node.children, typeFilters, matchedIds, matchIndicesMap) : undefined;
|
|
705
|
-
if (filteredChildren && filteredChildren.length > 0) {
|
|
706
|
-
result.push(_objectSpread$2(_objectSpread$2({}, node), {}, {
|
|
707
|
-
matched: false,
|
|
708
|
-
children: filteredChildren
|
|
709
|
-
}));
|
|
710
|
-
}
|
|
711
984
|
}
|
|
712
985
|
}
|
|
713
986
|
} catch (err) {
|
|
@@ -721,6 +994,8 @@ function filterTree(nodes, typeFilters, matchedIds, matchIndicesMap) {
|
|
|
721
994
|
/**
|
|
722
995
|
* Returns matching nodes with their full subtrees, flattened out of the
|
|
723
996
|
* original hierarchy. Used to scope text search to type-matched nodes only.
|
|
997
|
+
* Descendants of a match are not emitted again: they are already visible inside
|
|
998
|
+
* the subtree that was kept.
|
|
724
999
|
*/
|
|
725
1000
|
function filterTreeByTypesOnly(nodes, typeFilters) {
|
|
726
1001
|
var result = [];
|
|
@@ -734,6 +1009,7 @@ function filterTreeByTypesOnly(nodes, typeFilters) {
|
|
|
734
1009
|
matched: true,
|
|
735
1010
|
children: node.children ? annotateSubtree(node.children) : undefined
|
|
736
1011
|
}));
|
|
1012
|
+
continue;
|
|
737
1013
|
}
|
|
738
1014
|
if (node.children) {
|
|
739
1015
|
result.push.apply(result, _toConsumableArray(filterTreeByTypesOnly(node.children, typeFilters)));
|
|
@@ -746,203 +1022,25 @@ function filterTreeByTypesOnly(nodes, typeFilters) {
|
|
|
746
1022
|
}
|
|
747
1023
|
return result;
|
|
748
1024
|
}
|
|
749
|
-
|
|
750
|
-
/**
|
|
751
|
-
* Fuse.js indices include noisy single-char overlaps outside the actual match region.
|
|
752
|
-
* Finds the densest cluster of matched chars within a pattern-sized window and
|
|
753
|
-
* drops indices outside it.
|
|
754
|
-
*/
|
|
755
|
-
function filterMatchIndices(indices, patternLength) {
|
|
756
|
-
if (indices.length <= 1) return indices;
|
|
757
|
-
var windowSize = patternLength + 2;
|
|
758
|
-
var positions = [];
|
|
759
|
-
var _iterator4 = _createForOfIteratorHelper$1(indices),
|
|
760
|
-
_step4;
|
|
761
|
-
try {
|
|
762
|
-
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
763
|
-
var _step4$value = _slicedToArray(_step4.value, 2),
|
|
764
|
-
start = _step4$value[0],
|
|
765
|
-
end = _step4$value[1];
|
|
766
|
-
for (var i = start; i <= end; i++) positions.push(i);
|
|
767
|
-
}
|
|
768
|
-
} catch (err) {
|
|
769
|
-
_iterator4.e(err);
|
|
770
|
-
} finally {
|
|
771
|
-
_iterator4.f();
|
|
772
|
-
}
|
|
773
|
-
positions.sort(function (a, b) {
|
|
774
|
-
return a - b;
|
|
775
|
-
});
|
|
776
|
-
if (positions.length === 0) return indices;
|
|
777
|
-
var bestLeft = 0;
|
|
778
|
-
var bestRight = 0;
|
|
779
|
-
var bestCount = 0;
|
|
780
|
-
var left = 0;
|
|
781
|
-
for (var right = 0; right < positions.length; right++) {
|
|
782
|
-
while (positions[right] - positions[left] >= windowSize) left++;
|
|
783
|
-
if (right - left + 1 > bestCount) {
|
|
784
|
-
bestCount = right - left + 1;
|
|
785
|
-
bestLeft = positions[left];
|
|
786
|
-
bestRight = positions[right];
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
return indices.filter(function (_ref) {
|
|
790
|
-
var _ref2 = _slicedToArray(_ref, 2),
|
|
791
|
-
start = _ref2[0],
|
|
792
|
-
end = _ref2[1];
|
|
793
|
-
return end >= bestLeft && start <= bestRight;
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Returns 0 for match at start of string, 1 for start of a word, 2 for mid-word.
|
|
799
|
-
* Used to boost score so matches at word boundaries rank higher.
|
|
800
|
-
*/
|
|
801
|
-
function getMatchPositionScore(arg) {
|
|
802
|
-
var _arg$matches;
|
|
803
|
-
if (!((_arg$matches = arg.matches) !== null && _arg$matches !== void 0 && _arg$matches.length)) return 3;
|
|
804
|
-
var best = 3;
|
|
805
|
-
var _iterator5 = _createForOfIteratorHelper$1(arg.matches),
|
|
806
|
-
_step5;
|
|
807
|
-
try {
|
|
808
|
-
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
809
|
-
var _match$indices, _match$value;
|
|
810
|
-
var match = _step5.value;
|
|
811
|
-
if (!((_match$indices = match.indices) !== null && _match$indices !== void 0 && _match$indices.length)) continue;
|
|
812
|
-
var startIdx = match.indices[0][0];
|
|
813
|
-
if (startIdx === 0) return 0;
|
|
814
|
-
var charBefore = (_match$value = match.value) === null || _match$value === void 0 ? void 0 : _match$value[startIdx - 1];
|
|
815
|
-
if (charBefore !== undefined && /[\s\-_./,()]/.test(charBefore)) best = Math.min(best, 1);else best = Math.min(best, 2);
|
|
816
|
-
}
|
|
817
|
-
} catch (err) {
|
|
818
|
-
_iterator5.e(err);
|
|
819
|
-
} finally {
|
|
820
|
-
_iterator5.f();
|
|
821
|
-
}
|
|
822
|
-
return best;
|
|
823
|
-
}
|
|
824
1025
|
function collectExpandedIds(nodes) {
|
|
825
1026
|
var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
|
|
826
|
-
var
|
|
827
|
-
|
|
1027
|
+
var _iterator4 = _createForOfIteratorHelper$1(nodes),
|
|
1028
|
+
_step4;
|
|
828
1029
|
try {
|
|
829
|
-
for (
|
|
830
|
-
var node =
|
|
1030
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
1031
|
+
var node = _step4.value;
|
|
831
1032
|
if (node.children && node.children.length > 0) {
|
|
832
1033
|
result.add(node._id);
|
|
833
1034
|
collectExpandedIds(node.children, result);
|
|
834
1035
|
}
|
|
835
1036
|
}
|
|
836
1037
|
} catch (err) {
|
|
837
|
-
|
|
1038
|
+
_iterator4.e(err);
|
|
838
1039
|
} finally {
|
|
839
|
-
|
|
1040
|
+
_iterator4.f();
|
|
840
1041
|
}
|
|
841
1042
|
return result;
|
|
842
1043
|
}
|
|
843
|
-
var MAX_FUSE_SCORE = 0.4;
|
|
844
|
-
var POSITION_WEIGHT = 0.15;
|
|
845
|
-
var MATCH_COUNT_BONUS = 0.5;
|
|
846
|
-
function collectExactIdMatches(flatItems, query) {
|
|
847
|
-
var normalizedQuery = query.trim().toLowerCase();
|
|
848
|
-
if (!normalizedQuery) return new Set();
|
|
849
|
-
return new Set(flatItems.filter(function (item) {
|
|
850
|
-
return item._id.toLowerCase() === normalizedQuery;
|
|
851
|
-
}).map(function (item) {
|
|
852
|
-
return item._id;
|
|
853
|
-
}));
|
|
854
|
-
}
|
|
855
|
-
function performSearch(fuse, flatItems, query) {
|
|
856
|
-
var words = query.trim().split(/\s+/);
|
|
857
|
-
var matchedIds = new Set();
|
|
858
|
-
var matchIndicesMap = new Map();
|
|
859
|
-
var scoreMap = new Map();
|
|
860
|
-
var _iterator7 = _createForOfIteratorHelper$1(words),
|
|
861
|
-
_step7;
|
|
862
|
-
try {
|
|
863
|
-
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
864
|
-
var word = _step7.value;
|
|
865
|
-
var results = fuse.search(word).filter(function (r) {
|
|
866
|
-
var _r$score;
|
|
867
|
-
return ((_r$score = r.score) !== null && _r$score !== void 0 ? _r$score : 1) <= MAX_FUSE_SCORE;
|
|
868
|
-
});
|
|
869
|
-
var _iterator9 = _createForOfIteratorHelper$1(results),
|
|
870
|
-
_step9;
|
|
871
|
-
try {
|
|
872
|
-
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
873
|
-
var _scoreMap$get, _result$score;
|
|
874
|
-
var result = _step9.value;
|
|
875
|
-
var prev = (_scoreMap$get = scoreMap.get(result.item._id)) !== null && _scoreMap$get !== void 0 ? _scoreMap$get : 0;
|
|
876
|
-
// getMatchPositionScore returns rank (0 best -> 2 worst). Convert to boost
|
|
877
|
-
// so stronger positional matches receive larger score reductions.
|
|
878
|
-
var positionRank = getMatchPositionScore(result);
|
|
879
|
-
var positionBonus = Math.max(0, 2 - Math.min(positionRank, 2)) * POSITION_WEIGHT;
|
|
880
|
-
scoreMap.set(result.item._id, prev + ((_result$score = result.score) !== null && _result$score !== void 0 ? _result$score : 0) - positionBonus - MATCH_COUNT_BONUS);
|
|
881
|
-
if (result.matches) {
|
|
882
|
-
var _iterator10 = _createForOfIteratorHelper$1(result.matches),
|
|
883
|
-
_step10;
|
|
884
|
-
try {
|
|
885
|
-
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
886
|
-
var match = _step10.value;
|
|
887
|
-
if (match.indices && match.key === 'displayName') {
|
|
888
|
-
var _matchIndicesMap$get;
|
|
889
|
-
var cleaned = filterMatchIndices(match.indices, word.length);
|
|
890
|
-
var existing = (_matchIndicesMap$get = matchIndicesMap.get(result.item._id)) !== null && _matchIndicesMap$get !== void 0 ? _matchIndicesMap$get : [];
|
|
891
|
-
matchIndicesMap.set(result.item._id, [].concat(_toConsumableArray(existing), _toConsumableArray(cleaned)));
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
} catch (err) {
|
|
895
|
-
_iterator10.e(err);
|
|
896
|
-
} finally {
|
|
897
|
-
_iterator10.f();
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
} catch (err) {
|
|
902
|
-
_iterator9.e(err);
|
|
903
|
-
} finally {
|
|
904
|
-
_iterator9.f();
|
|
905
|
-
}
|
|
906
|
-
matchedIds = matchedIds.union(new Set(results.map(function (r) {
|
|
907
|
-
return r.item._id;
|
|
908
|
-
})));
|
|
909
|
-
}
|
|
910
|
-
} catch (err) {
|
|
911
|
-
_iterator7.e(err);
|
|
912
|
-
} finally {
|
|
913
|
-
_iterator7.f();
|
|
914
|
-
}
|
|
915
|
-
var exactIdMatchedIds = collectExactIdMatches(flatItems, query);
|
|
916
|
-
var _iterator8 = _createForOfIteratorHelper$1(exactIdMatchedIds),
|
|
917
|
-
_step8;
|
|
918
|
-
try {
|
|
919
|
-
var _loop = function _loop() {
|
|
920
|
-
var _scoreMap$get2;
|
|
921
|
-
var matchedId = _step8.value;
|
|
922
|
-
matchedIds.add(matchedId);
|
|
923
|
-
var prev = (_scoreMap$get2 = scoreMap.get(matchedId)) !== null && _scoreMap$get2 !== void 0 ? _scoreMap$get2 : 0;
|
|
924
|
-
scoreMap.set(matchedId, prev - 1);
|
|
925
|
-
var matchedItem = flatItems.find(function (item) {
|
|
926
|
-
return item._id === matchedId;
|
|
927
|
-
});
|
|
928
|
-
if (matchedItem && matchedItem.displayName.length > 0) {
|
|
929
|
-
matchIndicesMap.set(matchedId, [[0, matchedItem.displayName.length - 1]]);
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
933
|
-
_loop();
|
|
934
|
-
}
|
|
935
|
-
} catch (err) {
|
|
936
|
-
_iterator8.e(err);
|
|
937
|
-
} finally {
|
|
938
|
-
_iterator8.f();
|
|
939
|
-
}
|
|
940
|
-
return {
|
|
941
|
-
matchedIds: matchedIds,
|
|
942
|
-
matchIndicesMap: matchIndicesMap,
|
|
943
|
-
scoreMap: scoreMap
|
|
944
|
-
};
|
|
945
|
-
}
|
|
946
1044
|
function useTreeSearch(tree) {
|
|
947
1045
|
var _useState = useState(''),
|
|
948
1046
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -970,14 +1068,7 @@ function useTreeSearch(tree) {
|
|
|
970
1068
|
return flattenTree(treeForSearch);
|
|
971
1069
|
}, [treeForSearch]);
|
|
972
1070
|
var fuse = useMemo(function () {
|
|
973
|
-
return
|
|
974
|
-
keys: ['displayName'],
|
|
975
|
-
threshold: MAX_FUSE_SCORE,
|
|
976
|
-
ignoreLocation: true,
|
|
977
|
-
findAllMatches: true,
|
|
978
|
-
includeMatches: true,
|
|
979
|
-
includeScore: true
|
|
980
|
-
});
|
|
1071
|
+
return createOrgFuse(flatItems);
|
|
981
1072
|
}, [flatItems]);
|
|
982
1073
|
var _useMemo = useMemo(function () {
|
|
983
1074
|
var emptyScoreMap = new Map();
|
|
@@ -991,11 +1082,11 @@ function useTreeSearch(tree) {
|
|
|
991
1082
|
};
|
|
992
1083
|
}
|
|
993
1084
|
if (hasTextSearch) {
|
|
994
|
-
var
|
|
995
|
-
matchedIds =
|
|
996
|
-
matchIndicesMap =
|
|
997
|
-
_scoreMap =
|
|
998
|
-
var filtered = filterTree(treeForSearch,
|
|
1085
|
+
var _searchOrgs = searchOrgs(flatItems, deferredQuery, fuse),
|
|
1086
|
+
matchedIds = _searchOrgs.matchedIds,
|
|
1087
|
+
matchIndicesMap = _searchOrgs.matchIndicesMap,
|
|
1088
|
+
_scoreMap = _searchOrgs.scoreMap;
|
|
1089
|
+
var filtered = filterTree(treeForSearch, matchedIds, matchIndicesMap);
|
|
999
1090
|
var expandedIds = filtered ? collectExpandedIds(filtered) : new Set();
|
|
1000
1091
|
return {
|
|
1001
1092
|
filteredTree: filtered !== null && filtered !== void 0 ? filtered : [],
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Fuse from 'fuse.js';
|
|
2
|
+
/** Minimal org shape the search operates on, produced by flattening the org tree. */
|
|
3
|
+
export interface SearchableOrg {
|
|
4
|
+
_id: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface OrgSearchResult {
|
|
8
|
+
matchedIds: Set<string>;
|
|
9
|
+
matchIndicesMap: Map<string, ReadonlyArray<readonly [number, number]>>;
|
|
10
|
+
/** Lower is better; consumed by `computeEffectiveScores` / `sortTree`. */
|
|
11
|
+
scoreMap: Map<string, number>;
|
|
12
|
+
}
|
|
13
|
+
/** Splits a raw query into folded, non-empty tokens. */
|
|
14
|
+
export declare function tokenizeQuery(query: string): string[];
|
|
15
|
+
/** Creates the Fuse index for the typo-tolerant fallback. Memoize this per item list. */
|
|
16
|
+
export declare function createOrgFuse(items: SearchableOrg[]): Fuse<SearchableOrg>;
|
|
17
|
+
/**
|
|
18
|
+
* Matches orgs by display name: every query token must occur in the name, in any
|
|
19
|
+
* order and with any words in between. A single-token query also matches an org id
|
|
20
|
+
* verbatim. Fuzzy matching runs only when nothing matched literally, so a typo
|
|
21
|
+
* still finds its org without letting fuzzy noise into normal results.
|
|
22
|
+
*/
|
|
23
|
+
export declare function searchOrgs(items: SearchableOrg[], query: string, fuse: Fuse<SearchableOrg>): OrgSearchResult;
|
|
24
|
+
//# sourceMappingURL=orgSearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgSearch.d.ts","sourceRoot":"","sources":["../../../../../src/OrgTreeSelect/orgSearch.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE,0EAA0E;IAC1E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAiCD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAErD;AA6DD,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,CAQzE;AAmCD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,eAAe,CA+B5G"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { OrgTreeNode, OrgType } from './types';
|
|
1
|
+
import { OrgTreeNode, FilteredOrgTreeNode, OrgType } from './types';
|
|
2
2
|
export default function useTreeSearch(tree: OrgTreeNode[]): {
|
|
3
3
|
searchQuery: string;
|
|
4
4
|
onSearchChange: (value: string) => void;
|
|
5
5
|
typeFilters: Set<OrgType>;
|
|
6
6
|
toggleTypeFilter: (type: OrgType) => void;
|
|
7
|
-
filteredTree:
|
|
7
|
+
filteredTree: FilteredOrgTreeNode[] | null;
|
|
8
8
|
searchExpandedIds: Set<string> | null;
|
|
9
9
|
scoreMap: Map<string, number>;
|
|
10
10
|
isSearchActive: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTreeSearch.d.ts","sourceRoot":"","sources":["../../../../../src/OrgTreeSelect/useTreeSearch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useTreeSearch.d.ts","sourceRoot":"","sources":["../../../../../src/OrgTreeSelect/useTreeSearch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAqGpE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE;;4BAKZ,MAAM;;6BAIL,OAAO;;;;;EA8CpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgSearch.test.d.ts","sourceRoot":"","sources":["../../../../../../../src/tests/unit/OrgTreeSelect/orgSearch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTreeSearch.test.d.ts","sourceRoot":"","sources":["../../../../../../../src/tests/unit/OrgTreeSelect/useTreeSearch.test.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crystaldesign/diva-navigator",
|
|
3
|
-
"version": "26.10.0-beta.
|
|
3
|
+
"version": "26.10.0-beta.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@testing-library/jest-dom": "^6.5.0",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"react-dom": "18.3.1"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@crystaldesign/content-item": "26.10.0-beta.
|
|
14
|
-
"@crystaldesign/organization-selection": "26.10.0-beta.
|
|
13
|
+
"@crystaldesign/content-item": "26.10.0-beta.23",
|
|
14
|
+
"@crystaldesign/organization-selection": "26.10.0-beta.23",
|
|
15
15
|
"classnames": "^2.5.1",
|
|
16
16
|
"fuse.js": "^7.0.0",
|
|
17
17
|
"html5-qrcode": "^2.3.8",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
},
|
|
28
28
|
"module": "build/esm/index.js",
|
|
29
29
|
"types": "./build/types/navigator/src/index.d.ts",
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "b2e70ecdffcda726f5abaf4834ac6e1fdf8d7b22"
|
|
31
31
|
}
|