All files / modules/70-pipeline/components/LogsContent/LogsState search.ts

22.22% Statements 6/27
0% Branches 0/8
0% Functions 0/5
22.22% Lines 6/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71              34x 34x   34x 34x       34x   34x                                                                                                          
/*
 * Copyright 2021 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import produce from 'immer'
import { mapValues, range } from 'lodash-es'
 
import { sanitizeHTML } from '@common/utils/StringUtils'
import { getRegexForSearch } from './utils'
import type { Action, ActionType, TextKeys, State } from './types'
 
// make sure that this array has same order as render
const dataKeys: TextKeys[] = ['level', 'time', 'out']
 
export function search(state: State, action: Action<ActionType.Search>): State {
  const { payload } = action
  const searchRegex = getRegexForSearch(sanitizeHTML(payload))
 
  return produce(state, draft => {
    const linesWithResults: number[] = []
    let prevLinesCount = 0
 
    draft.dataMap = mapValues(state.dataMap, unit => {
      // do not search in closed units
      if (!unit.isOpen) {
        return unit
      }
 
      return {
        ...unit,
        data: unit.data.map(lineData => {
          const searchIndices: Partial<Record<TextKeys, number[]>> = {}
          dataKeys.forEach(key => {
            const value = lineData.text[key]
            if (value) {
              const matches = value.match(searchRegex)
 
              if (matches && matches.length) {
                const prevResultsCount = linesWithResults.length
 
                // store all the indices of the search results
                searchIndices[key] = range(prevResultsCount, prevResultsCount + matches.length)
 
                // store the line numbers of the search results
                // same line number is stored multiple times for multiple results of search
                linesWithResults.push(...Array.from<number>({ length: matches.length }).fill(prevLinesCount))
              }
            }
          })
 
          prevLinesCount++
 
          return {
            ...lineData,
            searchIndices
          }
        })
      }
    })
 
    draft.searchData = {
      currentIndex: 0,
      text: payload,
      linesWithResults
    }
  })
}