/** * Copyright (c) 2023 Google LLC * SPDX-License-Identifier: MIT */ import React from 'react'; import type { TreeModel } from '../types'; import { ReplaceText } from '@looker/components'; // TODO: find matches if words in middle of string; fuzzify it. /** * Given a search string, highlight every occurrence of that string and * if it's a section name, open the section. * @param trees * @param search * @param parentIsOpen */ export const searchTree = ( trees: TreeModel[], search?: string, parentIsOpen?: boolean ): TreeModel[] => trees.map(tree => { const isOpen = (!tree.isNotHighlightable && containsString(tree, search)) || !!parentIsOpen; const match = tree.isNotHighlightable ? undefined : search; if (tree.children) { const children = searchTree(tree.children, search, isOpen); const childContains = children.some(child => child.isOpen); return { ...tree, isOpen: isOpen || childContains, hide: !isOpen && !childContains && search !== '', label: {tree.value}, children, }; } else { return { ...tree, label: {tree.value}, isOpen, hide: !isOpen && search !== '', }; } }); export const containsString = ({ value }: TreeModel, str2?: string) => !!(str2 && value.toLowerCase().includes(str2.toLowerCase())); /** * Returns TRUE if there is any first-level entry in the * given "tree" that is not hidden. * * Since we do hide the children whenever a parent * entry is hidden and hide the parent if all children are * hidden, we can safely check on the first level of entries * in the tree. * * @param tree the tree to check for visibility */ export const hasAnyVisibleEntry = (tree?: TreeModel[]) => (tree || []).some(entry => !entry.hide);