1 |
|
2 |
|
3 | import { InputGroup } from '@jupyterlab/ui-components';
|
4 | import { StringExt } from '@lumino/algorithm';
|
5 | import React, { useEffect, useState } from 'react';
|
6 | import { ReactWidget } from './vdom';
|
7 |
|
8 |
|
9 |
|
10 | export function fuzzySearch(source, query) {
|
11 |
|
12 | let score = Infinity;
|
13 | let indices = null;
|
14 |
|
15 | const rgx = /\b\w/g;
|
16 | let continueSearch = true;
|
17 |
|
18 | while (continueSearch) {
|
19 |
|
20 | let rgxMatch = rgx.exec(source);
|
21 |
|
22 | if (!rgxMatch) {
|
23 | break;
|
24 | }
|
25 |
|
26 | let match = StringExt.matchSumOfDeltas(source, query, rgxMatch.index);
|
27 |
|
28 | if (!match) {
|
29 | break;
|
30 | }
|
31 |
|
32 | if (match && match.score <= score) {
|
33 | score = match.score;
|
34 | indices = match.indices;
|
35 | }
|
36 | }
|
37 |
|
38 | if (!indices || score === Infinity) {
|
39 | return null;
|
40 | }
|
41 |
|
42 | return {
|
43 | score,
|
44 | indices
|
45 | };
|
46 | }
|
47 | export const updateFilterFunction = (value, useFuzzyFilter, caseSensitive) => {
|
48 | return (item) => {
|
49 | if (useFuzzyFilter) {
|
50 |
|
51 | const query = value.toLowerCase();
|
52 |
|
53 | return fuzzySearch(item, query);
|
54 | }
|
55 | if (!caseSensitive) {
|
56 | item = item.toLocaleLowerCase();
|
57 | value = value.toLocaleLowerCase();
|
58 | }
|
59 | const i = item.indexOf(value);
|
60 | if (i === -1) {
|
61 | return null;
|
62 | }
|
63 | return {
|
64 | indices: [...Array(item.length).keys()].map(x => x + 1)
|
65 | };
|
66 | };
|
67 | };
|
68 | export const FilterBox = (props) => {
|
69 | var _a;
|
70 | const [filter, setFilter] = useState((_a = props.initialQuery) !== null && _a !== void 0 ? _a : '');
|
71 | if (props.forceRefresh) {
|
72 | useEffect(() => {
|
73 | props.updateFilter((item) => {
|
74 | return {};
|
75 | });
|
76 | }, []);
|
77 | }
|
78 | useEffect(() => {
|
79 |
|
80 | if (props.initialQuery !== undefined) {
|
81 | props.updateFilter(updateFilterFunction(props.initialQuery, props.useFuzzyFilter, props.caseSensitive), props.initialQuery);
|
82 | }
|
83 | }, []);
|
84 | |
85 |
|
86 |
|
87 | const handleChange = (e) => {
|
88 | const target = e.target;
|
89 | setFilter(target.value);
|
90 | props.updateFilter(updateFilterFunction(target.value, props.useFuzzyFilter, props.caseSensitive), target.value);
|
91 | };
|
92 | return (React.createElement(InputGroup, { type: "text", rightIcon: "ui-components:search", placeholder: props.placeholder, onChange: handleChange, className: "jp-FilterBox", value: filter }));
|
93 | };
|
94 |
|
95 |
|
96 |
|
97 | export const FilenameSearcher = (props) => {
|
98 | return ReactWidget.create(React.createElement(FilterBox, { updateFilter: props.updateFilter, useFuzzyFilter: props.useFuzzyFilter, placeholder: props.placeholder, forceRefresh: props.forceRefresh, caseSensitive: props.caseSensitive }));
|
99 | };
|
100 |
|
\ | No newline at end of file |