diff --git a/package.json b/package.json index 086db6e4c..1c5267092 100644 --- a/package.json +++ b/package.json @@ -176,6 +176,7 @@ "webpack-dev-middleware": "^3.4.0", "webpack-hot-middleware": "^2.24.2", "workbox-webpack-plugin": "^3.6.1", + "worker-loader": "^2.0.0", "yaml-jest": "^1.0.5", "yaml-loader": "^0.5.0" }, diff --git a/source/components/SearchBar.js b/source/components/SearchBar.js index b1a95a0dd..c45c66d40 100644 --- a/source/components/SearchBar.js +++ b/source/components/SearchBar.js @@ -1,50 +1,87 @@ import withSitePaths from 'Components/utils/withSitePaths' -import { encodeRuleName } from 'Engine/rules' -import Fuse from 'fuse.js' -import { compose, pick, sortBy } from 'ramda' -import React, { useMemo, useRef, useState } from 'react' +import { encodeRuleName, parentName } from 'Engine/rules.js' +import { compose, pick, sortBy, take } from 'ramda' +import React, { useEffect, useState } from 'react' import Highlighter from 'react-highlight-words' import { useTranslation } from 'react-i18next' import { Link, Redirect } from 'react-router-dom' -import Select from 'react-select' -import 'react-select/dist/react-select.css' +import Worker from 'worker-loader!./SearchBar.worker.js' import { capitalise0 } from '../utils' -function SearchBar({ +const worker = new Worker() + +let SearchBar = ({ rules, showDefaultList, finally: finallyCallback, sitePaths -}) { - const [inputValue, setInputValue] = useState(null) +}) => { + const [input, setInput] = useState('') const [selectedOption, setSelectedOption] = useState(null) - const inputElementRef = useRef() - // This operation is expensive, we don't want to do it everytime we re-render, so we cache its result - const fuse = useMemo(() => { - const list = rules.map( - pick(['title', 'espace', 'description', 'name', 'dottedName']) - ) - const options = { - keys: [ - { name: 'name', weight: 0.3 }, - { name: 'title', weight: 0.3 }, - { name: 'espace', weight: 0.2 }, - { name: 'description', weight: 0.2 } - ] - } - return new Fuse(list, options) - }, [rules]) + const [results, setResults] = useState([]) const { i18n } = useTranslation() - const renderOption = ({ title, dottedName }) => ( - - - - - - - ) - const filterOptions = (options, filter) => fuse.search(filter) + useEffect(() => { + worker.postMessage({ + rules: rules.map( + pick(['title', 'espace', 'description', 'name', 'dottedName']) + ) + }) + + worker.onmessage = ({ data: results }) => setResults(results) + }, []) + + let renderOptions = rules => { + let options = + (rules && sortBy(rule => rule.dottedName, rules)) || take(5)(results) + return + } + + let renderOption = option => { + let { title, dottedName, name } = option + return ( +
  • setSelectedOption(option)}> +
    + +
    + + + +
  • + ) + } if (selectedOption != null) { finallyCallback && finallyCallback() @@ -61,37 +98,22 @@ function SearchBar({ return ( <> -