All files / react-app/src/components/Opensearch utils.ts

100% Statements 49/49
100% Branches 53/53
100% Functions 11/11
100% Lines 42/42

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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140    72x       248x 3x         248x     242x 23x         242x   241x 189x         241x 2x         241x 24x         241x 2x       6x                       241x     72x 159x   156x                       72x 153x   151x 151x           150x   1x     151x           72x 81x 76x     72x 77x   74x   407x 404x               407x         72x 87x 1x                   72x 734x   16x      
import { opensearch } from "shared-types";
 
const filterMapQueryReducer = (
  state: Record<opensearch.Filterable<any>["prefix"], any[]>,
  filter: opensearch.Filterable<any>,
) => {
  if (filter.type === "exists") {
    state[filter.prefix].push({
      exists: { field: filter.field },
    });
  }
 
  if (filter.value === undefined || filter.value == null) return state;
 
  // this was hoisted up since false is a valid "match" value
  if (filter.type === "match") {
    state[filter.prefix].push({
      match: { [filter.field]: filter.value },
    });
  }
 
  if (!filter.value) return state;
 
  if (filter.type === "terms") {
    state[filter.prefix].push({
      terms: { [filter.field]: filter.value },
    });
  }
 
  if (filter.type === "term") {
    state[filter.prefix].push({
      term: { [filter.field]: filter.value },
    });
  }
 
  if (filter.type === "range") {
    state[filter.prefix].push({
      range: { [filter.field]: filter.value },
    });
  }
 
  if (filter.type === "global_search") {
    state[filter.prefix].push({
      dis_max: {
        tie_breaker: 0.7,
        boost: 1.2,
        queries: ["id", "submitterName", "leadAnalystName"].map((FIELD) => ({
          wildcard: {
            [`${FIELD}.keyword`]: {
              value: `*${(filter.value as string).trim()}*`,
              case_insensitive: true,
            },
          },
        })),
      },
    });
  }
 
  return state;
};
 
export const filterQueryBuilder = (filters: opensearch.Filterable<any>[]) => {
  if (!filters?.length) return {};
 
  return {
    query: {
      bool: filters.reduce(filterMapQueryReducer, {
        must: [],
        must_not: [],
        should: [],
        filter: [],
      }),
    },
  };
};
 
export const paginationQueryBuilder = (pagination: opensearch.QueryState<any>["pagination"]) => {
  if (!pagination) return {};
 
  const from = (() => {
    if (
      !pagination?.number ||
      !pagination?.size ||
      pagination?.number < 1 ||
      pagination?.size < 1
    ) {
      return 0;
    }
    return pagination.number * pagination.size;
  })();
 
  return {
    size: pagination?.size && pagination?.size > 0 ? pagination?.size : 25,
    from,
  };
};
 
export const sortQueryBuilder = (sort: opensearch.QueryState<any>["sort"]) => {
  if (!sort?.field) return {};
  return { sort: [{ [sort.field]: sort.order || "asc" }] };
};
 
export const aggQueryBuilder = (aggs: opensearch.AggQuery<any>[]) => {
  if (!aggs?.length) return {};
 
  return {
    aggs: aggs.reduce((STATE, AGG) => {
      if (AGG?.name && AGG?.type && AGG?.field) {
        STATE[AGG.name] = {
          [AGG.type]: {
            field: AGG.field,
            order: { _term: "asc" },
            ...(AGG.size && { size: AGG.size }),
          },
        };
      }
      return STATE;
    }, {} as any),
  };
};
 
export const createSearchFilterable = (value?: string) => {
  if (!value) return [];
  return [
    {
      type: "global_search",
      field: "",
      value,
      prefix: "must",
    } as unknown as opensearch.Filterable<any>,
  ];
};
 
export const checkMultiFilter = (filters: opensearch.Filterable<any>[] = [], val: number = 0) => {
  return (
    filters.length >= val ||
    filters.some((filter) => Array.isArray(filter.value) && filter.value.length >= val)
  );
};